From: Munkyu Im Date: Thu, 13 Oct 2016 13:18:30 +0000 (+0900) Subject: emulator: respawning when elevated X-Git-Tag: TizenStudio_2.0_p2.4~19^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=98046ab6c35ce83999c9a18811a4e40f307bc0f1;p=sdk%2Femulator%2Fqemu.git emulator: respawning when elevated In order to prevent potential elevation of privilege attack, lower privilege processes can't interfere with higher privilege on Windows. Emulator is usually launched by emulator manager that has high integrity level, then drag-and-drop from Explorer (mostly medium integrity level) does not work. So, when emulator process has elevated integrity level, we try to respawn emulator with medium integrity level. Change-Id: I17f29e411252758098304ba25b60219d07aa0d7c Signed-off-by: Munkyu Im Signed-off-by: SeokYeon Hwang --- diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c index 940e0d1..94b0fcc 100644 --- a/tizen/src/emulator.c +++ b/tizen/src/emulator.c @@ -47,7 +47,10 @@ #include "ecs/ecs.h" #include "util/device_hotplug.h" #include "util/exported_strings.h" - +#ifdef CONFIG_WIN32 +#include +#include +#endif #ifdef CONFIG_QT #include #endif @@ -346,6 +349,15 @@ int main(int argc, char *argv[], char **envp) init_error_handler(); return emulator_main(argc, argv, envp); } +#elif defined (CONFIG_WIN32) +int main(int argc, char *argv[]) +{ + if (!check_integrity_level_and_respawn()) { + init_error_handler(); + return emulator_main(argc, argv, NULL); + } + return 0; +} #else int main(int argc, char *argv[]) { diff --git a/tizen/src/util/osutil-win32.c b/tizen/src/util/osutil-win32.c index bced9f8..f733aed 100644 --- a/tizen/src/util/osutil-win32.c +++ b/tizen/src/util/osutil-win32.c @@ -96,12 +96,12 @@ void make_vm_lock_os(gchar *vms_path) GetLastError()); } lock_file = CreateFile(lock_filename, - GENERIC_READ | GENERIC_WRITE, - 0, // No share - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, - NULL); + GENERIC_READ | GENERIC_WRITE, + 0, // No share + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, + NULL); if (lock_file == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); // On Windows, the file opened by CreateFile has exclusive lock @@ -202,12 +202,12 @@ bool make_sdcard_lock_os(char *sdcard) fname = g_strdup_printf("%s.lck", sdcard); h = CreateFile(fname, - GENERIC_READ, - 0, // No share - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, - NULL); + GENERIC_READ, + 0, // No share + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, + NULL); if (h == INVALID_HANDLE_VALUE) { LOG_WARNING("Failed to CreateFile a sdcard lock file: %d\n", @@ -278,11 +278,11 @@ void get_java_path_win32(const char **java_path) /* Opens above key to query the current version */ res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - strKey, - 0, - KEY_QUERY_VALUE | - MY_KEY_WOW64_64KEY, - &hKey); + strKey, + 0, + KEY_QUERY_VALUE | + MY_KEY_WOW64_64KEY, + &hKey); if (res != ERROR_SUCCESS) { LOG_WARNING("Java Runtime Environment key not found\n"); goto javahome_not_found; @@ -290,11 +290,11 @@ void get_java_path_win32(const char **java_path) /* Queries for the current version */ res = RegQueryValueEx(hKey, - "CurrentVersion", - NULL, - NULL, - (LPBYTE)strVersion, - &dwBufLen); + "CurrentVersion", + NULL, + NULL, + (LPBYTE)strVersion, + &dwBufLen); RegCloseKey(hKey); if (res != ERROR_SUCCESS) { LOG_WARNING("JRE CurrentVersion not found\n"); @@ -307,11 +307,11 @@ void get_java_path_win32(const char **java_path) /* Opens above key to query the JavaHome */ res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - strKey, - 0, - KEY_QUERY_VALUE | - MY_KEY_WOW64_64KEY, - &hKey); + strKey, + 0, + KEY_QUERY_VALUE | + MY_KEY_WOW64_64KEY, + &hKey); if (res == ERROR_SUCCESS) { /* Queries for the JavaHome */ dwBufLen = PATH_MAX; @@ -337,3 +337,117 @@ javahome_not_found: *java_path = current_java_path; } + +bool check_integrity_level_and_respawn(void) +{ + BOOL bResult = false; + HANDLE hToken = NULL; + HANDLE hNewToken = NULL; + PSID pIntegritySid = NULL; + TOKEN_MANDATORY_LABEL TIL = { { 0, }, }; + PTOKEN_MANDATORY_LABEL pTIL = NULL; + PROCESS_INFORMATION ProcInfo = { 0, }; + STARTUPINFO StartupInfo = { 0, }; + SID_IDENTIFIER_AUTHORITY + MLAuthority = { SECURITY_MANDATORY_LABEL_AUTHORITY }; + DWORD dwIntegrityLevel, dwSize = 0; + + if(!OpenProcessToken(GetCurrentProcess(), + TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | + TOKEN_ASSIGN_PRIMARY, &hToken)) { + LOG_WARNING("OpenProcessToken Error %lu\n", GetLastError()); + goto CleanExit; + } + + if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize)) { + DWORD dwResult = GetLastError(); + if (dwResult != ERROR_INSUFFICIENT_BUFFER) { + LOG_WARNING("GetTokenInformation Error %lu\n", dwResult); + goto CleanExit; + } + } + + pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwSize); + if (!pTIL) { + LOG_WARNING("LocalAlloc Error %lu\n", GetLastError()); + goto CleanExit; + } + + if (!GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, + dwSize, &dwSize)) { + LOG_WARNING("GetTokenInformation Error %lu\n", GetLastError()); + goto CleanExit; + } + + dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, + (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1)); + + if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && + dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) { + // We have medium integrity level. So keep going on. + goto CleanExit; + } + + LOG_INFO("Running with elevated integrity level. Try to respawn.\n"); + + if (!DuplicateTokenEx(hToken, 0, NULL, SecurityImpersonation, + TokenPrimary, &hNewToken)) { + LOG_WARNING("DuplicateTokenEx Error %lu\n", GetLastError()); + goto CleanExit; + } + + if (!AllocateAndInitializeSid(&MLAuthority, 1, SECURITY_MANDATORY_MEDIUM_RID, + 0, 0, 0, 0, 0, 0, 0, &pIntegritySid)) { + LOG_WARNING("AllocateAndInitializeSid Error %lu\n", GetLastError()); + goto CleanExit; + } + + TIL.Label.Attributes = SE_GROUP_INTEGRITY; + TIL.Label.Sid = pIntegritySid; + + if (!SetTokenInformation(hNewToken, + TokenIntegrityLevel, + &TIL, + sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) { + LOG_WARNING("SetTokenInformation Error %lu\n", GetLastError()); + goto CleanExit; + } + + if (!CreateProcessAsUser(hNewToken, 0, GetCommandLine(), + NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcInfo)) { + LOG_WARNING( "CreateProcessAsUser Error %lu\n", GetLastError()); + goto CleanExit; + } + + LOG_INFO("Respawning success. Waiting for child process.\n"); + bResult = true; + WaitForSingleObject(ProcInfo.hProcess, INFINITE); + +CleanExit: + if (ProcInfo.hProcess != NULL) { + CloseHandle(ProcInfo.hProcess); + } + + if (ProcInfo.hThread != NULL) { + CloseHandle(ProcInfo.hThread); + } + + if (pIntegritySid != NULL) { + LocalFree(pIntegritySid); + } + + if (hNewToken != NULL) { + CloseHandle(hNewToken); + } + + if (hToken != NULL) { + CloseHandle(hToken); + } + + if (pTIL != NULL) { + LocalFree(pTIL); + } + + return bResult; +} + diff --git a/tizen/src/util/osutil.h b/tizen/src/util/osutil.h index 7dc9fea..d478155 100644 --- a/tizen/src/util/osutil.h +++ b/tizen/src/util/osutil.h @@ -57,6 +57,7 @@ bool make_sdcard_lock_posix(char *sdcard); int remove_sdcard_lock_posix(char *sdcard); #else void get_java_path_win32(const char **java_path); +bool check_integrity_level_and_respawn(void); #endif void set_bin_path_os(char const *const); diff --git a/version.rc b/version.rc index c7922d5..86455bb 100644 --- a/version.rc +++ b/version.rc @@ -14,7 +14,11 @@ FILESUBTYPE VFT2_UNKNOWN BLOCK "040904E4" { VALUE "CompanyName", "http://www.qemu-project.org" +#ifdef CONFIG_MARU + VALUE "FileDescription", "Tizen Emulator" +#else VALUE "FileDescription", "QEMU machine emulators and tools" +#endif VALUE "FileVersion", QEMU_VERSION VALUE "LegalCopyright", "Copyright various authors. Released under the GNU General Public License." VALUE "LegalTrademarks", "QEMU is a trademark of Fabrice Bellard."