From df869d77131c6279c0e370f59066c1d5eb8e0abe Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 3 Apr 2003 18:35:40 +0000 Subject: [PATCH] server buffer overrun svn path=/trunk/boinc/; revision=1131 --- checkin_notes | 32 +++++++++++++++++++++++++++ client/app.C | 8 +++---- client/client_state.C | 4 ++-- client/client_types.C | 8 +++---- client/cs_scheduler.C | 12 +++++------ client/hostinfo_unix.C | 4 ++-- client/http.C | 12 +++++------ client/net_xfer.C | 2 +- client/pers_file_xfer.C | 5 +---- client/scheduler_op.C | 6 +++--- doc/index.html | 15 +++++++------ lib/filesys.C | 6 +++--- lib/util.C | 7 ++---- lib/util.h | 4 +++- sched/file_deleter.C | 4 ++-- sched/file_upload_handler.C | 6 ++++++ sched/handle_request.C | 19 ++++++++-------- sched/server_types.C | 43 ++++++++++++++----------------------- sched/server_types.h | 8 +++---- 19 files changed, 114 insertions(+), 91 deletions(-) diff --git a/checkin_notes b/checkin_notes index 0ad59023a2..f4ac8bd689 100755 --- a/checkin_notes +++ b/checkin_notes @@ -4003,3 +4003,35 @@ David Mar 31 2003 test_uc.php tools/ backend_lib.C + +David Apr 3 2003 + - added macro "safe_strcpy(x, y)" + ** USE THIS INSTEAD OF safe_strncpy(x, y, sizeof(x)) + - added macro "safe_strcat(x, y)" + ** USE THIS INSTEAD OF strcat() + - changed dynamically-allocated fields of SCHEDULER_REQUEST, + SCHEDULER_REPLY to static + + That combination of the above fixes a bug where a long + stderr_out could overwrite other fields of RESULT + + client/ + app.C + client_state.C + client_types.C + cs_scheduler.C + hostinfo_unix.C + http.C + net_xfer.C + pers_file_xfer.C + scheduler_op.C + doc/ + index.html + lib/ + filesys.C + util.C,h + sched/ + file_deleter.C + file_upload_handler.C + handle_request.C + server_types.C,h diff --git a/client/app.C b/client/app.C index 4c273acb75..2e046668ec 100644 --- a/client/app.C +++ b/client/app.C @@ -140,8 +140,8 @@ int ACTIVE_TASK::start(bool first_time) { memset(&aid, 0, sizeof(aid)); - safe_strncpy(aid.user_name, wup->project->user_name, sizeof(aid.user_name)); - safe_strncpy(aid.team_name, wup->project->team_name, sizeof(aid.team_name)); + safe_strcpy(aid.user_name, wup->project->user_name); + safe_strcpy(aid.team_name, wup->project->team_name); sprintf(aid.comm_obj_name, "boinc_%d", slot); if (wup->project->project_specific_prefs) { extract_venue( @@ -208,8 +208,8 @@ int ACTIVE_TASK::start(bool first_time) { fip = app_version->app_files[i].file_info; get_pathname(fip, file_path); if (i == 0) { - safe_strncpy(exec_name, fip->name, sizeof(exec_name)); - safe_strncpy(exec_path, file_path, sizeof(exec_path)); + safe_strcpy(exec_name, fip->name); + safe_strcpy(exec_path, file_path); } if (first_time) { sprintf(link_path, "%s%s%s", slot_dir, PATH_SEPARATOR, fip->name); diff --git a/client/client_state.C b/client/client_state.C index 68f58a8301..dfe2ede7e1 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -1344,11 +1344,11 @@ void CLIENT_STATE::parse_env_vars() { } if ((p = getenv("SOCKS_USER"))) { - safe_strncpy(socks_user_name, p, sizeof(socks_user_name)); + safe_strcpy(socks_user_name, p); } if ((p = getenv("SOCKS_PASSWD"))) { - safe_strncpy(socks_user_passwd, p, sizeof(socks_user_passwd)); + safe_strcpy(socks_user_passwd, p); } } diff --git a/client/client_types.C b/client/client_types.C index ecb4fb6beb..6286bebd99 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -221,9 +221,9 @@ int PROJECT::write_state(FILE* out) { // void PROJECT::copy_state_fields(PROJECT& p) { scheduler_urls = p.scheduler_urls; - safe_strncpy(project_name, p.project_name, sizeof(project_name)); - safe_strncpy(user_name, p.user_name, sizeof(user_name)); - safe_strncpy(team_name, p.team_name, sizeof(team_name)); + safe_strcpy(project_name, p.project_name); + safe_strcpy(user_name, p.user_name); + safe_strcpy(team_name, p.team_name); user_total_credit = p.user_total_credit; user_expavg_credit = p.user_expavg_credit; user_create_time = p.user_create_time; @@ -239,7 +239,7 @@ void PROJECT::copy_state_fields(PROJECT& p) { min_rpc_time = p.min_rpc_time; master_url_fetch_pending = p.master_url_fetch_pending; sched_rpc_pending = p.sched_rpc_pending; - safe_strncpy(code_sign_key, p.code_sign_key, sizeof(code_sign_key)); + safe_strcpy(code_sign_key, p.code_sign_key); } int APP::parse(FILE* in) { diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index b474ebac14..15e57d5b85 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -342,13 +342,13 @@ int CLIENT_STATE::handle_scheduler_reply( if (retval) return retval; if (strlen(sr.project_name)) { - safe_strncpy(project->project_name, sr.project_name, sizeof(project->project_name)); + safe_strcpy(project->project_name, sr.project_name); } if (strlen(sr.user_name)) { - safe_strncpy(project->user_name, sr.user_name, sizeof(project->user_name)); + safe_strcpy(project->user_name, sr.user_name); } if (strlen(sr.team_name)) { - safe_strncpy(project->team_name, sr.team_name, sizeof(project->team_name)); + safe_strcpy(project->team_name, sr.team_name); } project->user_total_credit = sr.user_total_credit; project->user_expavg_credit = sr.user_expavg_credit; @@ -387,7 +387,7 @@ int CLIENT_STATE::handle_scheduler_reply( sr.global_prefs_xml ); fclose(f); - safe_strncpy(host_venue, sr.host_venue, sizeof(host_venue)); + safe_strcpy(host_venue, sr.host_venue); retval = global_prefs.parse_file(host_venue); if (retval) return retval; install_global_prefs(); @@ -416,7 +416,7 @@ int CLIENT_STATE::handle_scheduler_reply( if (sr.code_sign_key) { if (!strlen(project->code_sign_key)) { - safe_strncpy(project->code_sign_key, sr.code_sign_key, sizeof(project->code_sign_key)); + safe_strcpy(project->code_sign_key, sr.code_sign_key); } else { if (sr.code_sign_key_signature) { retval = verify_string2( @@ -424,7 +424,7 @@ int CLIENT_STATE::handle_scheduler_reply( project->code_sign_key, signature_valid ); if (!retval && signature_valid) { - safe_strncpy(project->code_sign_key, sr.code_sign_key, sizeof(project->code_sign_key)); + safe_strcpy(project->code_sign_key, sr.code_sign_key); } else { fprintf(stdout, "New code signing key from %s doesn't validate\n", diff --git a/client/hostinfo_unix.C b/client/hostinfo_unix.C index 8bf632cef4..584ae7b00a 100644 --- a/client/hostinfo_unix.C +++ b/client/hostinfo_unix.C @@ -187,8 +187,8 @@ void parse_cpuinfo(HOST_INFO& host) { void get_osinfo(HOST_INFO& host) { struct utsname u; uname(&u); - safe_strncpy(host.os_name, u.sysname, sizeof(host.os_name)); - safe_strncpy(host.os_version, u.release, sizeof(host.os_version)); + safe_strcpy(host.os_name, u.sysname); + safe_strcpy(host.os_version, u.release); } #endif diff --git a/client/http.C b/client/http.C index 74312a9572..d3f1192b40 100644 --- a/client/http.C +++ b/client/http.C @@ -49,9 +49,9 @@ void parse_url(char* url, char* host, int &port, char* file) { char buf[256]; if (strncmp(url, "http://", 7) == 0) { - safe_strncpy(buf, url+7, sizeof(buf)); + safe_strcpy(buf, url+7); } else { - safe_strncpy(buf, url, sizeof(buf)); + safe_strcpy(buf, url); } p = strchr(buf, '/'); if (p) { @@ -225,7 +225,7 @@ int HTTP_OP::init_get(char* url, char* out, bool del_old_file, double off) { file_offset = off; parse_url(url, hostname, port, filename); NET_XFER::init(use_http_proxy?proxy_server_name:hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE); - safe_strncpy(outfile, out, sizeof(outfile)); + safe_strcpy(outfile, out); http_op_type = HTTP_OP_GET; http_op_state = HTTP_STATE_CONNECTING; if (use_http_proxy) { @@ -246,8 +246,8 @@ int HTTP_OP::init_post(char* url, char* in, char* out) { parse_url(url, hostname, port, filename); NET_XFER::init(use_http_proxy?proxy_server_name:hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE); - safe_strncpy(infile, in, sizeof(infile)); - safe_strncpy(outfile, out, sizeof(outfile)); + safe_strcpy(infile, in); + safe_strcpy(outfile, out); retval = file_size(infile, size); if (retval) return retval; content_length = (int)size; @@ -280,7 +280,7 @@ int HTTP_OP::init_post2( NET_XFER::init(use_http_proxy?proxy_server_name:hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE); req1 = r1; if (in) { - safe_strncpy(infile, in, sizeof(infile)); + safe_strcpy(infile, in); file_offset = offset; retval = file_size(infile, size); if (retval) { diff --git a/client/net_xfer.C b/client/net_xfer.C index f2e6fca32c..34884d29e9 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -174,7 +174,7 @@ void NET_XFER::init(char* host, int p, int b) { file = NULL; io_ready = false; error = 0; - safe_strncpy(hostname, host, sizeof(hostname)); + safe_strcpy(hostname, host); port = p; blocksize = (b > MAX_BLOCKSIZE ? MAX_BLOCKSIZE : b); xfer_speed = 0; diff --git a/client/pers_file_xfer.C b/client/pers_file_xfer.C index 6d8a10d433..67f76ab187 100644 --- a/client/pers_file_xfer.C +++ b/client/pers_file_xfer.C @@ -81,10 +81,7 @@ bool PERS_FILE_XFER::start_xfer() { file_xfer = new FILE_XFER; if (gstate.use_http_proxy) { file_xfer->use_http_proxy = true; - safe_strncpy( - file_xfer->proxy_server_name, gstate.proxy_server_name, - sizeof(file_xfer->proxy_server_name) - ); + safe_strcpy(file_xfer->proxy_server_name, gstate.proxy_server_name); file_xfer->proxy_server_port = gstate.proxy_server_port; } if (is_upload) { diff --git a/client/scheduler_op.C b/client/scheduler_op.C index aaceba5da2..c52e03dd58 100644 --- a/client/scheduler_op.C +++ b/client/scheduler_op.C @@ -178,7 +178,7 @@ int SCHEDULER_OP::start_rpc() { FILE *f; int retval; - safe_strncpy(scheduler_url, project->scheduler_urls[url_index].text, sizeof(scheduler_url)); + safe_strcpy(scheduler_url, project->scheduler_urls[url_index].text); if (log_flags.sched_ops) { printf("Sending request to scheduler: %s\n", scheduler_url); } @@ -191,7 +191,7 @@ int SCHEDULER_OP::start_rpc() { } if (gstate.use_http_proxy) { http_op.use_http_proxy = true; - safe_strncpy(http_op.proxy_server_name, gstate.proxy_server_name, sizeof(http_op.proxy_server_name)); + safe_strcpy(http_op.proxy_server_name, gstate.proxy_server_name); http_op.proxy_server_port = gstate.proxy_server_port; } retval = http_op.init_post( @@ -217,7 +217,7 @@ int SCHEDULER_OP::init_master_fetch(PROJECT* p) { } if (gstate.use_http_proxy) { http_op.use_http_proxy = true; - safe_strncpy(http_op.proxy_server_name, gstate.proxy_server_name, sizeof(http_op.proxy_server_name)); + safe_strcpy(http_op.proxy_server_name, gstate.proxy_server_name); http_op.proxy_server_port = gstate.proxy_server_port; } retval = http_op.init_get(project->master_url, MASTER_FILE_NAME, true); diff --git a/doc/index.html b/doc/index.html index 1a4f075283..1a9dd6739f 100644 --- a/doc/index.html +++ b/doc/index.html @@ -11,7 +11,7 @@ Berkeley Open Infrastructure for Network Computing (BOINC) -combines PCs to form a parallel supercomputer. +combines PCs into supercomputers. @@ -60,19 +60,20 @@ Help debug and enhance the BOINC software. Contact us

-
BOINC development -is hosted at Sourceforge.net -

-SourceForge Logo +is hosted at +SourceForge Logo

Status and news

+March 31, 2003 +
+We are preparing a BOINC-based version of SETI@home. +See a preview of the graphics. +

March 25, 2003
Non-English diff --git a/lib/filesys.C b/lib/filesys.C index 7edc06919e..1640830caa 100755 --- a/lib/filesys.C +++ b/lib/filesys.C @@ -80,7 +80,7 @@ DIRREF dir_open(char* p) { if(!is_dir(p)) return NULL; dirp = (DIR_DESC*) calloc(sizeof(DIR_DESC), 1); dirp->first = true; - safe_strncpy(dirp->path, p, sizeof(dirp->path)); + safe_strcpy(dirp->path, p); strcat(dirp->path, "\\*"); dirp->handle = INVALID_HANDLE_VALUE; #endif @@ -159,7 +159,7 @@ int file_delete(char* path) { retval = remove(path); #endif if (retval) { - safe_strncpy(failed_file, path, sizeof(failed_file)); + safe_strcpy(failed_file, path); return ERR_UNLINK; } return 0; @@ -201,7 +201,7 @@ int clean_out_dir(char* dirpath) { dirp = dir_open(dirpath); if (!dirp) return -1; while (1) { - safe_strncpy(filename,"",sizeof(filename)); + strcpy(filename, ""); retval = dir_scan(filename, dirp, sizeof(filename)); if (retval) break; sprintf(path, "%s%s%s", dirpath, PATH_SEPARATOR, filename); diff --git a/lib/util.C b/lib/util.C index 530d13f176..c631158fac 100755 --- a/lib/util.C +++ b/lib/util.C @@ -280,12 +280,9 @@ void escape_url(char *in, char*out) { out[y] = 0; } -char * safe_strncpy(char* dst, char* src, int len) { - char *retval; - - retval = strncpy(dst, src, len); +void safe_strncpy(char* dst, char* src, int len) { + strncpy(dst, src, len); dst[len-1]=0; - return retval; } char* timestamp() { diff --git a/lib/util.h b/lib/util.h index de53d6f5ed..e5b4bbbe5e 100755 --- a/lib/util.h +++ b/lib/util.h @@ -28,7 +28,9 @@ extern double drand(); extern void c2x(char *what); extern void unescape_url(char *url); extern void escape_url(char *in, char*out); -extern char* safe_strncpy(char*, char*, int); +extern void safe_strncpy(char*, char*, int); +#define safe_strcpy(x, y) safe_strncpy(x, y, sizeof(x)) +#define safe_strcat(x, y) if (strlen(x)+strlen(y)", filename, sizeof(filename))) { diff --git a/sched/file_upload_handler.C b/sched/file_upload_handler.C index de6c11f79e..86caf31003 100644 --- a/sched/file_upload_handler.C +++ b/sched/file_upload_handler.C @@ -36,6 +36,7 @@ CONFIG config; +#define STDERR_FILENAME "file_upload_handler.out" //#define DEBUG #define MAX_FILES 32 @@ -303,6 +304,11 @@ int main() { int retval; R_RSA_PUBLIC_KEY key; + if (!freopen(STDERR_FILENAME, "a", stderr)) { + fprintf(stderr, "Can't redirect stderr\n"); + exit(1); + } + retval = config.parse_file(); if (retval) { return_error("can't read config file"); diff --git a/sched/handle_request.C b/sched/handle_request.C index c0f642713f..ed3310e395 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -34,12 +34,12 @@ using namespace std; #include "db.h" #include "backend_lib.h" #include "parse.h" +#include "util.h" #include "server_types.h" #include "main.h" #include "handle_request.h" #define MIN_SECONDS_TO_SEND 0 -#define SECONDS_PER_DAY (3600*24) #define MAX_SECONDS_TO_SEND (28*SECONDS_PER_DAY) #define MAX_WUS_TO_SEND 10 @@ -318,7 +318,7 @@ int handle_global_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { unsigned int req_mod_time, db_mod_time; bool need_update; reply.send_global_prefs = false; - if (sreq.global_prefs_xml) { + if (strlen(sreq.global_prefs_xml)) { need_update = false; parse_int(sreq.global_prefs_xml, "", (int)req_mod_time); if (strlen(reply.user.global_prefs)) { @@ -332,10 +332,7 @@ int handle_global_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { need_update = true; } if (need_update) { - strncpy( - reply.user.global_prefs, sreq.global_prefs_xml, - sizeof(reply.user.global_prefs) - ); + safe_strcpy(reply.user.global_prefs, sreq.global_prefs_xml); db_user_update(reply.user); } } else { @@ -552,9 +549,10 @@ void send_code_sign_key( int i, retval; char path[256]; - if (sreq.code_sign_key) { + if (strlen(sreq.code_sign_key)) { if (strcmp(sreq.code_sign_key, code_sign_key)) { write_log("received old code sign key\n"); + // look for a signature file // for (i=0; ; i++) { @@ -576,8 +574,9 @@ void send_code_sign_key( "Please report this to project." ); } else { - reply.code_sign_key = strdup(code_sign_key); - reply.code_sign_key_signature = signature; + safe_strcpy(reply.code_sign_key, code_sign_key); + safe_strcpy(reply.code_sign_key_signature, signature); + free(signature); } } free(oldkey); @@ -585,7 +584,7 @@ void send_code_sign_key( } } } else { - reply.code_sign_key = strdup(code_sign_key); + safe_strcpy(reply.code_sign_key, code_sign_key); } } diff --git a/sched/server_types.C b/sched/server_types.C index 90ef454207..71badcc733 100644 --- a/sched/server_types.C +++ b/sched/server_types.C @@ -26,17 +26,14 @@ using namespace std; #include #include "parse.h" +#include "util.h" #include "main.h" #include "server_types.h" SCHEDULER_REQUEST::SCHEDULER_REQUEST() { - global_prefs_xml = 0; - code_sign_key = 0; } SCHEDULER_REQUEST::~SCHEDULER_REQUEST() { - if (global_prefs_xml) free(global_prefs_xml); - if (code_sign_key) free(code_sign_key); } int SCHEDULER_REQUEST::parse(FILE* fin) { @@ -46,7 +43,8 @@ int SCHEDULER_REQUEST::parse(FILE* fin) { strcpy(authenticator, ""); hostid = 0; work_req_seconds = 0; - global_prefs_xml = strdup(""); + strcpy(global_prefs_xml, ""); + strcpy(code_sign_key, ""); fgets(buf, 256, fin); if (!match_tag(buf, "")) return 1; @@ -60,12 +58,12 @@ int SCHEDULER_REQUEST::parse(FILE* fin) { else if (parse_int(buf, "", core_client_minor_version)) continue; else if (parse_int(buf, "", work_req_seconds)) continue; else if (match_tag(buf, "")) { - global_prefs_xml = strdup("\n"); + strcpy(global_prefs_xml, "\n"); while (fgets(buf, 256, fin)) { if (strstr(buf, "")) break; - strcatdup(global_prefs_xml, buf); + safe_strcat(global_prefs_xml, buf); } - strcatdup(global_prefs_xml, "\n"); + safe_strcat(global_prefs_xml, "\n"); } else if (match_tag(buf, "")) { host.parse(fin); @@ -85,7 +83,7 @@ int SCHEDULER_REQUEST::parse(FILE* fin) { continue; } else if (match_tag(buf, "")) { - dup_element_contents(fin, "", &code_sign_key); + copy_element_contents(fin, "", code_sign_key, sizeof(code_sign_key)); } else { sprintf(ebuf, "SCHEDULER_REQUEST::parse(): unrecognized: %s\n", buf); @@ -102,8 +100,8 @@ SCHEDULER_REPLY::SCHEDULER_REPLY() { strcpy(message, ""); strcpy(message_priority, ""); send_global_prefs = false; - code_sign_key = 0; - code_sign_key_signature = 0; + strcpy(code_sign_key, ""); + strcpy(code_sign_key_signature, ""); memset(&user, 0, sizeof(user)); memset(&host, 0, sizeof(host)); memset(&team, 0, sizeof(team)); @@ -111,8 +109,6 @@ SCHEDULER_REPLY::SCHEDULER_REPLY() { } SCHEDULER_REPLY::~SCHEDULER_REPLY() { - if (code_sign_key) free(code_sign_key); - if (code_sign_key_signature) free(code_sign_key_signature); } int SCHEDULER_REPLY::write(FILE* fout) { @@ -210,12 +206,12 @@ int SCHEDULER_REPLY::write(FILE* fout) { for (i=0; i\n", fout); fputs(code_sign_key, fout); fputs("\n", fout); } - if (code_sign_key_signature) { + if (strlen(code_sign_key_signature)) { fputs("\n", fout); fputs(code_sign_key_signature, fout); fputs("\n", fout); @@ -280,26 +276,19 @@ int RESULT::parse_from_client(FILE* fin) { else if (parse_int(buf, "", client_state)) continue; else if (parse_double(buf, "", cpu_time)) continue; else if (match_tag(buf, "")) { - strcat(xml_doc_out, buf); + safe_strcat(xml_doc_out, buf); while (fgets(buf, 256, fin)) { - // protect againt buffer overrun - if (strlen(buf) + strlen(xml_doc_out) <= MAX_BLOB_SIZE) { - strcat(xml_doc_out, buf); - } + safe_strcat(xml_doc_out, buf); if (match_tag(buf, "")) break; } continue; - } - else if (match_tag(buf, "" )) { + } else if (match_tag(buf, "" )) { while (fgets(buf, 256, fin)) { if (match_tag(buf, "")) break; - if (strlen(stderr_out) + strlen(buf) < MAX_BLOB_SIZE) { - strcat(stderr_out, buf); - } + safe_strcat(stderr_out, buf); } continue; - } - else { + } else { sprintf(ebuf, "RESULT::parse_from_client(): unrecognized: %s\n", buf); write_log(ebuf); } diff --git a/sched/server_types.h b/sched/server_types.h index f43a042237..433185849c 100644 --- a/sched/server_types.h +++ b/sched/server_types.h @@ -43,8 +43,8 @@ struct SCHEDULER_REQUEST { int core_client_minor_version; int rpc_seqno; int work_req_seconds; - char* global_prefs_xml; - char* code_sign_key; + char global_prefs_xml[MAX_BLOB_SIZE]; + char code_sign_key[MAX_BLOB_SIZE]; HOST host; vector results; @@ -73,8 +73,8 @@ struct SCHEDULER_REPLY { vectorwus; vectorresults; vectorresult_acks; - char* code_sign_key; - char* code_sign_key_signature; + char code_sign_key[MAX_BLOB_SIZE]; + char code_sign_key_signature[MAX_BLOB_SIZE]; SCHEDULER_REPLY(); ~SCHEDULER_REPLY();