SS: Under Mac Sandbox security, terminate default screensaver graphics app via gfx_switcher

svn path=/trunk/boinc/; revision=17722
This commit is contained in:
Charlie Fenton 2009-04-02 10:25:16 +00:00
parent fc544d15aa
commit 3840b814b7
7 changed files with 120 additions and 26 deletions

View File

@ -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

View File

@ -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);

View File

@ -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 <unistd.h>
#include <cstdio>
#include <cstring>
@ -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<argc; i++) {
print_to_log_file("switcher arg %d: %s\n", i, argv[i]);
print_to_log_file("switcher arg %d: %s", i, argv[i]);
}
#endif
@ -104,7 +108,7 @@ int main(int argc, char** argv) {
#if 0 // For debugging only
for (int i=2; i<argc; i++) {
print_to_log_file("calling execv with arg %d: %s\n", i-2, argv[i]);
print_to_log_file("calling execv with arg %d: %s", i-2, argv[i]);
}
#endif
@ -129,7 +133,7 @@ int main(int argc, char** argv) {
#if 0 // For debugging only
for (int i=2; i<argc; i++) {
print_to_log_file("calling execv with arg %d: %s\n", i-2, argv[i]);
print_to_log_file("calling execv with arg %d: %s", i-2, argv[i]);
}
#endif
@ -142,10 +146,16 @@ int main(int argc, char** argv) {
return errno;
}
if (strcmp(argv[1], "-kill_gfx") == 0) {
if ((strcmp(argv[1], "-kill_gfx") == 0) ||
(strcmp(argv[1], "-kill_default_gfx") == 0)) {
pid = atoi(argv[2]);
if (! pid) return EINVAL;
if ( kill(pid, SIGKILL)) return errno;
if ( kill(pid, SIGKILL)) {
#if 0 // For debugging only
print_to_log_file("kill(%d, SIGKILL) returned error %d", pid, errno);
#endif
return errno;
}
return 0;
}

View File

@ -42,7 +42,7 @@
//#include <drivers/event_status_driver.h>
// 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 */

View File

@ -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) {

View File

@ -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);

View File

@ -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