Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac: More fixes for MacOS 13 and Xcode 14 #5010

Merged
merged 5 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions client/check_security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ bool IsUserInGroup(char* groupName);
static int CheckNestedDirectories(
char * basepath, int depth,
int use_sandbox, int isManager,
char * path_to_error,
bool isSlotDir, char * path_to_error,
int len
);

#if (! defined(__WXMAC__) && ! defined(_MAC_INSTALLER))
#include "sandbox.h"

static char * PersistentFGets(char *buf, size_t buflen, FILE *f);
static void GetPathToThisProcess(char* outbuf, size_t maxLen);
#endif
Expand Down Expand Up @@ -348,7 +350,7 @@ int use_sandbox, int isManager, char* path_to_error, int len
return -1026;

// Step through project directories
retval = CheckNestedDirectories(full_path, 1, use_sandbox, isManager, path_to_error, len);
retval = CheckNestedDirectories(full_path, 1, use_sandbox, isManager, false, path_to_error, len);
if (retval)
return retval;
}
Expand All @@ -368,7 +370,7 @@ int use_sandbox, int isManager, char* path_to_error, int len
return -1029;

// Step through slot directories
retval = CheckNestedDirectories(full_path, 1, use_sandbox, isManager, path_to_error, len);
retval = CheckNestedDirectories(full_path, 1, use_sandbox, isManager, true, path_to_error, len);
if (retval)
return retval;
}
Expand Down Expand Up @@ -483,6 +485,7 @@ int use_sandbox, int isManager, char* path_to_error, int len
static int CheckNestedDirectories(
char * basepath, int depth,
int use_sandbox, int isManager,
bool isSlotDir,
char * path_to_error, int len
) {
int isDirectory;
Expand Down Expand Up @@ -527,10 +530,35 @@ static int CheckNestedDirectories(
if (depth > 1) {
// files and subdirectories created by projects may have owner boinc_master or boinc_project
if ( (sbuf.st_uid != boinc_master_uid) && (sbuf.st_uid != boinc_project_uid) ) {
retval = -1202;
break;
}
} else {
if (!isSlotDir) {
retval = -1202;
break;
} else { // Slots
// Graphics apps called by screensaver or Manager (via Show
// Graphics button) now write files in their slot directory
// as the logged in user, not boinc_master. In most cases,
// the manager or screensaver will tell the client to fix
// all ownerships in that slot directory, but a crash can
// prevent that. As a backup strategy, we ignore ownership
// of files in slot directories under the Manager, and fix
// them in the client.
#if (! defined(__WXMAC__) && ! defined(_MAC_INSTALLER))
char* s = strstr(full_path, "/slots/");
if (s) {
s = strchr(s+1, '/');
if (s) {
int slot = atoi(s+1);
fix_slot_owners(slot); // client
}
}

#elif defined(_MAC_INSTALLER)
retval = -1202;
break;
#endif
} // isSlotDir
} // bad uid
} else { // depth == 1
// project & slot directories (projects/setiathome.berkeley.edu, slots/0 etc.)
// must have owner boinc_master
if (sbuf.st_uid != boinc_master_uid) {
Expand Down Expand Up @@ -581,7 +609,7 @@ static int CheckNestedDirectories(
#endif
continue; // Client can't check subdirectories owned by boinc_project
}
retval = CheckNestedDirectories(full_path, depth + 1, use_sandbox, isManager, path_to_error, len);
retval = CheckNestedDirectories(full_path, depth + 1, use_sandbox, isManager, isSlotDir, path_to_error, len);
if (retval)
break;
}
Expand Down
8 changes: 5 additions & 3 deletions client/gui_rpc_server_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1378,9 +1378,11 @@ static void stop_graphics_app(pid_t thePID,
argv[3] = (char *)pidString;
argc = 4;
#endif
// Graphics apps run by Manager write files in slot directory
// as logged in user, not boinc_master. This ugly hack uses
// setprojectgrp to fix all ownerships in this slot directory.
// Graphics apps called by screensaver or Manager (via Show
// Graphics button) now write files in their slot directory
// as the logged in user, not boinc_master. This ugly hack
// uses setprojectgrp to fix all ownerships in this slot
// directory.
// To fix all ownerships in the slot directory, invoke the
// run_graphics_app RPC with operation "stop", slot number
// for the operand and empty string for screensaverLoginUser
Expand Down
71 changes: 59 additions & 12 deletions client/sandbox.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
// Copyright (C) 2022 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand All @@ -23,10 +23,13 @@
#include "config.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>
#include <pwd.h>
#include <stdlib.h>
#endif

#include "error_numbers.h"
Expand Down Expand Up @@ -175,14 +178,12 @@ int kill_via_switcher(int pid) {
return switcher_exec(SWITCHER_FILE_NAME, cmd);
}

#ifndef _DEBUG
static int lookup_group(const char* name, gid_t& gid) {
struct group* gp = getgrnam(name);
if (!gp) return ERR_GETGRNAM;
gid = gp->gr_gid;
return 0;
}
#endif

int remove_project_owned_file_or_dir(const char* path) {
char cmd[5120];
Expand Down Expand Up @@ -213,26 +214,72 @@ int get_project_gid() {
return 0;
}

// Graphics apps run by Manager write files in slot directory
// as logged in user, not boinc_master. This ugly hack uses
// Graphics apps called by screensaver or Manager (via Show
// Graphics button) now write files in their slot directory as
// the logged in user, not boinc_master. This ugly hack uses
// setprojectgrp to fix all ownerships in this slot directory.
int fix_slot_owners(const int slot){
char path[MAXPATHLEN];
#ifdef __APPLE__
char relative_path[100];
char full_path[MAXPATHLEN];

if (g_use_sandbox) {
snprintf(relative_path, sizeof(relative_path), "slots/%d", slot);
realpath(relative_path, full_path);
fix_owners_in_directory(full_path);
}
#endif
return 0;
}

int fix_owners_in_directory(char* dir_path) {
char item_path[MAXPATHLEN];
char quoted_item_path[MAXPATHLEN+2];
DIR* dirp;
struct stat sbuf;
int retval = 0;
bool isDirectory = false;
passwd *pw;
uid_t boinc_master_uid = -1;
uid_t boinc_project_uid = -1;
gid_t boinc_project_gid = -1;

pw = getpwnam(BOINC_MASTER_USER_NAME);
if (pw == NULL) return -1;
boinc_master_uid = pw->pw_uid;

pw = getpwnam(BOINC_PROJECT_USER_NAME);
if (pw == NULL) return -1;
boinc_project_uid = pw->pw_uid;

snprintf(path, sizeof(path), "slots/%d", slot);
dirp = opendir(path);
lookup_group(BOINC_PROJECT_GROUP_NAME, boinc_project_gid);

dirp = opendir(dir_path);
if (!dirp) return ERR_READDIR;
while (1) {
dirent* dp = readdir(dirp);
if (!dp) break;
if (dp->d_name[0] == '.') continue;
snprintf(path, sizeof(path), "\"/Library/Application Support/BOINC Data/slots/%d/%s\"", slot, dp->d_name);
set_to_project_group(path);
snprintf(item_path, sizeof(item_path), "%s/%s", dir_path, dp->d_name);
retval = lstat(item_path, &sbuf);
if (retval)
break; // Should never happen

isDirectory = S_ISDIR(sbuf.st_mode);
if (isDirectory) {
fix_owners_in_directory(item_path);
}

if ( (sbuf.st_uid == boinc_master_uid) || (sbuf.st_uid == boinc_project_uid) ) {
if (sbuf.st_gid == boinc_project_gid) {
continue;
}
}
snprintf(quoted_item_path, sizeof(quoted_item_path),"\"%s\"", item_path);
set_to_project_group(quoted_item_path);
}
closedir(dirp);

return 0;
return retval;
}

int set_to_project_group(const char* path) {
Expand Down
5 changes: 4 additions & 1 deletion client/sandbox.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
// Copyright (C) 2022 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand All @@ -18,6 +18,7 @@
extern int kill_via_switcher(int pid);
extern int get_project_gid();
extern int fix_slot_owners(const int slot);
extern int fix_owners_in_directory(char* dir_path);
extern int set_to_project_group(const char* path);
extern int switcher_exec(const char* util_filename, const char* cmdline);
extern int client_clean_out_dir(
Expand All @@ -28,6 +29,8 @@ extern int remove_project_owned_dir(const char* name);
extern int remove_project_owned_file_or_dir(const char* path);
extern int check_security(int use_sandbox, int isManager, char* path_to_error, int len);

#define BOINC_MASTER_USER_NAME "boinc_master"
#define BOINC_PROJECT_USER_NAME "boinc_project"
#define BOINC_PROJECT_GROUP_NAME "boinc_project"

extern bool g_use_sandbox;
2 changes: 1 addition & 1 deletion client/setprojectgrp.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
// Copyright (C) 2022 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand Down
2 changes: 1 addition & 1 deletion client/switcher.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2020 University of California
// Copyright (C) 2022 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand Down
20 changes: 20 additions & 0 deletions clientscr/gfx_cleanup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "gui_rpc_client.h"
#include "util.h"
#include "mac_util.h"
#include "shmem.h"

#define CREATE_LOG 0
#define USE_TIMER 0
Expand All @@ -50,6 +51,13 @@
pthread_t MonitorParentThread = 0;
bool quit_MonitorParentThread = false;

struct ss_shmem_data {
pid_t gfx_pid;
int gfx_slot;
};

static struct ss_shmem_data* ss_shmem = NULL;

#if USE_TIMER
time_t startTime = 0;
time_t endTime = 0;
Expand Down Expand Up @@ -104,6 +112,18 @@ void killGfxApp(pid_t thePID) {
}
print_to_log_file("in gfx_cleanup: killGfxApp(%d): rpc->run_graphics_app(test) returned pid %d, retval %d when i = %d", thePID, p, retval, i);

// Graphics apps called by screensaver or Manager (via Show
// Graphics button) now write files in their slot directory as
// the logged in user, not boinc_master. This ugly hack tells
// BOINC client to fix all ownerships in this slot directory
char shmem_name[MAXPATHLEN];
snprintf(shmem_name, sizeof(shmem_name), "/tmp/boinc_ss_%s", userName);
retval = attach_shmem_mmap(shmem_name, (void**)&ss_shmem);
if (ss_shmem) {
rpc->run_graphics_app("stop", ss_shmem->gfx_slot, "");
ss_shmem->gfx_slot = -1;
}

rpc->close();
#endif
return;
Expand Down
33 changes: 19 additions & 14 deletions clientscr/gfx_switcher.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2020 University of California
// Copyright (C) 2022 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
Expand Down Expand Up @@ -82,7 +82,12 @@ static void strip_cr(char *buf);

void * MonitorScreenSaverEngine(void* param);

pid_t* pid_for_shmem = NULL;
struct ss_shmem_data {
pid_t gfx_pid;
int gfx_slot;
};

static struct ss_shmem_data* ss_shmem = NULL;

int main(int argc, char** argv) {
passwd *pw;
Expand Down Expand Up @@ -207,15 +212,16 @@ int main(int argc, char** argv) {
print_to_log_file("gfx_switcher: Child PID=%d", pid);
#endif
snprintf(shmem_name, sizeof(shmem_name), "/tmp/boinc_ss_%s", screensaverLoginUser);
retval = attach_shmem_mmap(shmem_name, (void**)&pid_for_shmem);
if (pid_for_shmem != 0) {
*pid_for_shmem = pid;
retval = attach_shmem_mmap(shmem_name, (void**)&ss_shmem);
if (ss_shmem != 0) {
ss_shmem->gfx_pid = pid;
ss_shmem->gfx_slot = -1; // Default GFX has no slot number
}
pthread_create(&monitorScreenSaverEngineThread, NULL, MonitorScreenSaverEngine, &pid);
waitpid(pid, 0, 0);
pthread_cancel(monitorScreenSaverEngineThread);
if (pid_for_shmem != 0) {
*pid_for_shmem = 0;
if (ss_shmem != 0) {
ss_shmem->gfx_pid = 0;
}
return 0;
}
Expand All @@ -229,8 +235,6 @@ int main(int argc, char** argv) {
retval = boinc_resolve_filename(gfx_app_path, resolved_path, sizeof(resolved_path));
if (retval) return retval;

argv[2] = resolved_path;

#if VERBOSE // For debugging only
print_to_log_file("gfx_switcher using fork()");;
#endif
Expand Down Expand Up @@ -273,15 +277,16 @@ int main(int argc, char** argv) {
} else {
char shmem_name[MAXPATHLEN];
snprintf(shmem_name, sizeof(shmem_name), "/tmp/boinc_ss_%s", screensaverLoginUser);
retval = attach_shmem_mmap(shmem_name, (void**)&pid_for_shmem);
if (pid_for_shmem != 0) {
*pid_for_shmem = pid;
retval = attach_shmem_mmap(shmem_name, (void**)&ss_shmem);
if (ss_shmem != 0) {
ss_shmem->gfx_pid = pid;
ss_shmem->gfx_slot = atoi(argv[2]);
}
pthread_create(&monitorScreenSaverEngineThread, NULL, MonitorScreenSaverEngine, &pid);
waitpid(pid, 0, 0);
pthread_cancel(monitorScreenSaverEngineThread);
if (pid_for_shmem != 0) {
*pid_for_shmem = 0;
if (ss_shmem != 0) {
ss_shmem ->gfx_pid = 0;
}
return 0;
}
Expand Down
Loading