From 3840b814b7a651ca7a9f2483cb4e9f498c722af5 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Thu, 2 Apr 2009 10:25:16 +0000 Subject: [PATCH] SS: Under Mac Sandbox security, terminate default screensaver graphics app via gfx_switcher svn path=/trunk/boinc/; revision=17722 --- checkin_notes | 16 ++++++ clientscr/Mac_Saver_Module.h | 1 + clientscr/gfx_switcher.cpp | 24 ++++++--- clientscr/mac_saver_module.cpp | 2 +- clientscr/screensaver.cpp | 94 +++++++++++++++++++++++++++++----- clientscr/screensaver_win.h | 1 + mac_build/Mac_SA_Secure.sh | 8 +-- 7 files changed, 120 insertions(+), 26 deletions(-) diff --git a/checkin_notes b/checkin_notes index 44018f1660..54220b10b7 100644 --- a/checkin_notes +++ b/checkin_notes @@ -3541,3 +3541,19 @@ Charlie 1 Apr 2009 screensaver.cpp mac_build/ Mac_SA_Secure.sh + +Charlie 2 Apr 2009 + SS: Under Mac Sandbox security, terminate default screensaver graphics + app via gfx_switcher. This is safer because the man page for kill() + says the user ID of the process sending the signal must match that + of the target process, though in practice that seems not to be true + on the Mac. + + clientscr/ + gfx_switcher.cpp + mac_saver_module.cpp + Mac_Saver_Module.h + screensaver.cpp + screensaver_win.h + mac_build/ + Mac_SA_Secure.sh diff --git a/clientscr/Mac_Saver_Module.h b/clientscr/Mac_Saver_Module.h index 8e91a9590c..9ae24838bc 100644 --- a/clientscr/Mac_Saver_Module.h +++ b/clientscr/Mac_Saver_Module.h @@ -99,6 +99,7 @@ protected: void* DataManagementProc(); static void* DataManagementProcStub( void* param ); int terminate_screensaver(int& graphics_application, RESULT *worker_app); + int terminate_default_screensaver(int& graphics_application); int launch_screensaver(RESULT* rp, int& graphics_application); int launch_default_screensaver(char *dir_path, int& graphics_application); void HandleRPCError(void); diff --git a/clientscr/gfx_switcher.cpp b/clientscr/gfx_switcher.cpp index 74c6685ccd..f738312a02 100644 --- a/clientscr/gfx_switcher.cpp +++ b/clientscr/gfx_switcher.cpp @@ -19,7 +19,10 @@ // // Used by screensaver to: // - launch graphics application at given slot number as user & owner boinc_project -// - kill graphics application with given process ID +// - kill graphics application with given process ID as user & owner boinc_project +// - launch default graphics application as user & owner boinc_master +// - kill default graphics application with given process ID as user & owner boinc_master +// #include #include #include @@ -58,7 +61,8 @@ int main(int argc, char** argv) { if (argc < 2) return EINVAL; - if (strcmp(argv[1], "-default_gfx") == 0) { + if ((strcmp(argv[1], "-default_gfx") == 0) || + (strcmp(argv[1], "-kill_default_gfx") == 0)) { strlcpy(user_name, "boinc_master", sizeof(user_name)); } else { strlcpy(user_name, "boinc_project", sizeof(user_name)); @@ -94,7 +98,7 @@ int main(int argc, char** argv) { print_to_log_file( "current directory = %s", current_dir); for (int i=0; i // Flags for testing & debugging -#define CREATE_LOG 1 +#define CREATE_LOG 0 #define USE_SPECIAL_LOG_FILE 0 #define TEXTLOGOFREQUENCY 60 /* Number of times per second to update moving logo with text */ diff --git a/clientscr/screensaver.cpp b/clientscr/screensaver.cpp index 880e66c6d0..f79c55a6fa 100644 --- a/clientscr/screensaver.cpp +++ b/clientscr/screensaver.cpp @@ -151,7 +151,7 @@ CLEANUP: } -// Launch the graphics application +// Launch a project (science) graphics application // #ifdef _WIN32 int CScreensaver::launch_screensaver(RESULT* rp, HANDLE& graphics_application) @@ -244,7 +244,7 @@ int CScreensaver::launch_screensaver(RESULT* rp, int& graphics_application) } -// Terminate the graphics application +// Terminate the project (science) graphics application // #ifdef _WIN32 int CScreensaver::terminate_screensaver(HANDLE& graphics_application, RESULT *worker_app) @@ -252,21 +252,23 @@ int CScreensaver::terminate_screensaver(HANDLE& graphics_application, RESULT *wo int CScreensaver::terminate_screensaver(int& graphics_application, RESULT *worker_app) #endif { - if (graphics_application) { // V6 Graphics - kill_program(graphics_application); #ifdef __APPLE__ if (!m_bScience_gfx_running) { return 0; // Don't use gfx_switcher for default gfx app } - // For sandbox security, use gfx_switcher to launch gfx app - // as user boinc_project and group boinc_project. - int retval = 0; + // Under sandbox security, use gfx_switcher to kill gfx app as + // user boinc_project and group boinc_project. The man page + // for kill() says the user ID of the process sending the signal + // must match that of the target process, though in practice + // that seems not to be true on the Mac. + char current_dir[MAXPATHLEN]; char gfx_pid[16]; pid_t thePID; int i; + int retval = 0; sprintf(gfx_pid, "%d", graphics_application); getcwd( current_dir, sizeof(current_dir)); @@ -285,16 +287,19 @@ int CScreensaver::terminate_screensaver(int& graphics_application, RESULT *worke 0, thePID ); - if (retval) return retval; - + for (i=0; i<200; i++) { boinc_sleep(0.01); // Wait 2 seconds max // Prevent gfx_switcher from becoming a zombie - if (waitpid(thePID, 0, WNOHANG) == thePID) break; + if (waitpid(thePID, 0, WNOHANG) == thePID) { + break; + } } - return retval; -#endif +#else graphics_application = 0; +#endif + // For safety, call kill_program even under Apple sandbox security + kill_program(graphics_application); } else { // V5 and Older DISPLAY_INFO di; @@ -395,6 +400,63 @@ int CScreensaver::launch_default_screensaver(char *dir_path, int& graphics_appli } +// Terminate the default graphics application +// +#ifdef _WIN32 +int CScreensaver::terminate_default_screensaver(HANDLE& graphics_application) +#else +int CScreensaver::terminate_default_screensaver(int& graphics_application) +#endif +{ + int retval = 0; + + if (! graphics_application) return 0; + +#ifdef __APPLE__ + // Under sandbox security, use gfx_switcher to kill default gfx app + // as user boinc_master and group boinc_master. The man page for + // kill() says the user ID of the process sending the signal must + // match that of the target process, though in practice that seems + // not to be true on the Mac. + + char current_dir[MAXPATHLEN]; + char gfx_pid[16]; + pid_t thePID; + int i; + + sprintf(gfx_pid, "%d", graphics_application); + getcwd( current_dir, sizeof(current_dir)); + + char* argv[4]; + argv[0] = "gfx_switcher"; + argv[1] = "-kill_default_gfx"; + argv[2] = gfx_pid; + argv[3] = 0; + + retval = run_program( + current_dir, + m_gfx_Switcher_Path, + 3, + argv, + 0, + thePID + ); + + for (i=0; i<200; i++) { + boinc_sleep(0.01); // Wait 2 seconds max + // Prevent gfx_switcher from becoming a zombie + if (waitpid(thePID, 0, WNOHANG) == thePID) { + break; + } + } +#endif + + // For safety, call kill_program even under Apple sandbox security + kill_program(graphics_application); + return retval; +} + + // If we cannot connect to the core client: // - we retry connecting every 10 seconds // - we launch the default graphics application with the argument --retry_connect, so @@ -492,7 +554,11 @@ void *CScreensaver::DataManagementProc() // Are we supposed to exit the screensaver? if (m_QuitDataManagementProc) { // If main thread has requested we exit if (m_hGraphicsApplication || graphics_app_result_ptr) { - terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr); + if (m_bDefault_gfx_running) { + terminate_default_screensaver(m_hGraphicsApplication); + } else { + terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr); + } graphics_app_result_ptr = NULL; previous_result_ptr = NULL; m_hGraphicsApplication = 0; @@ -699,7 +765,7 @@ void *CScreensaver::DataManagementProc() if (graphics_app_result_ptr) { if (m_bDefault_gfx_running) { - kill_program(m_hGraphicsApplication); + terminate_default_screensaver(m_hGraphicsApplication); killing_default_gfx = true; // Remember how long default graphics ran during science phase if (default_saver_start_time_in_science_phase) { diff --git a/clientscr/screensaver_win.h b/clientscr/screensaver_win.h index 2cf1046853..af20b7ed5a 100644 --- a/clientscr/screensaver_win.h +++ b/clientscr/screensaver_win.h @@ -183,6 +183,7 @@ protected: static DWORD WINAPI DataManagementProcStub( LPVOID lpParam ); int terminate_screensaver(HANDLE& graphics_application, RESULT *worker_app); + int terminate_default_screensaver(HANDLE& graphics_application); int launch_screensaver(RESULT* rp, HANDLE& graphics_application); int launch_default_screensaver(char *dir_path, HANDLE& graphics_application); void HandleRPCError(void); diff --git a/mac_build/Mac_SA_Secure.sh b/mac_build/Mac_SA_Secure.sh index 9eb7e4d00a..5605519048 100755 --- a/mac_build/Mac_SA_Secure.sh +++ b/mac_build/Mac_SA_Secure.sh @@ -62,7 +62,7 @@ # sudo dscl . -delete /groups/boinc_master users mary # -# Last updated 4/1/09 for BOINC version 6.7 +# Last updated 4/2/09 for BOINC version 6.7 # WARNING: do not use this script with older versions of BOINC function make_boinc_user() { @@ -179,7 +179,7 @@ make_boinc_users dscl . -merge /groups/boinc_master users "$(LOGNAME)" dscl . -merge /groups/boinc_project users "$(LOGNAME)" -set_perm_recursive . boinc_master boinc_master u+rw,g+rw,o+-rw +set_perm_recursive . boinc_master boinc_master u+rw,g+rw,o-rw set_perm . boinc_master boinc_master 0771 if [ -f gui_rpc_auth.cfg ] ; then set_perm gui_rpc_auth.cfg boinc_master boinc_master 0660 @@ -214,8 +214,8 @@ if [ -f boinc ] ; then set_perm boinc boinc_master boinc_master 6555 # boinc client fi -if [ -f boinc_cmd ] ; then - set_perm boinc_cmd boinc_master boinc_master 0550 +if [ -f boinccmd ] ; then + set_perm boinccmd boinc_master boinc_master 0550 fi if [ -f ss_config.xml ] ; then