From 9e265ac738bfd89b50071e9d0d881fe97f652c16 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Fri, 8 Mar 2024 17:40:23 -0600 Subject: [PATCH] Rebase against 1719aef8cbc99994ec93848ae6e9e29e5c4beb78. --- ...process-token-elevation-through-mani.patch | 149 -------- ...rt-explorer.exe-using-limited-rights.patch | 80 ---- ...asic-implementation-for-starting-pro.patch | 344 ------------------ ...ocesses-using-a-limited-administrato.patch | 27 -- ...rt-the-initial-process-through-start.patch | 57 --- ...te-processes-if-requested-in-CreateP.patch | 110 ------ ...ocesses-if-requested-in-RtlCreateUse.patch | 129 ------- patches/server-default_integrity/definition | 2 - staging/upstream-commit | 2 +- 9 files changed, 1 insertion(+), 899 deletions(-) delete mode 100644 patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch delete mode 100644 patches/advapi32-Token_Integrity_Level/0012-user32-Start-explorer.exe-using-limited-rights.patch delete mode 100644 patches/advapi32-Token_Integrity_Level/0014-programs-runas-Basic-implementation-for-starting-pro.patch delete mode 100644 patches/server-default_integrity/0001-server-Create-processes-using-a-limited-administrato.patch delete mode 100644 patches/server-default_integrity/0005-ntdll-Always-start-the-initial-process-through-start.patch delete mode 100644 patches/server-default_integrity/0006-kernelbase-Elevate-processes-if-requested-in-CreateP.patch delete mode 100644 patches/server-default_integrity/0007-ntdll-Elevate-processes-if-requested-in-RtlCreateUse.patch delete mode 100644 patches/server-default_integrity/definition diff --git a/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch b/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch deleted file mode 100644 index 9d10e143..00000000 --- a/patches/advapi32-Token_Integrity_Level/0008-ntdll-Implement-process-token-elevation-through-mani.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 51cde3dff5de27d1aebc964a4802758534d56773 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Sat, 5 Aug 2017 03:39:55 +0200 -Subject: [PATCH] ntdll: Implement process token elevation through manifests. - ---- - dlls/ntdll/loader.c | 37 +++++++++++++++++++++++++++++++++++++ - server/process.c | 8 ++++++++ - server/process.h | 1 + - server/protocol.def | 7 +++++++ - server/token.c | 14 ++++++++++++++ - 5 files changed, 67 insertions(+) - -diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c -index 6290cbcb4e6..9a8f13901b2 100644 ---- a/dlls/ntdll/loader.c -+++ b/dlls/ntdll/loader.c -@@ -3489,6 +3489,32 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow - } - - -+/*********************************************************************** -+ * elevate_process -+ */ -+static void elevate_process( void ) -+{ -+ NTSTATUS status; -+ HANDLE token; -+ -+ if (!(token = __wine_create_default_token( TRUE ))) -+ { -+ ERR( "Failed to create admin token\n" ); -+ return; -+ } -+ -+ SERVER_START_REQ( replace_process_token ) -+ { -+ req->token = wine_server_obj_handle( token ); -+ if ((status = wine_server_call( req ))) -+ ERR( "Failed to replace process token: %08x\n", status ); -+ } -+ SERVER_END_REQ; -+ -+ NtClose( token ); -+} -+ -+ - /*********************************************************************** - * load_global_options - */ -@@ -3900,6 +3926,7 @@ void __wine_process_init(void) - 'k','e','r','n','e','l','3','2','.','d','l','l',0}; - void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) = NULL; - RTL_USER_PROCESS_PARAMETERS *params; -+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION runlevel; - WINE_MODREF *wm; - NTSTATUS status; - ANSI_STRING func_name; -@@ -4021,6 +4048,16 @@ void __wine_process_init(void) - } - #endif - -+ /* elevate process if necessary */ -+ status = RtlQueryInformationActivationContext( 0, NULL, 0, RunlevelInformationInActivationContext, -+ &runlevel, sizeof(runlevel), NULL ); -+ if (!status && (runlevel.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE || -+ runlevel.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN)) -+ { -+ TRACE( "Application requested admin rights (run level %d)\n", runlevel.RunLevel ); -+ elevate_process(); /* FIXME: the process exists with a wrong token for a short time */ -+ } -+ - /* the main exe needs to be the first in the load order list */ - RemoveEntryList( &wm->ldr.InLoadOrderLinks ); - InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderLinks ); -diff --git a/server/process.c b/server/process.c -index fa8495511e0..df72efdecc8 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -1086,6 +1086,14 @@ int set_process_debug_flag( struct process *process, int flag ) - return write_process_memory( process, process->peb + 2, 1, &data ); - } - -+/* replace the token of a process */ -+void replace_process_token( struct process *process, struct token *new_token ) -+{ -+ release_object(current->process->token); -+ current->process->token = new_token; -+ grab_object(new_token); -+} -+ - /* create a new process */ - DECL_HANDLER(new_process) - { -diff --git a/server/process.h b/server/process.h -index 0fdf070b78e..43e8cc1ad7e 100644 ---- a/server/process.h -+++ b/server/process.h -@@ -129,6 +129,7 @@ extern void kill_console_processes( struct thread *renderer, int exit_code ); - extern void kill_debugged_processes( struct thread *debugger, int exit_code ); - extern void detach_debugged_processes( struct thread *debugger ); - extern void enum_processes( int (*cb)(struct process*, void*), void *user); -+extern void replace_process_token( struct process *process, struct token *token ); - - /* console functions */ - extern obj_handle_t inherit_console( struct thread *parent_thread, obj_handle_t handle, -diff --git a/server/protocol.def b/server/protocol.def -index a9308904afc..8c40fba8d0a 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -3489,6 +3489,13 @@ struct handle_info - @END - - -+/* Create a new token */ -+@REQ(replace_process_token) -+ obj_handle_t token; /* new process token */ -+@REPLY -+@END -+ -+ - /* Create I/O completion port */ - @REQ(create_completion) - unsigned int access; /* desired access to a port */ -diff --git a/server/token.c b/server/token.c -index 970ed1838da..1c1d49989b3 100644 ---- a/server/token.c -+++ b/server/token.c -@@ -1804,3 +1804,17 @@ DECL_HANDLER(create_token) - release_object( token ); - } - } -+ -+/* Replaces the token of the current process */ -+DECL_HANDLER(replace_process_token) -+{ -+ struct token *token; -+ -+ if ((token = (struct token *)get_handle_obj( current->process, req->token, -+ TOKEN_ASSIGN_PRIMARY, -+ &token_ops ))) -+ { -+ replace_process_token( current->process, token ); -+ release_object( token ); -+ } -+} --- -2.28.0 - diff --git a/patches/advapi32-Token_Integrity_Level/0012-user32-Start-explorer.exe-using-limited-rights.patch b/patches/advapi32-Token_Integrity_Level/0012-user32-Start-explorer.exe-using-limited-rights.patch deleted file mode 100644 index 050cabb1..00000000 --- a/patches/advapi32-Token_Integrity_Level/0012-user32-Start-explorer.exe-using-limited-rights.patch +++ /dev/null @@ -1,80 +0,0 @@ -From baff5c160cf7f1ac0011bf8f55d506bf0346e1fd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Mon, 7 Aug 2017 02:53:06 +0200 -Subject: [PATCH] user32: Start explorer.exe using limited rights. - ---- - dlls/advapi32/tests/security.c | 4 ++-- - dlls/user32/win.c | 12 ++++++++++-- - 2 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index f27642e7a7..0271cd72e0 100644 ---- a/dlls/advapi32/tests/security.c -+++ b/dlls/advapi32/tests/security.c -@@ -7313,7 +7313,7 @@ static void test_token_security_descriptor(void) - ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; -- todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); -+ ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); - - size = 0; - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); -@@ -7768,7 +7768,7 @@ static void test_child_token_sd_medium(void) - ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; -- todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); -+ ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); - - HeapFree(GetProcessHeap(), 0, sd); - } -diff --git a/dlls/user32/win.c b/dlls/user32/win.c -index cbfd8bb14a..8039f54fb0 100644 ---- a/dlls/user32/win.c -+++ b/dlls/user32/win.c -@@ -43,6 +43,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); - #define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1) - #define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1) - -+extern HANDLE CDECL __wine_create_default_token(BOOL admin); -+ - static DWORD process_layout = ~0u; - - static struct list window_surfaces = LIST_INIT( window_surfaces ); -@@ -2052,6 +2054,7 @@ HWND WINAPI GetDesktopWindow(void) - WCHAR app[MAX_PATH + ARRAY_SIZE( explorer )]; - WCHAR cmdline[MAX_PATH + ARRAY_SIZE( explorer ) + ARRAY_SIZE( args )]; - WCHAR desktop[MAX_PATH]; -+ HANDLE token; - void *redir; - - SERVER_START_REQ( set_user_object_info ) -@@ -2084,9 +2087,12 @@ HWND WINAPI GetDesktopWindow(void) - strcpyW( cmdline, app ); - strcatW( cmdline, args ); - -+ if (!(token = __wine_create_default_token( FALSE ))) -+ ERR( "Failed to create limited token\n" ); -+ - Wow64DisableWow64FsRedirection( &redir ); -- if (CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, -- NULL, windir, &si, &pi )) -+ if (CreateProcessAsUserW( token, app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, -+ NULL, windir, &si, &pi )) - { - TRACE( "started explorer pid %04x tid %04x\n", pi.dwProcessId, pi.dwThreadId ); - WaitForInputIdle( pi.hProcess, 10000 ); -@@ -2096,6 +2102,8 @@ HWND WINAPI GetDesktopWindow(void) - else WARN( "failed to start explorer, err %d\n", GetLastError() ); - Wow64RevertWow64FsRedirection( redir ); - -+ if (token) CloseHandle( token ); -+ - SERVER_START_REQ( get_desktop_window ) - { - req->force = 1; --- -2.18.0 - diff --git a/patches/advapi32-Token_Integrity_Level/0014-programs-runas-Basic-implementation-for-starting-pro.patch b/patches/advapi32-Token_Integrity_Level/0014-programs-runas-Basic-implementation-for-starting-pro.patch deleted file mode 100644 index 2cb894cc..00000000 --- a/patches/advapi32-Token_Integrity_Level/0014-programs-runas-Basic-implementation-for-starting-pro.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 5bf0baa79c46ec44dfd5e1340e96ff9289bc37f8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Sun, 6 Aug 2017 03:15:34 +0200 -Subject: [PATCH] programs/runas: Basic implementation for starting processes - with a different trustlevel. - ---- - configure.ac | 1 + - programs/runas/Makefile.in | 8 ++ - programs/runas/runas.c | 214 +++++++++++++++++++++++++++++++++++++ - programs/runas/runas.h | 26 +++++ - programs/runas/runas.rc | 39 +++++++ - 5 files changed, 288 insertions(+) - create mode 100644 programs/runas/Makefile.in - create mode 100644 programs/runas/runas.c - create mode 100644 programs/runas/runas.h - create mode 100644 programs/runas/runas.rc - -diff --git a/configure.ac b/configure.ac -index 499c4f37ca..6f12614af1 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3891,6 +3891,7 @@ WINE_CONFIG_MAKEFILE(programs/regedit/tests) - WINE_CONFIG_MAKEFILE(programs/regsvcs) - WINE_CONFIG_MAKEFILE(programs/regsvr32) - WINE_CONFIG_MAKEFILE(programs/rpcss) -+WINE_CONFIG_MAKEFILE(programs/runas) - WINE_CONFIG_MAKEFILE(programs/rundll.exe16,enable_win16) - WINE_CONFIG_MAKEFILE(programs/rundll32) - WINE_CONFIG_MAKEFILE(programs/sc) -diff --git a/programs/runas/Makefile.in b/programs/runas/Makefile.in -new file mode 100644 -index 0000000000..33aa00ab03 ---- /dev/null -+++ b/programs/runas/Makefile.in -@@ -0,0 +1,8 @@ -+MODULE = runas.exe -+APPMODE = -mconsole -municode -mno-cygwin -+IMPORTS = advapi32 user32 -+ -+C_SRCS = \ -+ runas.c -+ -+RC_SRCS = runas.rc -diff --git a/programs/runas/runas.c b/programs/runas/runas.c -new file mode 100644 -index 0000000000..412755afa0 ---- /dev/null -+++ b/programs/runas/runas.c -@@ -0,0 +1,214 @@ -+/* -+ * runas.exe implementation -+ * -+ * Copyright 2017 Michael Müller -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include -+#include -+#include -+ -+#include "runas.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(runas); -+ -+extern HANDLE CDECL __wine_create_default_token(BOOL admin); -+ -+struct cmdinfo -+{ -+ WCHAR *program; -+ DWORD trustlevel; -+}; -+ -+static void output_writeconsole(const WCHAR *str, DWORD wlen) -+{ -+ DWORD count, ret; -+ -+ ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL); -+ if (!ret) -+ { -+ DWORD len; -+ char *msgA; -+ -+ /* On Windows WriteConsoleW() fails if the output is redirected. So fall -+ * back to WriteFile(), assuming the console encoding is still the right -+ * one in that case. -+ */ -+ len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL); -+ msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char)); -+ if (!msgA) return; -+ -+ WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL); -+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE); -+ HeapFree(GetProcessHeap(), 0, msgA); -+ } -+} -+ -+static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args) -+{ -+ WCHAR *str; -+ DWORD len; -+ -+ SetLastError(NO_ERROR); -+ len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, -+ fmt, 0, 0, (WCHAR *)&str, 0, &va_args); -+ if (len == 0 && GetLastError() != NO_ERROR) -+ { -+ WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt)); -+ return; -+ } -+ output_writeconsole(str, len); -+ LocalFree(str); -+} -+ -+static void WINAPIV output_message(unsigned int id, ...) -+{ -+ WCHAR fmt[1024]; -+ __ms_va_list va_args; -+ -+ if (!LoadStringW(GetModuleHandleW(NULL), id, fmt, sizeof(fmt)/sizeof(WCHAR))) -+ { -+ WINE_FIXME("LoadString failed with %d\n", GetLastError()); -+ return; -+ } -+ __ms_va_start(va_args, id); -+ output_formatstring(fmt, va_args); -+ __ms_va_end(va_args); -+} -+ -+static void show_usage(void) -+{ -+ output_message(STRING_USAGE); -+} -+ -+static void show_trustlevels(void) -+{ -+ output_message(STRING_TRUSTLEVELS); -+ ExitProcess(0); -+} -+ -+static WCHAR *starts_with(WCHAR *str, const WCHAR *start) -+{ -+ DWORD start_len = lstrlenW(start); -+ if (lstrlenW(str) < start_len) -+ return NULL; -+ if (wcsncmp(str, start, start_len)) -+ return NULL; -+ return str + start_len; -+} -+ -+static BOOL parse_command_line(int argc, WCHAR *argv[], struct cmdinfo *cmd) -+{ -+ static const WCHAR showtrustlevelsW[] = {'/','s','h','o','w','t','r','u','s','t','l','e','v','e','l','s',0}; -+ static const WCHAR trustlevelW[] = {'/','t','r','u','s','t','l','e','v','e','l',':',0}; -+ int i; -+ -+ memset(cmd, 0, sizeof(*cmd)); -+ -+ for (i = 1; i < argc; i++) -+ { -+ if (argv[i][0] == '/') -+ { -+ WCHAR *arg; -+ -+ if ((arg = starts_with(argv[i], trustlevelW))) -+ cmd->trustlevel = wcstoul(arg, NULL, 0); -+ else if (!lstrcmpW(argv[i], showtrustlevelsW)) -+ show_trustlevels(); -+ else -+ WINE_FIXME("Ignoring parameter %s\n", wine_dbgstr_w(argv[i])); -+ } -+ else if (argv[i][0]) -+ { -+ if (cmd->program) return FALSE; -+ cmd->program = argv[i]; -+ } -+ } -+ -+ return TRUE; -+} -+ -+static BOOL start_process(struct cmdinfo *cmd) -+{ -+ PROCESS_INFORMATION info; -+ STARTUPINFOW startup; -+ HANDLE token = NULL; -+ BOOL ret; -+ -+ if (cmd->trustlevel == 0x20000) -+ { -+ if (!(token = __wine_create_default_token(FALSE))) -+ ERR("Failed to create limited token\n"); -+ } -+ -+ memset(&startup, 0, sizeof(startup)); -+ startup.cb = sizeof(startup); -+ ret = CreateProcessAsUserW(token, NULL, cmd->program, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); -+ if (ret) -+ { -+ CloseHandle(info.hProcess); -+ CloseHandle(info.hThread); -+ } -+ else -+ { -+ DWORD error = GetLastError(); -+ WCHAR *str; -+ -+ if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | -+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 0, (WCHAR *)&str, 0, NULL)) -+ { -+ output_message(STRING_START_ERROR, cmd->program, error, str); -+ LocalFree(str); -+ } -+ else -+ WINE_FIXME("Failed to format error: %u\n", error); -+ } -+ -+ if (token) CloseHandle(token); -+ return ret; -+} -+ -+int wmain(int argc, WCHAR *argv[]) -+{ -+ struct cmdinfo cmd; -+ -+ if (argc <= 1) -+ { -+ show_usage(); -+ return 0; -+ } -+ -+ if (!parse_command_line(argc, argv, &cmd)) -+ { -+ show_usage(); -+ return 1; -+ } -+ -+ if (!cmd.program) -+ { -+ show_usage(); -+ return 1; -+ } -+ -+ if (cmd.trustlevel && cmd.trustlevel != 0x20000) -+ { -+ output_message(STRING_UNHANDLED_TRUSTLEVEL, cmd.trustlevel); -+ return 1; -+ } -+ -+ return start_process(&cmd); -+} -diff --git a/programs/runas/runas.h b/programs/runas/runas.h -new file mode 100644 -index 0000000000..40599a3b33 ---- /dev/null -+++ b/programs/runas/runas.h -@@ -0,0 +1,26 @@ -+/* -+ * runas.exe implementation -+ * -+ * Copyright 2017 Michael Müller -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include -+ -+#define STRING_USAGE 101 -+#define STRING_UNHANDLED_TRUSTLEVEL 102 -+#define STRING_TRUSTLEVELS 103 -+#define STRING_START_ERROR 104 -diff --git a/programs/runas/runas.rc b/programs/runas/runas.rc -new file mode 100644 -index 0000000000..f9297a4479 ---- /dev/null -+++ b/programs/runas/runas.rc -@@ -0,0 +1,39 @@ -+/* -+ * runas.exe implementation -+ * -+ * Copyright 2017 Michael Müller -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "runas.h" -+ -+#pragma makedep po -+ -+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT -+ -+STRINGTABLE -+{ -+ STRING_USAGE, "Usage of RUNAS:\n\n\ -+\RUNAS /trustlevel: program\n\n\ -+\ /showtrustlevels Show possible trustlevels\n\ -+\ /trustlevel should be listed in /showtrustlevels\n\ -+\ program Program to start\n\n" -+ STRING_UNHANDLED_TRUSTLEVEL, "runas: Unhandled trustlevel 0x%1!x!\n" -+ STRING_TRUSTLEVELS, "The following trustlevels are supported:\n\ -+0x20000 (standard user)\n" -+ STRING_START_ERROR, "RUNAS-Error: %1 could not be started\n\ -+ %2!u!: %3\n" -+} --- -2.23.0.rc1 - diff --git a/patches/server-default_integrity/0001-server-Create-processes-using-a-limited-administrato.patch b/patches/server-default_integrity/0001-server-Create-processes-using-a-limited-administrato.patch deleted file mode 100644 index f92eeac7..00000000 --- a/patches/server-default_integrity/0001-server-Create-processes-using-a-limited-administrato.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9804dd77fd8c0ec56963306f409fea6b910bb48d Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Sun, 7 Feb 2021 22:54:19 -0600 -Subject: [PATCH] server: Create processes using a limited administrator token - by default. - -Signed-off-by: Zebediah Figura ---- - server/process.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/server/process.c b/server/process.c -index 15387a2affa..3a8bbdbfb2e 100644 ---- a/server/process.c -+++ b/server/process.c -@@ -664,7 +664,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla - if (!parent) - { - process->handles = alloc_handle_table( process, 0 ); -- process->token = token_create_admin( TRUE, -1, TokenElevationTypeFull, default_session_id ); -+ process->token = token_create_admin( TRUE, -1, TokenElevationTypeLimited, default_session_id ); - process->affinity = ~0; - } - else --- -2.30.2 - diff --git a/patches/server-default_integrity/0005-ntdll-Always-start-the-initial-process-through-start.patch b/patches/server-default_integrity/0005-ntdll-Always-start-the-initial-process-through-start.patch deleted file mode 100644 index 096525c6..00000000 --- a/patches/server-default_integrity/0005-ntdll-Always-start-the-initial-process-through-start.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 643461bc989bd848363241dcfa04187e8d3a84d1 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Fri, 21 May 2021 21:52:06 -0500 -Subject: [PATCH] ntdll: Always start the initial process through start.exe. - -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/unix/env.c | 26 +++----------------------- - 1 file changed, 3 insertions(+), 23 deletions(-) - -diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c -index 30782a70eb0..959bafb28b7 100644 ---- a/dlls/ntdll/unix/env.c -+++ b/dlls/ntdll/unix/env.c -@@ -1909,6 +1909,7 @@ static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module ) - */ - static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) - { -+ static const char *args[] = { "start.exe", "/exec" }; - static const WCHAR valueW[] = {'1',0}; - static const WCHAR pathW[] = {'P','A','T','H'}; - RTL_USER_PROCESS_PARAMETERS *params = NULL; -@@ -1937,29 +1938,8 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module ) - add_registry_environment( &env, &env_pos, &env_size ); - env[env_pos++] = 0; - -- status = load_main_exe( NULL, main_argv[1], curdir, 0, &image, module ); -- if (!status) -- { -- char *loader; -- -- if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; -- /* if we have to use a different loader, fall back to start.exe */ -- if ((loader = get_alternate_wineloader( main_image_info.Machine ))) -- { -- free( loader ); -- status = STATUS_INVALID_IMAGE_FORMAT; -- } -- } -- -- if (status) /* try launching it through start.exe */ -- { -- static const char *args[] = { "start.exe", "/exec" }; -- free( image ); -- if (*module) NtUnmapViewOfSection( GetCurrentProcess(), *module ); -- load_start_exe( &image, module ); -- prepend_argv( args, 2 ); -- } -- else rebuild_argv(); -+ load_start_exe( &image, module ); -+ prepend_argv( args, 2 ); - - main_wargv = build_wargv( get_dos_path( image )); - cmdline = build_command_line( main_wargv ); --- -2.40.1 - diff --git a/patches/server-default_integrity/0006-kernelbase-Elevate-processes-if-requested-in-CreateP.patch b/patches/server-default_integrity/0006-kernelbase-Elevate-processes-if-requested-in-CreateP.patch deleted file mode 100644 index 240c3169..00000000 --- a/patches/server-default_integrity/0006-kernelbase-Elevate-processes-if-requested-in-CreateP.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 1eaa73714299df810d22a727e8053679d5e89f64 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Sun, 18 Apr 2021 17:46:35 -0500 -Subject: [PATCH] kernelbase: Elevate processes if requested in - CreateProcessInternal(). - -Signed-off-by: Zebediah Figura ---- - dlls/kernelbase/process.c | 57 +++++++++++++++++++++++++++++++++++++-- - 1 file changed, 55 insertions(+), 2 deletions(-) - -diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c -index 54a524abe04..7365bee9425 100644 ---- a/dlls/kernelbase/process.c -+++ b/dlls/kernelbase/process.c -@@ -30,6 +30,7 @@ - #include "winnls.h" - #include "wincontypes.h" - #include "winternl.h" -+#include "winuser.h" - - #include "kernelbase.h" - #include "wine/debug.h" -@@ -431,6 +432,54 @@ BOOL WINAPI DECLSPEC_HOTPATCH CloseHandle( HANDLE handle ) - } - - -+static BOOL image_needs_elevation( const WCHAR *path ) -+{ -+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level; -+ BOOL ret = FALSE; -+ HANDLE handle; -+ ACTCTXW ctx; -+ -+ ctx.cbSize = sizeof(ctx); -+ ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; -+ ctx.lpSource = path; -+ ctx.lpResourceName = (const WCHAR *)CREATEPROCESS_MANIFEST_RESOURCE_ID; -+ -+ if (RtlCreateActivationContext( &handle, &ctx )) return FALSE; -+ -+ if (!RtlQueryInformationActivationContext( 0, handle, NULL, RunlevelInformationInActivationContext, -+ &run_level, sizeof(run_level), NULL )) -+ { -+ TRACE( "image requested run level %#x\n", run_level.RunLevel ); -+ if (run_level.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE -+ || run_level.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN) -+ ret = TRUE; -+ } -+ RtlReleaseActivationContext( handle ); -+ -+ return ret; -+} -+ -+ -+static HANDLE get_elevated_token(void) -+{ -+ TOKEN_ELEVATION_TYPE type; -+ TOKEN_LINKED_TOKEN linked; -+ NTSTATUS status; -+ -+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(), -+ TokenElevationType, &type, sizeof(type), NULL ))) -+ return NULL; -+ -+ if (type == TokenElevationTypeFull) return NULL; -+ -+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(), -+ TokenLinkedToken, &linked, sizeof(linked), NULL ))) -+ return NULL; -+ -+ return linked.LinkedToken; -+} -+ -+ - /********************************************************************** - * CreateProcessAsUserA (kernelbase.@) - */ -@@ -517,7 +566,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR - WCHAR *p, *tidy_cmdline = cmd_line; - RTL_USER_PROCESS_PARAMETERS *params = NULL; - RTL_USER_PROCESS_INFORMATION rtl_info; -- HANDLE parent = 0, debug = 0; -+ HANDLE parent = 0, debug = 0, elevated_token = NULL; - ULONG nt_flags = 0; - USHORT machine = 0; - NTSTATUS status; -@@ -629,6 +678,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR - if (flags & CREATE_BREAKAWAY_FROM_JOB) nt_flags |= PROCESS_CREATE_FLAGS_BREAKAWAY; - if (flags & CREATE_SUSPENDED) nt_flags |= PROCESS_CREATE_FLAGS_SUSPENDED; - -+ if (!token && image_needs_elevation( params->ImagePathName.Buffer )) -+ token = elevated_token = get_elevated_token(); -+ - status = create_nt_process( token, debug, process_attr, thread_attr, - nt_flags, params, &rtl_info, parent, machine, handle_list, job_list ); - switch (status) -@@ -670,7 +722,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR - TRACE( "started process pid %04lx tid %04lx\n", info->dwProcessId, info->dwThreadId ); - } - -- done: -+done: -+ if (elevated_token) NtClose( elevated_token ); - RtlDestroyProcessParameters( params ); - if (tidy_cmdline != cmd_line) HeapFree( GetProcessHeap(), 0, tidy_cmdline ); - return set_ntstatus( status ); --- -2.40.1 - diff --git a/patches/server-default_integrity/0007-ntdll-Elevate-processes-if-requested-in-RtlCreateUse.patch b/patches/server-default_integrity/0007-ntdll-Elevate-processes-if-requested-in-RtlCreateUse.patch deleted file mode 100644 index 0abde645..00000000 --- a/patches/server-default_integrity/0007-ntdll-Elevate-processes-if-requested-in-RtlCreateUse.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 1754d90b8cc833d55e6d3f3de23cdf89dffd37aa Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Sun, 18 Apr 2021 17:46:44 -0500 -Subject: [PATCH] ntdll: Elevate processes if requested in - RtlCreateUserProcess(). - -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/process.c | 81 +++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 76 insertions(+), 5 deletions(-) - -diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c -index dcdb26f81d1..ed1b2a20311 100644 ---- a/dlls/ntdll/process.c -+++ b/dlls/ntdll/process.c -@@ -37,6 +37,11 @@ - #include "wine/exception.h" - - -+/* we don't want to include winuser.h */ -+#define CREATEPROCESS_MANIFEST_RESOURCE_ID ((ULONG_PTR)1) -+ -+WINE_DEFAULT_DEBUG_CHANNEL(process); -+ - /****************************************************************************** - * RtlGetCurrentPeb [NTDLL.@] - * -@@ -89,6 +94,63 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx( ULONG disable, ULONG *old_value ) - } - - -+static BOOL image_needs_elevation( const UNICODE_STRING *path ) -+{ -+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level; -+ UNICODE_STRING path0; -+ BOOL ret = FALSE; -+ HANDLE handle; -+ ACTCTXW ctx; -+ -+ if (RtlDuplicateUnicodeString( 1, path, &path0 )) -+ return FALSE; -+ -+ ctx.cbSize = sizeof(ctx); -+ ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; -+ ctx.lpSource = path0.Buffer; -+ ctx.lpResourceName = (const WCHAR *)CREATEPROCESS_MANIFEST_RESOURCE_ID; -+ -+ if (RtlCreateActivationContext( &handle, &ctx )) -+ { -+ RtlFreeUnicodeString( &path0 ); -+ return FALSE; -+ } -+ -+ if (!RtlQueryInformationActivationContext( 0, handle, NULL, RunlevelInformationInActivationContext, -+ &run_level, sizeof(run_level), NULL )) -+ { -+ TRACE( "image requested run level %#x\n", run_level.RunLevel ); -+ if (run_level.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE -+ || run_level.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN) -+ ret = TRUE; -+ } -+ RtlReleaseActivationContext( handle ); -+ RtlFreeUnicodeString( &path0 ); -+ return ret; -+} -+ -+ -+static HANDLE get_elevated_token(void) -+{ -+ TOKEN_ELEVATION_TYPE type; -+ TOKEN_LINKED_TOKEN linked; -+ NTSTATUS status; -+ -+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(), -+ TokenElevationType, &type, sizeof(type), NULL ))) -+ return NULL; -+ -+ if (type == TokenElevationTypeFull) return NULL; -+ -+ -+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(), -+ TokenLinkedToken, &linked, sizeof(linked), NULL ))) -+ return NULL; -+ -+ return linked.LinkedToken; -+} -+ -+ - /********************************************************************** - * RtlWow64GetCurrentMachine (NTDLL.@) - */ -@@ -461,8 +523,15 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, - PS_CREATE_INFO create_info; - ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[6] ) / sizeof(ULONG_PTR)]; - PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer; -+ HANDLE elevated_token = NULL; -+ NTSTATUS status; - UINT pos = 0; - -+ /* It's not clear whether we should use path or ¶ms->ImagePathName here, -+ * but Roblox Player tries to pass an empty string for the latter. */ -+ if (!token && image_needs_elevation( path )) -+ token = elevated_token = get_elevated_token(); -+ - RtlNormalizeProcessParams( params ); - - attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_NAME; -@@ -509,11 +578,13 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, - InitializeObjectAttributes( &process_attr, NULL, 0, NULL, process_descr ); - InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, thread_descr ); - -- return NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, -- &process_attr, &thread_attr, -- inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0, -- THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params, -- &create_info, attr ); -+ status = NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, -+ &process_attr, &thread_attr, -+ inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0, -+ THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params, &create_info, attr ); -+ -+ if (elevated_token) NtClose( elevated_token ); -+ return status; - } - - /*********************************************************************** --- -2.43.0 - diff --git a/patches/server-default_integrity/definition b/patches/server-default_integrity/definition deleted file mode 100644 index 31f971ca..00000000 --- a/patches/server-default_integrity/definition +++ /dev/null @@ -1,2 +0,0 @@ -Fixes: [40613] Multiple applications require UAC implementation to run installer/app as a normal user instead of administrator (WhatsApp Desktop, Smartflix, Squirrel Installers, OneDrive) -Fixes: [39262] DiscordSetup.exe (.NET 4.5.2 app): Squirrell installer requires being run as unelevated process ('explorer.exe' should run unelevated by default with Vista+ setting) diff --git a/staging/upstream-commit b/staging/upstream-commit index ab36c878..699bad83 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -934cfb86b5e2b485b4b90e1eeac4021733559591 +1719aef8cbc99994ec93848ae6e9e29e5c4beb78