diff --git a/lib/app_ipc.cpp b/lib/app_ipc.cpp index 39e745d81e..bf1deca374 100644 --- a/lib/app_ipc.cpp +++ b/lib/app_ipc.cpp @@ -471,7 +471,7 @@ int boinc_resolve_filename( // must initialize buf since fgets() on an empty file won't do anything // buf[0] = 0; - p =fgets(buf, sizeof(buf), fp); + p = fgets(buf, sizeof(buf), fp); fclose(fp); // If it's the XML tag, return its value, @@ -502,6 +502,31 @@ int boinc_resolve_filename_s(const char *virtual_name, string& physical_name) { return 0; } +// if the given file is a soft link of the form ../../project_dir/x, +// return x, else return empty string +// +string resolve_soft_link(const char* project_dir, const char* file) { + char buf[1024], physical_name[1024]; + FILE* fp = boinc_fopen(file, "r"); + if (!fp) { + return string(""); + } + buf[0] = 0; + char* p = fgets(buf, sizeof(buf), fp); + fclose(fp); + if (!p) { + return string(""); + } + if (!parse_str(buf, "", physical_name, sizeof(physical_name))) { + return string(""); + } + sprintf(buf, "../../%s/", project_dir); + if (strstr(physical_name, buf) != physical_name) { + return string(""); + } + return string(physical_name + strlen(buf)); +} + void url_to_project_dir(char* url, char* dir) { char buf[256]; escape_project_url(url, buf); diff --git a/lib/app_ipc.h b/lib/app_ipc.h index 617bbfd8b3..1c0028f191 100644 --- a/lib/app_ipc.h +++ b/lib/app_ipc.h @@ -250,6 +250,7 @@ int parse_graphics_file(FILE* f, GRAPHICS_INFO* gi); extern int boinc_link(const char* phys_name, const char* logical_name); extern int boinc_resolve_filename_s(const char*, std::string&); +extern std::string resolve_soft_link(const char* project_dir, const char* file); extern void url_to_project_dir(char* url, char* dir); extern "C" { diff --git a/samples/wrapper/wrapper.cpp b/samples/wrapper/wrapper.cpp index 7c06ad5fa9..96490c4100 100644 --- a/samples/wrapper/wrapper.cpp +++ b/samples/wrapper/wrapper.cpp @@ -36,12 +36,19 @@ // // Contributor: Andrew J. Younge (ajy4490@umiacs.umd.edu) +// comment out the following to disable checking that +// executables are signed. +// Doing so introduces a security vulnerability. +// +#define CHECK_EXECUTABLES + #ifndef _WIN32 #include "config.h" #endif #include #include #include +#include #ifdef _WIN32 #include "boinc_win.h" #include "win_util.h" @@ -62,6 +69,7 @@ #include "version.h" #include "boinc_api.h" +#include "app_ipc.h" #include "graphics2.h" #include "boinc_zip.h" #include "diagnostics.h" @@ -997,6 +1005,40 @@ int read_checkpoint(int& ntasks_completed, double& cpu, double& rt) { return 0; } +// Check whether executable files (tasks and daemons) are code-signed. +// The client supplies a list of app version files, which are code-signed. +// For each executable file: +// - check that it's a soft link +// - check that it's of the form ../../project_url/x +// - check that "x" is in the list of app version files +// +void check_execs(vector &t) { + for (unsigned int i=0; i (int)tasks.size()) { fprintf(stderr, "%s Checkpoint file: ntasks_completed too large: %d > %d\n",