From fb5cec98e2f185b953e7957834487941a88e670d Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 16 Jan 2024 17:37:17 +0000 Subject: [PATCH] gh-114096: Restore privileges in _winapi.CreateJunction after creating the junction (GH-114089) This avoids impact on later parts of the application which may be able to do things they otherwise shouldn't. --- ...-01-15-23-53-25.gh-issue-114096.G-Myja.rst | 3 ++ Modules/_winapi.c | 34 ++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2024-01-15-23-53-25.gh-issue-114096.G-Myja.rst diff --git a/Misc/NEWS.d/next/Windows/2024-01-15-23-53-25.gh-issue-114096.G-Myja.rst b/Misc/NEWS.d/next/Windows/2024-01-15-23-53-25.gh-issue-114096.G-Myja.rst new file mode 100644 index 000000000000..f28fc04baa7f --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2024-01-15-23-53-25.gh-issue-114096.G-Myja.rst @@ -0,0 +1,3 @@ +Process privileges that are activated for creating directory junctions are +now restored afterwards, avoiding behaviour changes in other parts of the +program. diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 55b37188d24e..b44f44be0ff4 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -542,7 +542,12 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, { /* Privilege adjustment */ HANDLE token = NULL; - TOKEN_PRIVILEGES tp; + struct { + TOKEN_PRIVILEGES base; + /* overallocate by a few array elements */ + LUID_AND_ATTRIBUTES privs[4]; + } tp, previousTp; + int previousTpSize = 0; /* Reparse data buffer */ const USHORT prefix_len = 4; @@ -566,17 +571,21 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, /* Adjust privileges to allow rewriting directory entry as a junction point. */ - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { goto cleanup; + } - if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) + if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.base.Privileges[0].Luid)) { goto cleanup; + } - tp.PrivilegeCount = 1; - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), - NULL, NULL)) + tp.base.PrivilegeCount = 1; + tp.base.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (!AdjustTokenPrivileges(token, FALSE, &tp.base, sizeof(previousTp), + &previousTp.base, &previousTpSize)) { goto cleanup; + } if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES) goto cleanup; @@ -657,8 +666,15 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, cleanup: ret = GetLastError(); - CloseHandle(token); - CloseHandle(junction); + if (previousTpSize) { + AdjustTokenPrivileges(token, FALSE, &previousTp.base, previousTpSize, + NULL, NULL); + } + + if (token != NULL) + CloseHandle(token); + if (junction != NULL) + CloseHandle(junction); PyMem_RawFree(rdb); if (ret != 0) -- 2.47.3