From c81aa99c381a3ab144f49369735924b74e00516c Mon Sep 17 00:00:00 2001 From: Lukas Senionis Date: Thu, 19 Jan 2023 08:40:12 +0200 Subject: [PATCH] Fix child process spawning on linux (#773) --- src/platform/common.h | 3 ++- src/platform/linux/misc.cpp | 18 ++++++++++++++---- src/platform/macos/misc.cpp | 18 ++++++++++++++---- src/platform/windows/misc.cpp | 5 ++++- src/process.cpp | 6 ++---- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/platform/common.h b/src/platform/common.h index b9558484..89fdfe5c 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -33,6 +33,7 @@ class path; } namespace process { class child; +class group; template class basic_environment; typedef basic_environment environment; @@ -323,7 +324,7 @@ std::shared_ptr display(mem_type_e hwdevice_type, const std::string & // A list of names of displays accepted as display_name with the mem_type_e std::vector display_names(mem_type_e hwdevice_type); -boost::process::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, boost::process::environment &env, FILE *file, std::error_code &ec); +boost::process::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group); enum class thread_priority_e : int { low, diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index be606228..b5660fe9 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -145,13 +145,23 @@ std::string get_mac_address(const std::string_view &address) { return "00:00:00:00:00:00"s; } -bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec) { +bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv; - if(!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + if(!group) { + if(!file) { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + } + else { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + } } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + if(!file) { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group); + } + else { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group); + } } } diff --git a/src/platform/macos/misc.cpp b/src/platform/macos/misc.cpp index 199471e9..cb9c0c52 100644 --- a/src/platform/macos/misc.cpp +++ b/src/platform/macos/misc.cpp @@ -121,13 +121,23 @@ std::string get_mac_address(const std::string_view &address) { return "00:00:00:00:00:00"s; } -bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec) { +bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv; - if(!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + if(!group) { + if(!file) { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + } + else { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + } } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + if(!file) { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group); + } + else { + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group); + } } } diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index 9c1307b1..c89b0f2c 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -375,7 +375,7 @@ void free_proc_thread_attr_list(LPPROC_THREAD_ATTRIBUTE_LIST list) { HeapFree(GetProcessHeap(), 0, list); } -bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec) { +bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &working_dir, bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { HANDLE shell_token = duplicate_shell_token(); if(!shell_token) { // This can happen if the shell has crashed. Fail the launch rather than risking launching with @@ -490,6 +490,9 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work // Since we are always spawning a process with a less privileged token than ourselves, // bp::child() should have no problem opening it with any access rights it wants. auto child = bp::child((bp::pid_t)process_info.dwProcessId); + if(group) { + group->add(child); + } // Only close handles after bp::child() has opened the process. If the process terminates // quickly, the PID could be reused if we close the process handle. diff --git a/src/process.cpp b/src/process.cpp index 21e633ae..3d3bd3e7 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -150,7 +150,7 @@ int proc_t::execute(int app_id) { find_working_directory(cmd, _env) : boost::filesystem::path(proc.working_dir); BOOST_LOG(info) << "Spawning ["sv << cmd << "] in ["sv << working_dir << ']'; - auto child = platf::run_unprivileged(cmd, working_dir, _env, _pipe.get(), ec); + auto child = platf::run_unprivileged(cmd, working_dir, _env, _pipe.get(), ec, nullptr); if(ec) { BOOST_LOG(warning) << "Couldn't spawn ["sv << cmd << "]: System: "sv << ec.message(); } @@ -168,13 +168,11 @@ int proc_t::execute(int app_id) { find_working_directory(proc.cmd, _env) : boost::filesystem::path(proc.working_dir); BOOST_LOG(info) << "Executing: ["sv << proc.cmd << "] in ["sv << working_dir << ']'; - _process = platf::run_unprivileged(proc.cmd, working_dir, _env, _pipe.get(), ec); + _process = platf::run_unprivileged(proc.cmd, working_dir, _env, _pipe.get(), ec, &_process_handle); if(ec) { BOOST_LOG(warning) << "Couldn't run ["sv << proc.cmd << "]: System: "sv << ec.message(); return -1; } - - _process_handle.add(_process); } fg.disable();