Skip to content

Commit

Permalink
Quit client and server when starting with elevated privileges
Browse files Browse the repository at this point in the history
Launching client and server with elevated privileges can cause files and folders to have inconsistent permissions and should never be necessary. Therefore, immediately quit client and server if elevated privileges are detected.

On Unix, this mean the process was launched either by the "root" user itself or by using the "sudo" command on a regular user.

On Windows, this means the process was launched by giving it administrative access using User Account Control (UAC). This does not include the user itself having the administrator role, as this is very common on Windows and in itself does not cause issues with permissions, as long as the user stays administrator.

Add `os_has_elevated_privileges` to check for elevated privileges of the current process. Tests are also expected to not be run with elevated privileges.
  • Loading branch information
Robyt3 committed Sep 8, 2023
1 parent f3eaa10 commit 7e56caa
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/base/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4535,6 +4535,23 @@ void os_locale_str(char *locale, size_t length)
str_copy(locale, "en-US", length);
}

bool os_has_elevated_privileges()
{
#if defined(CONF_FAMILY_WINDOWS)
HANDLE token_handle;
dbg_assert(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token_handle), "OpenProcessToken failure");
TOKEN_ELEVATION token_elevation;
DWORD token_elevation_size = sizeof(TOKEN_ELEVATION);
dbg_assert(GetTokenInformation(token_handle, TokenElevation, &token_elevation, token_elevation_size, &token_elevation_size), "GetTokenInformation failure");
const bool elevated = token_elevation.TokenIsElevated != 0;
CloseHandle(token_handle);
return elevated;
#else
// Check if the effective user ID or real user ID is 0 (root)
return geteuid() == 0 || getuid() == 0;
#endif
}

#if defined(CONF_EXCEPTION_HANDLING)
#if defined(CONF_FAMILY_WINDOWS)
static HMODULE exception_handling_module = nullptr;
Expand Down
13 changes: 13 additions & 0 deletions src/base/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -2749,6 +2749,19 @@ bool os_version_str(char *version, size_t length);
*/
void os_locale_str(char *locale, size_t length);

/**
* Returns whether the current process was launched with elevated privileges.
* On Unix, this mean the process was launched either by the "root" user itself
* or by using the "sudo" command on a regular user.
* On Windows, this means the process was launched by giving it administrative
* access using User Account Control (UAC). This does not include the user itself
* having the administrator role, as this is very common on Windows and in itself
* does not cause issues with permissions, as long as the user stays administrator.
*
* @return true if process was launched with elevated privileges, false otherwise
*/
bool os_has_elevated_privileges();

#if defined(CONF_EXCEPTION_HANDLING)
void init_exception_handler();
void set_exception_handler_log_file(const char *log_file_path);
Expand Down
8 changes: 8 additions & 0 deletions src/engine/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4571,6 +4571,14 @@ int main(int argc, const char **argv)
vpLoggers.push_back(pFutureAssertionLogger);
log_set_global_logger(log_logger_collection(std::move(vpLoggers)).release());

if(os_has_elevated_privileges())
{
const char *pMessage = "You are trying to launch the game with elevated privileges (admin/root).\n"
"This can cause issues and is not necessary. Please launch the game without elevated privileges.";
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Elevated privileges (admin/root) detected", pMessage, nullptr);
return -1;
}

std::stack<std::function<void()>> CleanerFunctions;
std::function<void()> PerformCleanup = [&CleanerFunctions]() mutable {
while(!CleanerFunctions.empty())
Expand Down
6 changes: 6 additions & 0 deletions src/engine/server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ int main(int argc, const char **argv)
vpLoggers.push_back(pFutureAssertionLogger);
log_set_global_logger(log_logger_collection(std::move(vpLoggers)).release());

if(os_has_elevated_privileges())
{
log_error("server", "Elevated privileges detected. Launch the server without elevated privileges.");
return -1;
}

if(secure_random_init() != 0)
{
dbg_msg("secure", "could not initialize secure RNG");
Expand Down
5 changes: 5 additions & 0 deletions src/test/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ TEST(Os, LocaleStr)
os_locale_str(aLocale, sizeof(aLocale));
EXPECT_STRNE(aLocale, "");
}

TEST(Os, HasElevatedPrivileges)
{
EXPECT_FALSE(os_has_elevated_privileges());
}

0 comments on commit 7e56caa

Please sign in to comment.