wrapper: check that task executables are in the list of app files from client

This commit is contained in:
David Anderson 2015-09-23 00:02:52 -07:00
parent 3b7969b1fd
commit d503836a6a
3 changed files with 73 additions and 1 deletions

View File

@ -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 <soft_link> 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, "<soft_link>", 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);

View File

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

View File

@ -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 <stdio.h>
#include <vector>
#include <string>
#include <algorithm>
#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<TASK> &t) {
for (unsigned int i=0; i<t.size(); i++) {
TASK &task = t[i];
string phys_name = resolve_soft_link(
aid.project_dir, task.application.c_str()
);
if (phys_name.empty()) {
fprintf(stderr, "task executable %s is not a link\n",
phys_name.c_str()
);
boinc_finish(1);
}
if (std::find(aid.app_files.begin(), aid.app_files.end(), phys_name) == aid.app_files.end()) {
fprintf(stderr, "task executable %s is not in app version\n",
task.application.c_str()
);
boinc_finish(1);
}
}
}
void check_executables() {
if (aid.app_files.size() == 0) return;
check_execs(tasks);
check_execs(daemons);
}
int main(int argc, char** argv) {
BOINC_OPTIONS options;
int retval, ntasks_completed;
@ -1060,6 +1102,10 @@ int main(int argc, char** argv) {
boinc_get_init_data(aid);
#ifdef CHECK_EXECUTABLES
check_executables();
#endif
if (ntasks_completed > (int)tasks.size()) {
fprintf(stderr,
"%s Checkpoint file: ntasks_completed too large: %d > %d\n",