buffer length args

svn path=/trunk/boinc/; revision=431
This commit is contained in:
David Anderson 2002-09-22 23:27:14 +00:00
parent 9980bb7e00
commit 8d468c56f6
18 changed files with 237 additions and 174 deletions

View File

@ -139,7 +139,7 @@ int boinc_get_init_data(APP_INIT_DATA& app_init_data) {
// resolve XML soft links
//
int boinc_resolve_filename(char *virtual_name, char *physical_name) {
int boinc_resolve_filename(char *virtual_name, char *physical_name, int len) {
FILE *fp;
char buf[512];
@ -155,7 +155,7 @@ int boinc_resolve_filename(char *virtual_name, char *physical_name) {
// If it's the <soft_link> XML tag, return its value,
// otherwise, return the original file name
//
parse_str( buf, "<soft_link>", physical_name);
parse_str(buf, "<soft_link>", physical_name, len);
return 0;
}
@ -246,7 +246,7 @@ double boinc_cpu_time() {
}
#ifdef _WIN32
void CALLBACK on_timer( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime ) {
void CALLBACK on_timer(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) {
#else
void on_timer(int a) {
#endif
@ -273,7 +273,7 @@ void on_timer(int a) {
int set_timer(double period) {
int retval=0;
#ifdef _WIN32
retval = SetTimer( NULL, 0, (int)(period*1000), on_timer );
retval = SetTimer(NULL, 0, (int)(period*1000), on_timer);
#endif
#if HAVE_SIGNAL_H
@ -329,8 +329,8 @@ int parse_init_data_file(FILE* f, APP_INIT_DATA& ai) {
}
continue;
}
else if (parse_str(buf, "<user_name>", ai.user_name)) continue;
else if (parse_str(buf, "<team_name>", ai.team_name)) continue;
else if (parse_str(buf, "<user_name>", ai.user_name, sizeof(ai.user_name))) continue;
else if (parse_str(buf, "<team_name>", ai.team_name, sizeof(ai.team_name))) continue;
else if (parse_double(buf, "<total_cobblestones>", ai.total_cobblestones)) continue;
else if (parse_double(buf, "<recent_avg_cobblestones>", ai.recent_avg_cobblestones)) continue;
else if (parse_double(buf, "<wu_cpu_time>", ai.wu_cpu_time)) continue;
@ -397,14 +397,14 @@ int parse_fd_init_file(FILE* f) {
char buf[256],filename[256];
int filedesc;
while (fgets(buf, 256, f)) {
if (parse_str(buf, "<fdesc_dup_infile>", filename)) {
if (parse_str(buf, "<fdesc_dup_infile>", filename, sizeof(filename))) {
if (fgets(buf, 256, f)) {
if (parse_int(buf, "<fdesc_dup_innum>", filedesc)) {
freopen(filename, "r", stdin);
fprintf(stderr, "opened input file %s\n", filename);
}
}
} else if (parse_str(buf, "<fdesc_dup_outfile>", filename)) {
} else if (parse_str(buf, "<fdesc_dup_outfile>", filename, sizeof(filename))) {
if (fgets(buf, 256, f)) {
if (parse_int(buf, "<fdesc_dup_outnum>", filedesc)) {
freopen(filename, "w", stdout);

View File

@ -65,7 +65,7 @@ struct APP_INIT_DATA {
extern int boinc_init();
extern int boinc_get_init_data(APP_INIT_DATA&);
extern int boinc_finish(int);
extern int boinc_resolve_filename(char*, char*);
extern int boinc_resolve_filename(char*, char*, int len);
extern bool boinc_time_to_checkpoint();
extern int boinc_checkpoint_completed();
extern int boinc_fraction_done();

View File

@ -32,9 +32,9 @@ int run_slow = 0;
#define CHECKPOINT_FILE "concat_state"
int do_checkpoint(MFILE& mf, int filenum, int nchars ) {
int do_checkpoint(MFILE& mf, int filenum, int nchars) {
int retval;
char resolved_name[512],res_name2[512];
char res_name2[512];
FILE* f = fopen("temp", "w");
if (!f) return 1;
@ -43,7 +43,7 @@ int do_checkpoint(MFILE& mf, int filenum, int nchars ) {
fprintf(stderr, "APP: concat checkpointing\n");
boinc_resolve_filename( CHECKPOINT_FILE, res_name2 );
boinc_resolve_filename(CHECKPOINT_FILE, res_name2, sizeof(res_name2));
retval = mf.flush();
if (retval) return retval;
@ -57,7 +57,7 @@ void file_append(FILE* in, MFILE &out, int skip, int filenum) {
char buf[1];
int n,nread,retval;
fseek( in, skip, SEEK_SET );
fseek(in, skip, SEEK_SET);
nread = skip;
while (1) {
@ -66,11 +66,11 @@ void file_append(FILE* in, MFILE &out, int skip, int filenum) {
out.write(buf, 1, n);
nread += n;
if( boinc_time_to_checkpoint() ) {
fprintf( stderr, "Checkpoint.\n" );
retval = do_checkpoint( out, filenum, nread );
if( retval ) {
fprintf( stderr, "APP: concat checkpoint failed %d\n", retval );
if (boinc_time_to_checkpoint()) {
fprintf(stderr, "Checkpoint.\n");
retval = do_checkpoint(out, filenum, nread);
if (retval) {
fprintf(stderr, "APP: concat checkpoint failed %d\n", retval);
exit(1);
}
boinc_checkpoint_completed();
@ -115,26 +115,26 @@ int main(int argc, char** argv) {
fprintf(stderr, "APP: concat: argv[%d] is %s\n", i, argv[i]);
if (!strcmp(argv[i], "-run_slow")) run_slow = 1;
}
boinc_resolve_filename( CHECKPOINT_FILE, file_name );
state = fopen( file_name, "r" );
if( state ) {
fscanf( state, "%d %d", &file_num, &nchars );
boinc_resolve_filename(CHECKPOINT_FILE, file_name, sizeof(file_name));
state = fopen(file_name, "r");
if (state) {
fscanf(state, "%d %d", &file_num, &nchars);
mode = "a";
} else {
file_num = (run_slow ? 2 : 1);
nchars = 0;
mode = "w";
}
boinc_resolve_filename( argv[argc-1], file_name );
fprintf( stderr, "res: %s\n", file_name );
boinc_resolve_filename(argv[argc-1], file_name, sizeof(file_name));
fprintf(stderr, "res: %s\n", file_name);
retval = out.open(file_name, mode);
if (retval) {
fprintf(stderr, "APP: concat: can't open out file %s\n", argv[argc-1]);
exit(1);
}
for (i=file_num; i<argc-1; i++) {
boinc_resolve_filename( argv[i], file_name );
fprintf( stderr, "res: %s\n", file_name );
boinc_resolve_filename(argv[i], file_name, sizeof(file_name));
fprintf(stderr, "res: %s\n", file_name);
in = fopen(file_name, "r");
if (!in) {
fprintf(stderr, "APP: concat: can't open in file %s\n", argv[i]);

View File

@ -51,7 +51,7 @@
#endif
bool app_render(int xs, int ys, double time_of_day);
void renderBitmapString( float x, float y, void *font, char *string);
void renderBitmapString(float x, float y, void *font, char *string);
int DrawGLScene(GLvoid);
#endif
@ -80,7 +80,7 @@ int do_checkpoint(MFILE& mf, int nchars) {
client_time = fopen("../../client.time", "w");
boinc_get_init_data(uc_aid);
}
boinc_resolve_filename( "temp", resolved_name );
boinc_resolve_filename("temp", resolved_name, sizeof(resolved_name));
FILE* f = fopen(resolved_name, "w");
if (!f) return 1;
fprintf(f, "%d", nchars);
@ -91,7 +91,7 @@ int do_checkpoint(MFILE& mf, int nchars) {
// hopefully atomic part starts here
retval = mf.flush();
if (retval) return retval;
boinc_resolve_filename( CHECKPOINT_FILE, res_name2 );
boinc_resolve_filename(CHECKPOINT_FILE, res_name2, sizeof(res_name2));
retval = boinc_rename(resolved_name, res_name2);
if (retval) return retval;
// hopefully atomic part ends here
@ -143,7 +143,7 @@ int main(int argc, char **argv) {
my_start_time = time(0);
strcpy( the_char, "(none)\0" );
strcpy(the_char, "(none)\0");
retval = boinc_init();
if (retval) exit(retval);
@ -154,8 +154,8 @@ int main(int argc, char **argv) {
boinc_get_init_data(uc_aid);
boinc_resolve_filename( "in", resolved_name );
fprintf( stderr, "APP: upper_case: starting, argc %d\n", argc );
boinc_resolve_filename("in", resolved_name, sizeof(resolved_name));
fprintf(stderr, "APP: upper_case: starting, argc %d\n", argc);
for (i=0; i<argc; i++) {
fprintf(stderr, "APP: upper_case: argv[%d] is %s\n", i, argv[i]);
if (!strcmp(argv[i], "-run_slow")) run_slow = 1;
@ -163,16 +163,16 @@ int main(int argc, char **argv) {
}
run_slow = 1;
in = fopen(resolved_name, "r");
boinc_resolve_filename( CHECKPOINT_FILE, resolved_name );
boinc_resolve_filename(CHECKPOINT_FILE, resolved_name, sizeof(resolved_name));
state = fopen(resolved_name, "r");
if (state) {
fscanf(state, "%d", &nchars);
printf("nchars %d\n", nchars);
fseek(in, nchars, SEEK_SET);
boinc_resolve_filename( "out", resolved_name );
boinc_resolve_filename("out", resolved_name, sizeof(resolved_name));
retval = out.open(resolved_name, "a");
} else {
boinc_resolve_filename( "out", resolved_name );
boinc_resolve_filename("out", resolved_name, sizeof(resolved_name));
retval = out.open(resolved_name, "w");
}
if (retval) {
@ -183,7 +183,7 @@ int main(int argc, char **argv) {
while (1) {
c = fgetc(in);
if (c == EOF) break;
sprintf( the_char, "%c -> %c\0", c, toupper(c) );
sprintf(the_char, "%c -> %c\0", c, toupper(c));
c = toupper(c);
out._putchar(c);
nchars++;
@ -241,14 +241,14 @@ int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
renderBitmapString(xPos,yPos,GLUT_BITMAP_HELVETICA_12,the_char);
xPos += xDelta;
yPos += yDelta;
if( xPos < -1 || xPos > 1 ) xDelta *= -1;
if( yPos < -1 || yPos > 1 ) yDelta *= -1;
if (xPos < -1 || xPos > 1) xDelta *= -1;
if (yPos < -1 || yPos > 1) yDelta *= -1;
sprintf( text, "User: %s", uc_aid.user_name );
sprintf(text, "User: %s", uc_aid.user_name);
renderBitmapString(-1.3,1.1,GLUT_BITMAP_HELVETICA_12, text);
sprintf( text, "Team: %s", uc_aid.team_name );
sprintf(text, "Team: %s", uc_aid.team_name);
renderBitmapString(-1.3,1.0,GLUT_BITMAP_HELVETICA_12, text);
sprintf( text, "CPU Time: %f", uc_aid.wu_cpu_time );
sprintf(text, "CPU Time: %f", uc_aid.wu_cpu_time);
renderBitmapString(-1.3,0.9,GLUT_BITMAP_HELVETICA_12, text);
return TRUE; // Everything Went OK

View File

@ -1858,3 +1858,27 @@ Eric September 18, 2002
graphics_api.C
graphics_api.h
windows_opengl.cpp
David Sept 22, 2002
- Various changes to prevent buffer overrun in servers;
parse_str and parse_attr now take a buffer length arg
api/
boinc_api.C,h
apps/
concat.C
upper_case.C
client/
app.C
client_types.C
file_xfer.C
hostinfo.C
scheduler_op.C
doc/
account.html
lib/
parse.C,h
sched/
file_upload_handler.C
handle_request.C
server_types.C,h

View File

@ -295,7 +295,7 @@ int ACTIVE_TASK::start(bool first_time) {
argv[0] = exec_name;
parse_command_line(wup->command_line, argv+1);
if (log_flags.task_debug) print_argv(argv);
boinc_resolve_filename(exec_name, temp);
boinc_resolve_filename(exec_name, temp, sizeof(temp));
retval = execv(temp, argv);
fprintf(stderr, "execv failed: %d\n", retval);
perror("execv");
@ -664,14 +664,16 @@ bool ACTIVE_TASK_SET::poll_time() {
}
// Gets the next available free slot, or returns -1 if all slots are full
// TODO: don't use malloc here
//
int ACTIVE_TASK_SET::get_free_slot(int total_slots) {
int i;
unsigned int i;
char *slot_status;
if (active_tasks.size() >= total_slots)
if (active_tasks.size() >= (unsigned int)total_slots) {
return -1;
}
slot_status = (char *)calloc( sizeof(char), total_slots );
if (!slot_status) return -1;
@ -681,7 +683,7 @@ int ACTIVE_TASK_SET::get_free_slot(int total_slots) {
}
}
for (i=0; i<total_slots; i++) {
for (i=0; i<(unsigned int)total_slots; i++) {
if (!slot_status[i]) {
free(slot_status);
return i;
@ -746,8 +748,8 @@ int ACTIVE_TASK::parse(FILE* fin, CLIENT_STATE* cs) {
}
return 0;
}
else if (parse_str(buf, "<result_name>", result_name)) continue;
else if (parse_str(buf, "<project_master_url>", project_master_url)) continue;
else if (parse_str(buf, "<result_name>", result_name, sizeof(result_name))) continue;
else if (parse_str(buf, "<project_master_url>", project_master_url, sizeof(project_master_url))) continue;
else if (parse_int(buf, "<app_version_num>", app_version_num)) continue;
else if (parse_int(buf, "<slot>", slot)) continue;
else if (parse_double(buf, "<checkpoint_cpu_time>", checkpoint_cpu_time)) continue;

View File

@ -66,8 +66,8 @@ int PROJECT::parse_prefs(FILE* in) {
strcpy(authenticator, "");
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</project>")) return 0;
else if (parse_str(buf, "<master_url>", master_url)) continue;
else if (parse_str(buf, "<authenticator>", authenticator)) continue;
else if (parse_str(buf, "<master_url>", master_url, sizeof(master_url))) continue;
else if (parse_str(buf, "<authenticator>", authenticator, sizeof(authenticator))) continue;
else if (parse_double(buf, "<resource_share>", resource_share)) continue;
else if (match_tag(buf, "<project_specific>")) {
retval = dup_element_contents(in, "</project_specific>", &p);
@ -95,13 +95,13 @@ int PROJECT::parse_state(FILE* in) {
nrpc_failures = 0;
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</project>")) return 0;
else if (parse_str(buf, "<scheduler_url>", string.text)) {
else if (parse_str(buf, "<scheduler_url>", string.text, sizeof(string.text))) {
scheduler_urls.push_back(string);
continue;
}
else if (parse_str(buf, "<master_url>", master_url)) continue;
else if (parse_str(buf, "<project_name>", project_name)) continue;
else if (parse_str(buf, "<user_name>", user_name)) continue;
else if (parse_str(buf, "<master_url>", master_url, sizeof(master_url))) continue;
else if (parse_str(buf, "<project_name>", project_name, sizeof(project_name))) continue;
else if (parse_str(buf, "<user_name>", user_name, sizeof(user_name))) continue;
else if (parse_double(buf, "<total_credit>", total_credit)) continue;
else if (parse_double(buf, "<expavg_credit>", expavg_credit)) continue;
else if (parse_int(buf, "<rpc_seqno>", rpc_seqno)) continue;
@ -202,7 +202,7 @@ int APP::parse(FILE* in) {
project = NULL;
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</app>")) return 0;
else if (parse_str(buf, "<name>", name)) continue;
else if (parse_str(buf, "<name>", name, sizeof(name))) continue;
else fprintf(stderr, "APP::parse(): unrecognized: %s\n", buf);
}
return ERR_XML_PARSE;
@ -287,8 +287,8 @@ int FILE_INFO::parse(FILE* in, bool from_server) {
if (from_server) {
strcatdup(signed_xml, buf);
}
if (parse_str(buf, "<name>", name)) continue;
else if (parse_str(buf, "<url>", url.text)) {
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
else if (parse_str(buf, "<url>", url.text, sizeof(url.text))) {
urls.push_back(url);
continue;
}
@ -296,7 +296,7 @@ int FILE_INFO::parse(FILE* in, bool from_server) {
dup_element_contents(in, "</file_signature>", &file_signature);
continue;
}
else if (parse_str(buf, "<md5_cksum>", md5_cksum)) continue;
else if (parse_str(buf, "<md5_cksum>", md5_cksum, sizeof(md5_cksum))) continue;
else if (parse_double(buf, "<nbytes>", nbytes)) continue;
else if (parse_double(buf, "<max_nbytes>", max_nbytes)) continue;
else if (match_tag(buf, "<generated_locally/>")) generated_locally = true;
@ -409,7 +409,7 @@ int APP_VERSION::parse(FILE* in) {
project = NULL;
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</app_version>")) return 0;
else if (parse_str(buf, "<app_name>", app_name)) continue;
else if (parse_str(buf, "<app_name>", app_name, sizeof(app_name))) continue;
else if (match_tag(buf, "<file_ref>")) {
file_ref.parse(in);
app_files.push_back(file_ref);
@ -449,8 +449,8 @@ int FILE_REF::parse(FILE* in) {
main_program = false;
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</file_ref>")) return 0;
else if (parse_str(buf, "<file_name>", file_name)) continue;
else if (parse_str(buf, "<open_name>", open_name)) continue;
else if (parse_str(buf, "<file_name>", file_name, sizeof(file_name))) continue;
else if (parse_str(buf, "<open_name>", open_name, sizeof(open_name))) continue;
else if (parse_int(buf, "<fd>", fd)) continue;
else if (match_tag(buf, "<main_program/>")) main_program = true;
else fprintf(stderr, "FILE_REF::parse(): unrecognized: %s\n", buf);
@ -492,11 +492,11 @@ int WORKUNIT::parse(FILE* in) {
seconds_to_complete = 0;
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</workunit>")) return 0;
else if (parse_str(buf, "<name>", name)) continue;
else if (parse_str(buf, "<app_name>", app_name)) continue;
else if (parse_str(buf, "<name>", name, sizeof(name))) continue;
else if (parse_str(buf, "<app_name>", app_name, sizeof(app_name))) continue;
else if (parse_int(buf, "<version_num>", version_num)) continue;
else if (parse_str(buf, "<command_line>", command_line)) continue;
else if (parse_str(buf, "<env_vars>", env_vars)) continue;
else if (parse_str(buf, "<command_line>", command_line, sizeof(command_line))) continue;
else if (parse_str(buf, "<env_vars>", env_vars, sizeof(env_vars))) continue;
else if (parse_double(buf, "<seconds_to_complete>", seconds_to_complete)) continue;
else if (match_tag(buf, "<file_ref>")) {
file_ref.parse(in);
@ -534,7 +534,7 @@ int RESULT::parse_ack(FILE* in) {
strcpy(name, "");
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</result_ack>")) return 0;
else if (parse_str(buf, "<name>", name)) continue;
else if (parse_str(buf, "<name>", name, sizeof(name))) continue;
else fprintf(stderr, "RESULT::parse(): unrecognized: %s\n", buf);
}
return 1;
@ -564,8 +564,8 @@ int RESULT::parse_server(FILE* in) {
clear();
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</result>")) return 0;
if (parse_str(buf, "<name>", name)) continue;
if (parse_str(buf, "<wu_name>", wu_name)) continue;
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
if (parse_str(buf, "<wu_name>", wu_name, sizeof(wu_name))) continue;
if (parse_int(buf, "<report_deadline>", report_deadline)) continue;
if (match_tag(buf, "<file_ref>")) {
file_ref.parse(in);
@ -586,8 +586,8 @@ int RESULT::parse_state(FILE* in) {
clear();
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</result>")) return 0;
if (parse_str(buf, "<name>", name)) continue;
if (parse_str(buf, "<wu_name>", wu_name)) continue;
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
if (parse_str(buf, "<wu_name>", wu_name, sizeof(wu_name))) continue;
if (parse_int(buf, "<report_deadline>", report_deadline)) continue;
if (match_tag(buf, "<file_ref>")) {
file_ref.parse(in);

View File

@ -120,7 +120,7 @@ int FILE_XFER::parse_server_response(double &offset) {
parse_double(req1, "<nbytes>", offset);
parse_int(req1, "<status>", status);
// TODO: decide what to do with error string
//if (!parse_str(req1, "<error>", upload_offset) ) return -1;
//if (!parse_str(req1, "<error>", upload_offset, sizeof(upload_offset)) ) return -1;
return status;
}

View File

@ -33,17 +33,17 @@ int HOST_INFO::parse(FILE* in) {
while (fgets(buf, 256, in)) {
if (match_tag(buf, "</host_info>")) return 0;
else if (parse_int(buf, "<timezone>", timezone)) continue;
else if (parse_str(buf, "<domain_name>", domain_name)) continue;
else if (parse_str(buf, "<ip_addr>", ip_addr)) continue;
else if (parse_str(buf, "<domain_name>", domain_name, sizeof(domain_name))) continue;
else if (parse_str(buf, "<ip_addr>", ip_addr, sizeof(ip_addr))) continue;
else if (parse_int(buf, "<p_ncpus>", p_ncpus)) continue;
else if (parse_str(buf, "<p_vendor>", p_vendor)) continue;
else if (parse_str(buf, "<p_model>", p_model)) continue;
else if (parse_str(buf, "<p_vendor>", p_vendor, sizeof(p_vendor))) continue;
else if (parse_str(buf, "<p_model>", p_model, sizeof(p_model))) continue;
else if (parse_double(buf, "<p_fpops>", p_fpops)) continue;
else if (parse_double(buf, "<p_iops>", p_iops)) continue;
else if (parse_double(buf, "<p_membw>", p_membw)) continue;
else if (parse_double(buf, "<p_calculated>", p_calculated)) continue;
else if (parse_str(buf, "<os_name>", os_name)) continue;
else if (parse_str(buf, "<os_version>", os_version)) continue;
else if (parse_str(buf, "<os_name>", os_name, sizeof(os_name))) continue;
else if (parse_str(buf, "<os_version>", os_version, sizeof(os_version))) continue;
else if (parse_double(buf, "<m_nbytes>", m_nbytes)) continue;
else if (parse_double(buf, "<m_cache>", m_cache)) continue;
else if (parse_double(buf, "<m_swap>", m_swap)) continue;

View File

@ -163,7 +163,7 @@ int SCHEDULER_OP::parse_master_file(vector<STRING256> &urls) {
}
project->scheduler_urls.clear();
while (fgets(buf, 256, f)) {
if (parse_str(buf, "<scheduler>", str.text)) {
if (parse_str(buf, "<scheduler>", str.text, sizeof(str.text))) {
urls.push_back(str);
}
}
@ -376,9 +376,9 @@ int SCHEDULER_REPLY::parse(FILE* in) {
// Do nothing
} else if (match_tag(buf, "</scheduler_reply>")) {
return 0;
} else if (parse_str(buf, "<project_name>", project_name)) {
} else if (parse_str(buf, "<project_name>", project_name, sizeof(project_name))) {
continue;
} else if (parse_str(buf, "<user_name>", user_name)) {
} else if (parse_str(buf, "<user_name>", user_name, sizeof(user_name))) {
continue;
} else if (parse_double(buf, "<total_credit>", total_credit)) {
continue;
@ -428,8 +428,8 @@ int SCHEDULER_REPLY::parse(FILE* in) {
RESULT result;
result.parse_ack(in);
result_acks.push_back(result);
} else if (parse_str(buf, "<message", message)) {
parse_attr(buf, "priority", message_priority);
} else if (parse_str(buf, "<message", message, sizeof(message))) {
parse_attr(buf, "priority", message_priority, sizeof(message_priority));
continue;
} else {
fprintf(stderr, "SCHEDULER_REPLY::parse: unrecognized %s\n", buf);

View File

@ -10,6 +10,7 @@ This involves filling out a form with
<ul>
<li> An email address.
<li> A public "screen name" (real name or nickname).
This also serves as your login name for the project's web site.
<li> A web password
(used to log in to the project's web site).
<li> Country (optional)
@ -30,6 +31,9 @@ That's it!
You can go to the project web site to set your
<b>user preferences</b>.
<h3>Security</h3>
<p>
<h3>Multiple hosts under one account</h3>
<p>
You can run BOINC on many hosts, all under one account.

56
doc/server_security.html Normal file
View File

@ -0,0 +1,56 @@
<h3>Notes on server security</h3>
<p>
BOINC scheduling servers, data servers, and web servers
must be accessible via HTTP (port 80)
and therefore are potential targets for network attacks.
The possibility exists that BOINC software could
have vulnerabilities to such attacks.
<h3>Scheduling server</h3>
<p>
All network input to the scheduling server is read by calls of the form
<pre>fgets(buf, 256, stdin);</pre>
where buf is a 256-byte buffer.
There is no possibility of a buffer overrun from these calls.
In some cases data is copied out of the buffer to a second buffer;
this is done using functions
(<pre>parse_str()</pre>, <pre>parse_attr()</pre> and <pre>strncpy()</pre>)
that take a buffer-length argument,
so again there can be no buffer overruns.
<p>
The scheduling server doesn't run any secondary programs.
<p>
The scheduling server creates disk files in which it stores
request and reply messages.
These files have names of the form
PATH/sched_req_PID
where PATH is a compiled-in directory name (e.g. /tmp)
and PID is the server process ID.
There is no possibility of the server creating
executable files, or files in other directories.
<h3>File upload handler</h3>
<p>
The file upload handler parses its input
in the same way as the scheduling servers,
except for file data.
This data is read using fread() in fixed-sized increments.
So there are no buffer overruns.
<p>
The file upload handler reads and writes
files with names of the form BOINC_UPLOAD_DIR/filename,
where BOINC_UPLOAD_DIR is a compiled constant
for the directory where data files are stored.
"filename" is checked for ".." and such requests are ignored.
Hence files outside the directory cannot be read or written.
<p>
The only place where files are created (in copy_socket_to_file())
is a call "fopen(path, "wb");".
Hence no executable files or links are created.
<h3>PHP files</h3>
<p>
The PHP files in the participant and administrative
web directories (html_user and html_ops)
make no calls that access local files or run programs.

View File

@ -34,11 +34,17 @@
#include "parse.h"
#include "error_numbers.h"
// return true if the tag appears in the line
//
bool match_tag(char* buf, char* tag) {
if (strstr(buf, tag)) return true;
return false;
}
// parse an integer of the form <tag>1234</tag>
// return true if it's there
// Note: this doesn't check for the end tag
//
bool parse_int(char* buf, char* tag, int& x) {
char* p = strstr(buf, tag);
if (!p) return false;
@ -46,6 +52,8 @@ bool parse_int(char* buf, char* tag, int& x) {
return true;
}
// Same, for doubles
//
bool parse_double(char* buf, char* tag, double& x) {
char* p = strstr(buf, tag);
if (!p) return false;
@ -53,20 +61,25 @@ bool parse_double(char* buf, char* tag, double& x) {
return true;
}
bool parse_str(char* buf, char* tag, char* x) {
// parse a string of the form <tag>string</tag>
//
bool parse_str(char* buf, char* tag, char* dest, int len) {
char* p = strstr(buf, tag);
if (!p) return false;
p = strchr(p, '>');
char* q = strchr(p+1, '<');
*q = 0;
strcpy(x, p+1);
strncpy(dest, p+1, len);
dest[len-1] = 0;
return true;
}
void parse_attr(char* buf, char* name, char* out) {
// parse a string of the form name="string"
//
void parse_attr(char* buf, char* name, char* dest, int len) {
char* p, *q;
strcpy(out, "");
strcpy(dest, "");
p = strstr(buf, name);
if (!p) return;
p = strchr(p, '"');
@ -74,7 +87,8 @@ void parse_attr(char* buf, char* name, char* out) {
q = strchr(p+1, '"');
if (!q) return;
*q = 0;
strcpy(out, p+1);
strncpy(dest, p+1, len);
dest[len-1] = 0;
}
void copy_stream(FILE* in, FILE* out) {
@ -87,6 +101,8 @@ void copy_stream(FILE* in, FILE* out) {
}
}
// append to a malloc'd string
//
void strcatdup(char*& p, char* buf) {
p = (char*)realloc(p, strlen(p) + strlen(buf)+1);
if (!p) {
@ -96,6 +112,8 @@ void strcatdup(char*& p, char* buf) {
strcat(p, buf);
}
// copy from a file to a malloc'd string until the end tag is reached
//
int dup_element_contents(FILE* in, char* end_tag, char** pp) {
char buf[256];
@ -111,6 +129,8 @@ int dup_element_contents(FILE* in, char* end_tag, char** pp) {
return 1;
}
// read a file into a malloc'd string
//
int read_file_malloc(char* pathname, char*& str) {
char buf[256];
FILE* f;

View File

@ -22,8 +22,8 @@
extern bool parse(char*, char*);
extern bool parse_int(char*, char*, int&);
extern bool parse_double(char*, char*, double&);
extern bool parse_str(char*, char*, char*);
extern void parse_attr(char* buf, char* attrname, char* out);
extern bool parse_str(char*, char*, char*, int);
extern void parse_attr(char* buf, char* attrname, char* out, int len);
extern bool match_tag(char*, char*);
extern void copy_stream(FILE* in, FILE* out);
extern void strcatdup(char*& p, char* buf);

View File

@ -64,7 +64,7 @@ int FILE_INFO::parse(FILE* in) {
continue;
}
strcatdup(signed_xml, buf);
if (parse_str(buf, "<name>", name)) continue;
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
if (parse_double(buf, "<max_nbytes>", max_nbytes)) continue;
//fprintf(stderr, "file_upload_handler (%s): FILE_INFO::parse: unrecognized: %s \n", BOINC_USER, buf);
}
@ -158,7 +158,7 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) {
continue;
}
// Handle a file size request
else if (parse_str(buf, "<file_size_req>", file_name)) {
else if (parse_str(buf, "<file_size_req>", file_name, sizeof(file_name))) {
struct stat sbuf;
// TODO: check to ensure path doesn't point somewhere bad
//

View File

@ -133,7 +133,10 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
reply.host.rpc_seqno = sreq.rpc_seqno;
reply.host.rpc_time = time(0);
} else {
strcpy(reply.user.authenticator, sreq.authenticator);
strncpy(
reply.user.authenticator, sreq.authenticator,
sizeof(reply.user.authenticator)
);
retval = db_user_lookup_auth(reply.user);
if (retval) {
strcpy(reply.message, "Invalid or missing authenticator");
@ -170,10 +173,10 @@ int update_host_record(SCHEDULER_REQUEST& sreq, HOST& host) {
int retval;
host.timezone = sreq.host.timezone;
strcpy(host.domain_name, sreq.host.domain_name);
strcpy(host.serialnum, sreq.host.serialnum);
strncpy(host.domain_name, sreq.host.domain_name, sizeof(host.domain_name));
strncpy(host.serialnum, sreq.host.serialnum, sizeof(host.serialnum));
if (strcmp(host.last_ip_addr, sreq.host.last_ip_addr)) {
strcpy(host.last_ip_addr, sreq.host.last_ip_addr);
strncpy(host.last_ip_addr, sreq.host.last_ip_addr, sizeof(host.last_ip_addr));
} else {
host.nsame_ip_addr++;
}
@ -181,14 +184,14 @@ int update_host_record(SCHEDULER_REQUEST& sreq, HOST& host) {
host.connected_frac = sreq.host.connected_frac;
host.active_frac = sreq.host.active_frac;
host.p_ncpus = sreq.host.p_ncpus;
strcpy(host.p_vendor, sreq.host.p_vendor); // unlikely this will change
strcpy(host.p_model, sreq.host.p_model);
strncpy(host.p_vendor, sreq.host.p_vendor, sizeof(host.p_vendor)); // unlikely this will change
strncpy(host.p_model, sreq.host.p_model, sizeof(host.p_model));
host.p_fpops = sreq.host.p_fpops;
host.p_iops = sreq.host.p_iops;
host.p_membw = sreq.host.p_membw;
host.p_calculated = sreq.host.p_calculated;
strcpy(host.os_name, sreq.host.os_name);
strcpy(host.os_version, sreq.host.os_version);
strncpy(host.os_name, sreq.host.os_name, sizeof(host.os_name));
strncpy(host.os_version, sreq.host.os_version, sizeof(host.os_version));
host.m_nbytes = sreq.host.m_nbytes;
host.m_cache = sreq.host.m_cache;
host.m_swap = sreq.host.m_swap;
@ -209,7 +212,7 @@ int update_host_record(SCHEDULER_REQUEST& sreq, HOST& host) {
//
int handle_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
if (sreq.prefs_mod_time > reply.user.prefs_mod_time && strlen(sreq.prefs_xml)) {
strcpy(reply.user.prefs, sreq.prefs_xml);
strncpy(reply.user.prefs, sreq.prefs_xml, sizeof(reply.user.prefs));
reply.user.prefs_mod_time = sreq.prefs_mod_time;
if (reply.user.prefs_mod_time > (unsigned)time(0)) {
reply.user.prefs_mod_time = (unsigned)time(0);
@ -232,7 +235,7 @@ int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
for (i=0; i<sreq.results.size(); i++) {
rp = &sreq.results[i];
strcpy(result.name, rp->name);
strncpy(result.name, rp->name, sizeof(result.name));
retval = db_result_lookup_name(result);
if (retval) {
printf("can't find result %s\n", rp->name);
@ -245,6 +248,14 @@ int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
continue;
}
if (result.hostid != sreq.hostid) {
fprintf(stderr,
"got result from wrong host: %d %d\n",
result.hostid, sreq.hostid
);
continue;
}
// TODO: handle error returns
//
result.hostid = reply.host.id;
@ -252,8 +263,8 @@ int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
result.exit_status = rp->exit_status;
result.cpu_time = rp->cpu_time;
result.state = RESULT_STATE_DONE;
strcpy(result.stderr_out, rp->stderr_out);
strcpy(result.xml_doc_out, rp->xml_doc_out);
strncpy(result.stderr_out, rp->stderr_out, sizeof(result.stderr_out));
strncpy(result.xml_doc_out, rp->xml_doc_out, sizeof(result.xml_doc_out));
db_result_update(result);
retval = db_workunit(result.workunitid, wu);
@ -346,7 +357,7 @@ int send_work(
result.sent_time = time(0);
sprintf(result.name, "result_%d", result.id);
app = db.lookup_app(wu.appid);
strcpy(result.xml_doc_in, app->result_xml_template);
strncpy(result.xml_doc_in, app->result_xml_template, sizeof(result.xml_doc_in));
sprintf(prefix, "%s_", result.name);
process_result_template(
result.xml_doc_in, prefix, wu.name, result.name
@ -369,7 +380,7 @@ int send_work(
return 0;
}
// if the client has an old code sign key,
// if the client has an old code sign public key,
// send it the new one, with a signature based on the old one.
// If they don't have a code sign key, send them one
//

View File

@ -49,10 +49,10 @@ int SCHEDULER_REQUEST::parse(FILE* fin) {
if (!match_tag(buf, "<scheduler_request>")) return 1;
while (fgets(buf, 256, fin)) {
if (match_tag(buf, "</scheduler_request>")) return 0;
else if (parse_str(buf, "<authenticator>", authenticator)) continue;
else if (parse_str(buf, "<authenticator>", authenticator, sizeof(authenticator))) continue;
else if (parse_int(buf, "<hostid>", hostid)) continue;
else if (parse_int(buf, "<rpc_seqno>", rpc_seqno)) continue;
else if (parse_str(buf, "<platform_name>", platform_name)) continue;
else if (parse_str(buf, "<platform_name>", platform_name, sizeof(platform_name))) continue;
else if (parse_int(buf, "<core_client_version>", core_client_version)) continue;
else if (parse_int(buf, "<work_req_seconds>", work_req_seconds)) continue;
else if (parse_int(buf, "<prefs_mod_time>", (int)prefs_mod_time)) {
@ -98,6 +98,8 @@ SCHEDULER_REPLY::SCHEDULER_REPLY() {
send_prefs = false;
code_sign_key = 0;
code_sign_key_signature = 0;
memset(&user, 0, sizeof(user));
memset(&host, 0, sizeof(host));
}
SCHEDULER_REPLY::~SCHEDULER_REPLY() {
@ -239,7 +241,7 @@ int RESULT::parse_from_client(FILE* fin) {
memset(this, 0, sizeof(RESULT));
while (fgets(buf, 256, fin)) {
if (match_tag(buf, "</result>")) return 0;
else if (parse_str(buf, "<name>", name)) continue;
else if (parse_str(buf, "<name>", name, sizeof(name))) continue;
else if (parse_int(buf, "<exit_status>", exit_status)) continue;
else if (parse_double(buf, "<final_cpu_time>", cpu_time)) continue;
else if (match_tag(buf, "<file_info>")) {
@ -273,18 +275,18 @@ int HOST::parse(FILE* fin) {
while (fgets(buf, 256, fin)) {
if (match_tag(buf, "</host_info>")) return 0;
else if (parse_int(buf, "<timezone>", timezone)) continue;
else if (parse_str(buf, "<domain_name>", domain_name)) continue;
else if (parse_str(buf, "<serialnum>", serialnum)) continue;
else if (parse_str(buf, "<ip_addr>", last_ip_addr)) continue;
else if (parse_str(buf, "<domain_name>", domain_name, sizeof(domain_name))) continue;
else if (parse_str(buf, "<serialnum>", serialnum, sizeof(serialnum))) continue;
else if (parse_str(buf, "<ip_addr>", last_ip_addr, sizeof(last_ip_addr))) continue;
else if (parse_int(buf, "<p_ncpus>", p_ncpus)) continue;
else if (parse_str(buf, "<p_vendor>", p_vendor)) continue;
else if (parse_str(buf, "<p_model>", p_model)) continue;
else if (parse_str(buf, "<p_vendor>", p_vendor, sizeof(p_vendor))) continue;
else if (parse_str(buf, "<p_model>", p_model, sizeof(p_model))) continue;
else if (parse_double(buf, "<p_fpops>", p_fpops)) continue;
else if (parse_double(buf, "<p_iops>", p_iops)) continue;
else if (parse_double(buf, "<p_membw>", p_membw)) continue;
else if (parse_double(buf, "<p_calculated>", p_calculated)) continue;
else if (parse_str(buf, "<os_name>", os_name)) continue;
else if (parse_str(buf, "<os_version>", os_version)) continue;
else if (parse_str(buf, "<os_name>", os_name, sizeof(os_name))) continue;
else if (parse_str(buf, "<os_version>", os_version, sizeof(os_version))) continue;
else if (parse_double(buf, "<m_nbytes>", m_nbytes)) continue;
else if (parse_double(buf, "<m_cache>", m_cache)) continue;
else if (parse_double(buf, "<m_swap>", m_swap)) continue;
@ -322,62 +324,3 @@ int HOST::parse_net_stats(FILE* fin) {
}
return 1;
}
#if 0
DB_CACHE::DB_CACHE() {
}
int DB_CACHE::read_db() {
PLATFORM platform;
APP app;
APP_VERSION app_version;
while (!db_platform_enum(platform)) {
platforms.push_back(platform);
}
while (!db_app_enum(app)) {
apps.push_back(app);
}
while (!db_app_version_enum(app_version)) {
app_versions.push_back(app_version);
}
return 0;
}
PLATFORM* DB_CACHE::lookup_platform(char* name) {
unsigned int i;
assert(name!=NULL);
for (i=0; i<platforms.size(); i++) {
if (!strcmp(platforms[i].name, name)) {
return &platforms[i];
}
}
return 0;
}
APP* DB_CACHE::lookup_app(int id) {
unsigned int i;
for (i=0; i<apps.size(); i++) {
if (apps[i].id == id) {
return &apps[i];
}
}
return 0;
}
APP_VERSION* DB_CACHE::lookup_app_version(
int appid, int platformid, int version
) {
unsigned int i;
APP_VERSION* avp;
assert(version>=0);
for (i=0; i<app_versions.size(); i++) {
avp = &app_versions[i];
if (avp->appid == appid && avp->platformid == platformid && avp->version_num == version) {
return avp;
}
}
return 0;
}
#endif

View File

@ -44,6 +44,9 @@ struct SCHEDULER_REQUEST {
int parse(FILE*);
};
// NOTE: if any field requires initialization,
// you must do it in the constructor. Nothing is zeroed by default.
//
struct SCHEDULER_REPLY {
int request_delay; // don't request again until this time elapses
char message[1024];