Fix child process spawning on linux (#773)

This commit is contained in:
Lukas Senionis
2023-01-19 08:40:12 +02:00
committed by GitHub
parent c4c0413f9e
commit c81aa99c38
5 changed files with 36 additions and 14 deletions
+2 -1
View File
@@ -33,6 +33,7 @@ class path;
} }
namespace process { namespace process {
class child; class child;
class group;
template<typename Char> template<typename Char>
class basic_environment; class basic_environment;
typedef basic_environment<char> environment; typedef basic_environment<char> environment;
@@ -323,7 +324,7 @@ std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &
// A list of names of displays accepted as display_name with the mem_type_e // A list of names of displays accepted as display_name with the mem_type_e
std::vector<std::string> display_names(mem_type_e hwdevice_type); std::vector<std::string> 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 { enum class thread_priority_e : int {
low, low,
+11 -1
View File
@@ -145,8 +145,9 @@ std::string get_mac_address(const std::string_view &address) {
return "00:00:00:00:00:00"s; 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; BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
if(!group) {
if(!file) { if(!file) {
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
} }
@@ -154,6 +155,15 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
} }
} }
else {
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);
}
}
}
void adjust_thread_priority(thread_priority_e priority) { void adjust_thread_priority(thread_priority_e priority) {
// Unimplemented // Unimplemented
+11 -1
View File
@@ -121,8 +121,9 @@ std::string get_mac_address(const std::string_view &address) {
return "00:00:00:00:00:00"s; 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; BOOST_LOG(warning) << "run_unprivileged() is not yet implemented for this platform. The new process will run with Sunshine's permissions."sv;
if(!group) {
if(!file) { if(!file) {
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
} }
@@ -130,6 +131,15 @@ bp::child run_unprivileged(const std::string &cmd, boost::filesystem::path &work
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
} }
} }
else {
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);
}
}
}
void adjust_thread_priority(thread_priority_e priority) { void adjust_thread_priority(thread_priority_e priority) {
// Unimplemented // Unimplemented
+4 -1
View File
@@ -375,7 +375,7 @@ void free_proc_thread_attr_list(LPPROC_THREAD_ATTRIBUTE_LIST list) {
HeapFree(GetProcessHeap(), 0, 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(); HANDLE shell_token = duplicate_shell_token();
if(!shell_token) { if(!shell_token) {
// This can happen if the shell has crashed. Fail the launch rather than risking launching with // 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, // 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. // bp::child() should have no problem opening it with any access rights it wants.
auto child = bp::child((bp::pid_t)process_info.dwProcessId); 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 // 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. // quickly, the PID could be reused if we close the process handle.
+2 -4
View File
@@ -150,7 +150,7 @@ int proc_t::execute(int app_id) {
find_working_directory(cmd, _env) : find_working_directory(cmd, _env) :
boost::filesystem::path(proc.working_dir); boost::filesystem::path(proc.working_dir);
BOOST_LOG(info) << "Spawning ["sv << cmd << "] in ["sv << 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) { if(ec) {
BOOST_LOG(warning) << "Couldn't spawn ["sv << cmd << "]: System: "sv << ec.message(); 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) : find_working_directory(proc.cmd, _env) :
boost::filesystem::path(proc.working_dir); boost::filesystem::path(proc.working_dir);
BOOST_LOG(info) << "Executing: ["sv << proc.cmd << "] in ["sv << 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) { if(ec) {
BOOST_LOG(warning) << "Couldn't run ["sv << proc.cmd << "]: System: "sv << ec.message(); BOOST_LOG(warning) << "Couldn't run ["sv << proc.cmd << "]: System: "sv << ec.message();
return -1; return -1;
} }
_process_handle.add(_process);
} }
fg.disable(); fg.disable();