Commit ed657182 authored by Andrew Nguyen's avatar Andrew Nguyen Committed by Alexandre Julliard

server: Filter the WOW64 registry access flags before performing the access check.

parent 9926ca77
......@@ -29,6 +29,7 @@
#include "winreg.h"
#include "winsvc.h"
#include "winerror.h"
#include "aclapi.h"
static HKEY hkey_main;
static DWORD GLE;
......@@ -851,6 +852,14 @@ static void test_reg_open_key(void)
DWORD ret = 0;
HKEY hkResult = NULL;
HKEY hkPreserve = NULL;
HKEY hkRoot64 = NULL;
HKEY hkRoot32 = NULL;
BOOL bRet;
SID_IDENTIFIER_AUTHORITY sid_authority = {SECURITY_WORLD_SID_AUTHORITY};
PSID world_sid;
EXPLICIT_ACCESSA access;
PACL key_acl;
SECURITY_DESCRIPTOR *sd;
/* successful open */
ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult);
......@@ -954,12 +963,98 @@ static void test_reg_open_key(void)
ok((ret == ERROR_SUCCESS && hkResult != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */),
"RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret);
RegCloseKey(hkResult);
/* Try using WOW64 flags when opening a key with a DACL set to verify that
* the registry access check is performed correctly. Redirection isn't
* being tested, so the tests don't care about whether the process is
* running under WOW64. */
if (!pIsWow64Process)
{
win_skip("WOW64 flags are not recognized\n");
return;
}
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hkRoot32, NULL);
ok(ret == ERROR_SUCCESS && hkRoot32 != NULL,
"RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret);
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hkRoot64, NULL);
ok(ret == ERROR_SUCCESS && hkRoot64 != NULL,
"RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret);
bRet = AllocateAndInitializeSid(&sid_authority, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, &world_sid);
ok(bRet == TRUE,
"Expected AllocateAndInitializeSid to return TRUE, got %d, last error %u\n", bRet, GetLastError());
access.grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL;
access.grfAccessMode = SET_ACCESS;
access.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
access.Trustee.pMultipleTrustee = NULL;
access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
access.Trustee.ptstrName = (char *)world_sid;
ret = SetEntriesInAclA(1, &access, NULL, &key_acl);
ok(ret == ERROR_SUCCESS,
"Expected SetEntriesInAclA to return ERROR_SUCCESS, got %u, last error %u\n", ret, GetLastError());
sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
bRet = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
ok(bRet == TRUE,
"Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %u\n", bRet, GetLastError());
bRet = SetSecurityDescriptorDacl(sd, TRUE, key_acl, FALSE);
ok(bRet == TRUE,
"Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %u\n", bRet, GetLastError());
/* The "sanctioned" methods of setting a registry ACL aren't implemented in Wine. */
bRet = SetKernelObjectSecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd);
ok(bRet == TRUE,
"Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError());
bRet = SetKernelObjectSecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd);
ok(bRet == TRUE,
"Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError());
hkResult = NULL;
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_64KEY | KEY_READ, &hkResult);
ok(ret == ERROR_SUCCESS && hkResult != NULL,
"RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret);
RegCloseKey(hkResult);
hkResult = NULL;
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_32KEY | KEY_READ, &hkResult);
ok(ret == ERROR_SUCCESS && hkResult != NULL,
"RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret);
RegCloseKey(hkResult);
HeapFree(GetProcessHeap(), 0, sd);
LocalFree(key_acl);
FreeSid(world_sid);
RegDeleteKeyA(hkRoot64, "");
RegCloseKey(hkRoot64);
RegDeleteKeyA(hkRoot32, "");
RegCloseKey(hkRoot32);
}
static void test_reg_create_key(void)
{
LONG ret;
HKEY hkey1, hkey2;
HKEY hkRoot64 = NULL;
HKEY hkRoot32 = NULL;
DWORD dwRet;
BOOL bRet;
SID_IDENTIFIER_AUTHORITY sid_authority = {SECURITY_WORLD_SID_AUTHORITY};
PSID world_sid;
EXPLICIT_ACCESSA access;
PACL key_acl;
SECURITY_DESCRIPTOR *sd;
ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL);
ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
/* should succeed: all versions of Windows ignore the access rights
......@@ -1015,6 +1110,84 @@ static void test_reg_create_key(void)
ok((ret == ERROR_SUCCESS && hkey1 != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */),
"RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret);
RegCloseKey(hkey1);
/* Try using WOW64 flags when opening a key with a DACL set to verify that
* the registry access check is performed correctly. Redirection isn't
* being tested, so the tests don't care about whether the process is
* running under WOW64. */
if (!pIsWow64Process)
{
win_skip("WOW64 flags are not recognized\n");
return;
}
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hkRoot32, NULL);
ok(ret == ERROR_SUCCESS && hkRoot32 != NULL,
"RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%d)\n", ret);
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hkRoot64, NULL);
ok(ret == ERROR_SUCCESS && hkRoot64 != NULL,
"RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%d)\n", ret);
bRet = AllocateAndInitializeSid(&sid_authority, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, &world_sid);
ok(bRet == TRUE,
"Expected AllocateAndInitializeSid to return TRUE, got %d, last error %u\n", bRet, GetLastError());
access.grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL;
access.grfAccessMode = SET_ACCESS;
access.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
access.Trustee.pMultipleTrustee = NULL;
access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
access.Trustee.ptstrName = (char *)world_sid;
dwRet = SetEntriesInAclA(1, &access, NULL, &key_acl);
ok(ret == ERROR_SUCCESS,
"Expected SetEntriesInAclA to return ERROR_SUCCESS, got %u, last error %u\n", dwRet, GetLastError());
sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
bRet = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
ok(bRet == TRUE,
"Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %u\n", bRet, GetLastError());
bRet = SetSecurityDescriptorDacl(sd, TRUE, key_acl, FALSE);
ok(bRet == TRUE,
"Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %u\n", bRet, GetLastError());
/* The "sanctioned" methods of setting a registry ACL aren't implemented in Wine. */
bRet = SetKernelObjectSecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd);
ok(bRet == TRUE,
"Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError());
bRet = SetKernelObjectSecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd);
ok(bRet == TRUE,
"Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError());
hkey1 = NULL;
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
KEY_WOW64_64KEY | KEY_READ, NULL, &hkey1, NULL);
ok(ret == ERROR_SUCCESS && hkey1 != NULL,
"RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret);
RegCloseKey(hkey1);
hkey1 = NULL;
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0,
KEY_WOW64_32KEY | KEY_READ, NULL, &hkey1, NULL);
ok(ret == ERROR_SUCCESS && hkey1 != NULL,
"RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret);
RegCloseKey(hkey1);
HeapFree(GetProcessHeap(), 0, sd);
LocalFree(key_acl);
FreeSid(world_sid);
RegDeleteKeyA(hkRoot64, "");
RegCloseKey(hkRoot64);
RegDeleteKeyA(hkRoot32, "");
RegCloseKey(hkRoot32);
}
static void test_reg_close_key(void)
......
......@@ -331,7 +331,9 @@ static unsigned int key_map_access( struct object *obj, unsigned int access )
if (access & GENERIC_WRITE) access |= KEY_WRITE;
if (access & GENERIC_EXECUTE) access |= KEY_EXECUTE;
if (access & GENERIC_ALL) access |= KEY_ALL_ACCESS;
return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
/* filter the WOW64 masks, as they aren't real access bits */
return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL |
KEY_WOW64_64KEY | KEY_WOW64_32KEY);
}
/* close the notification associated with a handle */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment