Changeset: 8eaa6c17e70c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8eaa6c17e70c Modified Files: monetdb5/modules/mal/clients.c Branch: Nov2019 Log Message:
Don't use global buffer, it's vulnerable to race conditions diffs (153 lines): diff --git a/monetdb5/modules/mal/clients.c b/monetdb5/modules/mal/clients.c --- a/monetdb5/modules/mal/clients.c +++ b/monetdb5/modules/mal/clients.c @@ -86,42 +86,39 @@ CLTsetScenario(Client cntxt, MalBlkPtr m return msg; } -static char * -local_itoa(int i) +static char* +CLTtimeConvert(time_t l, char *s, size_t len) { - static char buf[32]; - - sprintf(buf, "%d", i); - return buf; -} + char *converted = NULL; + struct tm localt; -static void -CLTtimeConvert(time_t l, char *s){ - struct tm localt; - + (void) len; #ifdef HAVE_LOCALTIME_R - (void) localtime_r(&l, &localt); + (void) localtime_r(&l, &localt); #else - /* race condition: return value could be - * overwritten in parallel thread before - * assignment complete */ - localt = *localtime(&l); + /* race condition: return value could be + * overwritten in parallel thread before + * assignment complete */ + localt = *localtime(&l); #endif #ifdef HAVE_ASCTIME_R3 - asctime_r(&localt, s, 26); + converted = asctime_r(&localt, s, 26); #else #ifdef HAVE_ASCTIME_R - asctime_r(&localt, s); + converted = asctime_r(&localt, s); #else - /* race condition: return value could be - * overwritten in parallel thread before copy - * complete, however on Windows, asctime is - * thread-safe */ - strncpy(s, asctime(&localt), 26); + /* race condition: return value could be + * overwritten in parallel thread before copy + * complete, however on Windows, asctime is + * thread-safe */ + converted = asctime(&localt); + if (!converted || strlen(converted) > (len - 1)) + return NULL; + strcpy(s, converted); #endif #endif - s[24] = 0; + return converted; } str @@ -131,7 +128,7 @@ CLTInfo(Client cntxt, MalBlkPtr mb, MalS bat *ret2= getArgReference_bat(stk,pci,0); BAT *b = COLnew(0, TYPE_str, 12, TRANSIENT); BAT *bn = COLnew(0, TYPE_str, 12, TRANSIENT); - char s[26]; + char buf[32]; /* 32 bytes are enough */ (void) mb; if (b == 0 || bn == 0){ @@ -140,29 +137,36 @@ CLTInfo(Client cntxt, MalBlkPtr mb, MalS throw(MAL, "clients.info", SQLSTATE(HY001) MAL_MALLOC_FAIL); } + (void) sprintf(buf, ""LLFMT"", (lng) cntxt->user); if (BUNappend(b, "user", false) != GDK_SUCCEED || - BUNappend(bn, local_itoa((int)cntxt->user), false) != GDK_SUCCEED || - - BUNappend(b, "scenario", false) != GDK_SUCCEED || - BUNappend(bn, cntxt->scenario, false) != GDK_SUCCEED || + BUNappend(bn, buf, false) != GDK_SUCCEED) + goto bailout; - BUNappend(b, "listing", false) != GDK_SUCCEED || - BUNappend(bn, local_itoa(cntxt->listing), false) != GDK_SUCCEED || - - BUNappend(b, "debug", false) != GDK_SUCCEED || - BUNappend(bn, local_itoa(cntxt->debug), false) != GDK_SUCCEED) + if (BUNappend(b, "scenario", false) != GDK_SUCCEED || + BUNappend(bn, cntxt->scenario, false) != GDK_SUCCEED) goto bailout; - CLTtimeConvert(cntxt->login, s); + (void) sprintf(buf, "%d", cntxt->listing); + if (BUNappend(b, "listing", false) != GDK_SUCCEED || + BUNappend(bn, buf, false) != GDK_SUCCEED) + goto bailout; + + (void) sprintf(buf, "%d", cntxt->debug); + if (BUNappend(b, "debug", false) != GDK_SUCCEED || + BUNappend(bn, buf, false) != GDK_SUCCEED) + goto bailout; + + if (!CLTtimeConvert(cntxt->login, buf, sizeof(buf))) + goto bailout; if (BUNappend(b, "login", false) != GDK_SUCCEED || - BUNappend(bn, s, false) != GDK_SUCCEED) + BUNappend(bn, buf, false) != GDK_SUCCEED) goto bailout; if (pseudo(ret,b,"client","info")) goto bailout; BBPkeepref(*ret2= bn->batCacheid); return MAL_SUCCEED; - bailout: +bailout: BBPunfix(b->batCacheid); BBPunfix(bn->batCacheid); throw(MAL, "clients.info", SQLSTATE(HY001) MAL_MALLOC_FAIL); @@ -174,7 +178,7 @@ CLTLogin(bat *nme, bat *ret) BAT *b = COLnew(0, TYPE_str, 12, TRANSIENT); BAT *u = COLnew(0, TYPE_oid, 12, TRANSIENT); int i; - char s[26]; + char s[32]; if (b == 0 || u == 0) goto bailout; @@ -182,7 +186,8 @@ CLTLogin(bat *nme, bat *ret) for (i = 0; i < MAL_MAXCLIENTS; i++) { Client c = mal_clients+i; if (c->mode >= RUNCLIENT && !is_oid_nil(c->user)) { - CLTtimeConvert(c->login, s); + if (!CLTtimeConvert(c->login, s, sizeof(s))) + goto bailout; if (BUNappend(b, s, false) != GDK_SUCCEED || BUNappend(u, &c->user, false) != GDK_SUCCEED) goto bailout; @@ -193,7 +198,7 @@ CLTLogin(bat *nme, bat *ret) goto bailout; return MAL_SUCCEED; - bailout: +bailout: BBPreclaim(b); BBPreclaim(u); throw(MAL, "clients.getLogins", SQLSTATE(HY001) MAL_MALLOC_FAIL); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list