summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMunkyu Im <munkyu.im@samsung.com>2016-10-13 22:18:30 +0900
committerMunkyu Im <munkyu.im@samsung.com>2016-10-14 12:07:01 +0900
commit98046ab6c35ce83999c9a18811a4e40f307bc0f1 (patch)
treebd1dc2e28dffd71f70eba73d129cfe15c8641b06
parent1e884dfd8d10ad3c5cbd415467c1723b1e37c0f8 (diff)
downloadqemu-98046ab6c35ce83999c9a18811a4e40f307bc0f1.tar.gz
qemu-98046ab6c35ce83999c9a18811a4e40f307bc0f1.tar.bz2
qemu-98046ab6c35ce83999c9a18811a4e40f307bc0f1.zip
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 <munkyu.im@samsung.com> Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
-rw-r--r--tizen/src/emulator.c14
-rw-r--r--tizen/src/util/osutil-win32.c168
-rw-r--r--tizen/src/util/osutil.h1
-rw-r--r--version.rc4
4 files changed, 159 insertions, 28 deletions
diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c
index 940e0d1409..94b0fcc2e9 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 <windows.h>
+#include <sddl.h>
+#endif
#ifdef CONFIG_QT
#include <qt5_supplement.h>
#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 bced9f8e7a..f733aedc67 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 7dc9fea2f4..d478155f28 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 c7922d5200..86455bb873 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."