diff --git a/debian/changelog b/debian/changelog index d10a7a77..03db5a0e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ wine-compholio (1.7.20) UNRELEASED; urgency=low * Updated scripts to be compatible with BSD systems. * Update winepulse patches to latest revision (extracted from 1.7.19). * Force autoreconf even when timestamp seems to indicate that it is not necessary. + * Added patches for default security descriptor ownership and DACLs for processes. * Added a patch to avoid a race-condition when unloading modules while a hook is active. -- Erich E. Hoover Fri, 13 Jun 2014 15:29:07 -0600 diff --git a/patches/13-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch b/patches/13-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch new file mode 100644 index 00000000..7de1b67e --- /dev/null +++ b/patches/13-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch @@ -0,0 +1,168 @@ +From ccfec2389d48a56f0bfdf54b5f1fde6ead00e345 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Tue, 13 May 2014 16:49:31 -0600 +Subject: server: Add default security descriptor ownership for processes. + +--- + dlls/advapi32/tests/security.c | 34 ++++++++++++++++++++++++++++++++++ + server/process.c | 26 +++++++++++++++++++++++++- + server/security.h | 1 + + server/token.c | 8 ++++++++ + 4 files changed, 68 insertions(+), 1 deletion(-) + +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index 05da0ae..2cf18e0 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -3853,11 +3853,15 @@ static void test_acls(void) + + static void test_GetSecurityInfo(void) + { ++ char domain_users_ptr[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; + char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; + char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100]; ++ PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid; ++ SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY }; + DWORD sid_size = sizeof(admin_ptr), l = sizeof(b); + PSID admin_sid = (PSID) admin_ptr, user_sid; + char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; ++ BOOL owner_defaulted, group_defaulted; + ACL_SIZE_INFORMATION acl_size; + PSECURITY_DESCRIPTOR pSD; + ACCESS_ALLOWED_ACE *ace; +@@ -3887,6 +3891,18 @@ static void test_GetSecurityInfo(void) + CloseHandle( token ); + user_sid = ((TOKEN_USER *)b)->User.Sid; + ++ if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0), ++ *GetSidSubAuthority(user_sid, 1), ++ *GetSidSubAuthority(user_sid, 2), ++ *GetSidSubAuthority(user_sid, 3), 0, 0, 0, 0, &domain_sid)) ++ { ++ win_skip("Failed to get current domain SID\n"); ++ return; ++ } ++ sid_size = sizeof(domain_users_ptr); ++ pCreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size); ++ FreeSid(domain_sid); ++ + /* Create something. Files have lots of associated security info. */ + obj = CreateFileA(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +@@ -3982,6 +3998,24 @@ static void test_GetSecurityInfo(void) + } + LocalFree(pSD); + CloseHandle(obj); ++ ++ /* Test querying the ownership of a process */ ++ ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, ++ OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, ++ NULL, NULL, NULL, NULL, &pSD); ++ ok(!ret, "GetNamedSecurityInfo failed with error %d\n", ret); ++ ++ bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); ++ ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); ++ ok(owner != NULL, "owner should not be NULL\n"); ++ ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid), ++ "Process owner SID != Administrators SID.\n"); ++ ++ bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); ++ ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); ++ ok(group != NULL, "group should not be NULL\n"); ++ ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n"); ++ LocalFree(pSD); + } + + static void test_GetSidSubAuthority(void) +diff --git a/server/process.c b/server/process.c +index 7b9a3b2..01016d2 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -62,6 +62,7 @@ static int shutdown_stage; /* current stage in the shutdown process */ + static void process_dump( struct object *obj, int verbose ); + static int process_signaled( struct object *obj, struct wait_queue_entry *entry ); + static unsigned int process_map_access( struct object *obj, unsigned int access ); ++static struct security_descriptor *process_get_sd( struct object *obj ); + static void process_poll_event( struct fd *fd, int event ); + static void process_destroy( struct object *obj ); + +@@ -77,7 +78,7 @@ static const struct object_ops process_ops = + no_signal, /* signal */ + no_get_fd, /* get_fd */ + process_map_access, /* map_access */ +- default_get_sd, /* get_sd */ ++ process_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + no_lookup_name, /* lookup_name */ + no_open_file, /* open_file */ +@@ -456,6 +457,29 @@ static unsigned int process_map_access( struct object *obj, unsigned int access + return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); + } + ++static struct security_descriptor *process_get_sd( struct object *obj ) ++{ ++ static struct security_descriptor *key_default_sd; ++ ++ if (obj->sd) return obj->sd; ++ ++ if (!key_default_sd) ++ { ++ size_t users_sid_len = security_sid_len( security_domain_users_sid ); ++ size_t admins_sid_len = security_sid_len( security_builtin_admins_sid ); ++ ++ key_default_sd = mem_alloc( sizeof(*key_default_sd) + admins_sid_len + users_sid_len ); ++ key_default_sd->control = SE_DACL_PRESENT; ++ key_default_sd->owner_len = admins_sid_len; ++ key_default_sd->group_len = users_sid_len; ++ key_default_sd->sacl_len = 0; ++ key_default_sd->dacl_len = 0; ++ memcpy( key_default_sd + 1, security_builtin_admins_sid, admins_sid_len ); ++ memcpy( (char *)(key_default_sd + 1) + admins_sid_len, security_domain_users_sid, users_sid_len ); ++ } ++ return key_default_sd; ++} ++ + static void process_poll_event( struct fd *fd, int event ) + { + struct process *process = get_fd_user( fd ); +diff --git a/server/security.h b/server/security.h +index ab5f027..b9fbe6a 100644 +--- a/server/security.h ++++ b/server/security.h +@@ -44,6 +44,7 @@ extern const PSID security_local_user_sid; + extern const PSID security_local_system_sid; + extern const PSID security_builtin_users_sid; + extern const PSID security_builtin_admins_sid; ++extern const PSID security_domain_users_sid; + + + /* token functions */ +diff --git a/server/token.c b/server/token.c +index cb81eec..914dfba 100644 +--- a/server/token.c ++++ b/server/token.c +@@ -91,6 +91,13 @@ static const struct /* same fields as struct SID */ + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[2]; + } builtin_users_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } }; ++static const struct /* same fields as struct SID */ ++{ ++ BYTE Revision; ++ BYTE SubAuthorityCount; ++ SID_IDENTIFIER_AUTHORITY IdentifierAuthority; ++ DWORD SubAuthority[5]; ++} domain_users_sid = { SID_REVISION, 5, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0, DOMAIN_GROUP_RID_USERS } }; + + const PSID security_world_sid = (PSID)&world_sid; + static const PSID security_local_sid = (PSID)&local_sid; +@@ -100,6 +107,7 @@ const PSID security_local_system_sid = (PSID)&local_system_sid; + const PSID security_local_user_sid = (PSID)&local_user_sid; + const PSID security_builtin_admins_sid = (PSID)&builtin_admins_sid; + const PSID security_builtin_users_sid = (PSID)&builtin_users_sid; ++const PSID security_domain_users_sid = (PSID)&domain_users_sid; + + static luid_t prev_luid_value = { 1000, 0 }; + +-- +1.7.9.5 + diff --git a/patches/13-Misc_ACL/0002-server-Add-default-security-descriptor-DACL-for-proc.patch b/patches/13-Misc_ACL/0002-server-Add-default-security-descriptor-DACL-for-proc.patch new file mode 100644 index 00000000..b71141e8 --- /dev/null +++ b/patches/13-Misc_ACL/0002-server-Add-default-security-descriptor-DACL-for-proc.patch @@ -0,0 +1,138 @@ +From 83880f60c7b647123815acb945c090bec17bab47 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Wed, 14 May 2014 08:14:46 -0600 +Subject: server: Add default security descriptor DACL for processes. + +--- + dlls/advapi32/tests/security.c | 50 ++++++++++++++++++++++++++++++++++++++++ + server/process.c | 28 ++++++++++++++++++++-- + 2 files changed, 76 insertions(+), 2 deletions(-) + +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index 2cf18e0..f767512 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -3858,10 +3858,12 @@ static void test_GetSecurityInfo(void) + char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100]; + PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid; + SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY }; ++ int domain_users_ace_id = -1, admins_ace_id = -1, i; + DWORD sid_size = sizeof(admin_ptr), l = sizeof(b); + PSID admin_sid = (PSID) admin_ptr, user_sid; + char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; + BOOL owner_defaulted, group_defaulted; ++ BOOL dacl_defaulted, dacl_present; + ACL_SIZE_INFORMATION acl_size; + PSECURITY_DESCRIPTOR pSD; + ACCESS_ALLOWED_ACE *ace; +@@ -3869,6 +3871,7 @@ static void test_GetSecurityInfo(void) + PSID owner, group; + BOOL bret = TRUE; + PACL pDacl; ++ BYTE flags; + DWORD ret; + + if (!pGetSecurityInfo || !pSetSecurityInfo) +@@ -4016,6 +4019,53 @@ static void test_GetSecurityInfo(void) + ok(group != NULL, "group should not be NULL\n"); + ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n"); + LocalFree(pSD); ++ ++ /* Test querying the DACL of a process */ ++ ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, ++ NULL, NULL, NULL, NULL, &pSD); ++ ok(!ret, "GetSecurityInfo failed with error %d\n", ret); ++ ++ bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); ++ ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); ++ ok(dacl_present, "DACL should be present\n"); ++ ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); ++ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ++ ok(bret, "GetAclInformation failed\n"); ++ ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); ++ for (i=0; iSidStart, domain_users_sid); ++ if (bret) domain_users_ace_id = i; ++ bret = EqualSid(&ace->SidStart, admin_sid); ++ if (bret) admins_ace_id = i; ++ } ++ ok(domain_users_ace_id != -1 || broken(domain_users_ace_id == -1) /* win2k */, ++ "Domain Users ACE not found.\n"); ++ if (domain_users_ace_id != -1) ++ { ++ bret = pGetAce(pDacl, domain_users_ace_id, (VOID **)&ace); ++ ok(bret, "Failed to get Domain Users ACE.\n"); ++ flags = ((ACE_HEADER *)ace)->AceFlags; ++ ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE), ++ "Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags, ++ INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); ++ ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%x != 0x%x)\n", ++ ace->Mask, GENERIC_READ); ++ } ++ ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */, ++ "Builtin Admins ACE not found.\n"); ++ if (admins_ace_id != -1) ++ { ++ bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); ++ ok(bret, "Failed to get Builtin Admins ACE.\n"); ++ flags = ((ACE_HEADER *)ace)->AceFlags; ++ ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); ++ ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */, ++ "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS); ++ } ++ LocalFree(pSD); + } + + static void test_GetSidSubAuthority(void) +diff --git a/server/process.c b/server/process.c +index 01016d2..9f4586a 100644 +--- a/server/process.c ++++ b/server/process.c +@@ -467,15 +467,39 @@ static struct security_descriptor *process_get_sd( struct object *obj ) + { + size_t users_sid_len = security_sid_len( security_domain_users_sid ); + size_t admins_sid_len = security_sid_len( security_builtin_admins_sid ); ++ size_t dacl_len = sizeof(ACL) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart ) ++ + users_sid_len + admins_sid_len; ++ ACCESS_ALLOWED_ACE *aaa; ++ ACL *dacl; + +- key_default_sd = mem_alloc( sizeof(*key_default_sd) + admins_sid_len + users_sid_len ); ++ key_default_sd = mem_alloc( sizeof(*key_default_sd) + admins_sid_len + users_sid_len ++ + dacl_len ); + key_default_sd->control = SE_DACL_PRESENT; + key_default_sd->owner_len = admins_sid_len; + key_default_sd->group_len = users_sid_len; + key_default_sd->sacl_len = 0; +- key_default_sd->dacl_len = 0; ++ key_default_sd->dacl_len = dacl_len; + memcpy( key_default_sd + 1, security_builtin_admins_sid, admins_sid_len ); + memcpy( (char *)(key_default_sd + 1) + admins_sid_len, security_domain_users_sid, users_sid_len ); ++ ++ dacl = (ACL *)((char *)(key_default_sd + 1) + admins_sid_len + users_sid_len); ++ dacl->AclRevision = ACL_REVISION; ++ dacl->Sbz1 = 0; ++ dacl->AclSize = dacl_len; ++ dacl->AceCount = 2; ++ dacl->Sbz2 = 0; ++ aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1); ++ aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; ++ aaa->Header.AceFlags = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE; ++ aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + users_sid_len; ++ aaa->Mask = GENERIC_READ; ++ memcpy( &aaa->SidStart, security_domain_users_sid, users_sid_len ); ++ aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize); ++ aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; ++ aaa->Header.AceFlags = 0; ++ aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + admins_sid_len; ++ aaa->Mask = PROCESS_ALL_ACCESS; ++ memcpy( &aaa->SidStart, security_builtin_admins_sid, admins_sid_len ); + } + return key_default_sd; + } +-- +1.7.9.5 + diff --git a/patches/13-Misc_ACL/3405aa34-f341-11e3-83ce-0090f5c75ad5.def b/patches/13-Misc_ACL/3405aa34-f341-11e3-83ce-0090f5c75ad5.def new file mode 100644 index 00000000..72e4aa43 --- /dev/null +++ b/patches/13-Misc_ACL/3405aa34-f341-11e3-83ce-0090f5c75ad5.def @@ -0,0 +1,3 @@ +Revision: 1 +Author: Erich E. Hoover +Title: Add default security descriptor ownership and DACLs for processes. diff --git a/patches/patch-list.patch b/patches/patch-list.patch index a3eafd75..088d0383 100644 --- a/patches/patch-list.patch +++ b/patches/patch-list.patch @@ -6,7 +6,7 @@ diff --git a/libs/wine/config.c b/libs/wine/config.c index a273502..5fa0cd5 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c -@@ -478,6 +478,43 @@ const char *wine_get_version(void) +@@ -478,6 +478,44 @@ const char *wine_get_version(void) return PACKAGE_VERSION; } @@ -28,6 +28,7 @@ index a273502..5fa0cd5 100644 + { "5fb1f5c8-7f17-11e3-9b62-0090f5c75ad5:1", "Erich E. Hoover", "Implement TransmitFile." }, + { "3d7c4774-9e7f-11e3-9cfc-0090f5c75ad5:1", "Erich E. Hoover", "Implement missing fonts expected by Silverlight." }, + { "e7581ed7-12b3-4ed3-835b-5a62afbf9c85:4", "Sebastian Lackner", "Use lockfree implementation for get_cached_fd." }, ++ { "3405aa34-f341-11e3-83ce-0090f5c75ad5:1", "Erich E. Hoover", "Add default security descriptor ownership and DACLs for processes." }, + { "0b21d7ac-0387-4493-aa38-fbafe3e749f5:2", "Michael Müller", "Decrease minimum SetTimer interval to 5 ms." }, + { "2394843e-2bc4-4fa4-8368-1ef32093b89e:1", "Michael Müller", "Allow changing strict draw ordering through an exported function." }, + { "255473fa-4e0a-4f51-952b-4deecc1a2181:1", "Michael Müller", "Indicate direct rendering through OpenGL extension." },