diff --git a/include/errmsg.h b/include/errmsg.h index 04c7e5e0..7ca3238a 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -103,5 +103,5 @@ extern const char *mariadb_client_errors[]; /* Error messages */ #define CR_VERSION_MISMATCH 5008 /* Always last, if you add new error codes please update the value for CR_MARIADB_LAST_ERROR */ -#define CR_MARIADB_LAST_ERROR CR_INVALID_STMT +#define CR_MARIADB_LAST_ERROR CR_VERSION_MISMATCH #endif diff --git a/libmariadb/ma_dtoa.c b/libmariadb/ma_dtoa.c index cde097d0..1136bfee 100644 --- a/libmariadb/ma_dtoa.c +++ b/libmariadb/ma_dtoa.c @@ -1121,7 +1121,7 @@ static Bigint *d2b(U *d, int *e, int *bits, Stack_alloc *alloc) if ((k= lo0bits(&y))) { x[0]= y | z << (32 - k); - z>>= k; + z>>= (k == 32) ? (--k) : k; } else x[0]= y; @@ -1906,7 +1906,8 @@ trimzeros: s++; } ret: - Bfree(S, &alloc); + if (S != NULL) + Bfree(S, &alloc); if (mhi) { if (mlo && mlo != mhi) diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index e2ddb3fa..4cef6343 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -49,6 +49,7 @@ #include #include "mysql.h" #include /* ceil() */ +#include #ifdef WIN32 #include @@ -72,6 +73,8 @@ #define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL) #endif +#define MAX_DBL_STR 3 + DBL_MANT_DIG - DBL_MIN_EXP + #if defined(HAVE_LONG_LONG) && !defined(ULONGLONG_MAX) /* First check for ANSI C99 definition: */ #ifdef ULLONG_MAX @@ -254,19 +257,25 @@ static unsigned long long my_atoull(const char *str, const char *end_str, int *e double my_atod(const char *number, const char *end, int *error) { double val= 0.0; - char buffer[255]; + char buffer[MAX_DBL_STR + 1]; int len= (int)(end - number); - if (len > 254) - *error= 1; + *error= errno= 0; - len= MIN(len, 254); - memcpy(&buffer, number, len); + if (len > MAX_DBL_STR) + { + *error= 1; + len= MAX_DBL_STR; + } + + memcpy(buffer, number, len); buffer[len]= '\0'; val= strtod(buffer, NULL); -/* if (!*error) - *error= errno; */ + + if (errno) + *error= errno; + return val; } @@ -570,21 +579,26 @@ static void convert_froma_string(MYSQL_BIND *r_param, char *buffer, size_t len) case MYSQL_TYPE_NEWDECIMAL: default: { - char *start= buffer + r_param->offset; /* stmt_fetch_column sets offset */ - char *end= buffer + len; - size_t copylen= 0; - - if (start < end) + if (len > r_param->offset) { - copylen= end - start; - if (r_param->buffer_length) - memcpy(r_param->buffer, start, MIN(copylen, r_param->buffer_length)); - } - if (copylen < r_param->buffer_length) - ((char *)r_param->buffer)[copylen]= 0; - *r_param->error= (copylen > r_param->buffer_length); + char *start= buffer + r_param->offset; /* stmt_fetch_column sets offset */ + char *end= buffer + len; + size_t copylen= 0; - *r_param->length= (ulong)len; + if (start < end) + { + copylen= end - start; + if (r_param->buffer_length) + memcpy(r_param->buffer, start, MIN(copylen, r_param->buffer_length)); + } + if (copylen < r_param->buffer_length) + ((char *)r_param->buffer)[copylen]= 0; + *r_param->error= (copylen > r_param->buffer_length); + + } + else + *r_param->error= 1; + *r_param->length= (ulong)len; } break; } @@ -657,7 +671,7 @@ static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, lon if (display_width < r_param->buffer_length) { ma_bmove_upp(buffer + display_width, buffer + len, len); - /* coverity [bad_memset] */ + /* coverity[bad_memset] */ memset((void*) buffer, (int) '0', display_width - len); len= display_width; } @@ -880,7 +894,7 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1) break; ma_bmove_upp(buff + field->length, buff + length, length); - /* coverity [bad_memset] */ + /* coverity[bad_memset] */ memset((void*) buff, (int) '0', field->length - length); length= field->length; } @@ -1103,74 +1117,68 @@ void ps_fetch_datetime(MYSQL_BIND *r_param, const MYSQL_FIELD * field, unsigned int len= net_field_length(row); switch (r_param->buffer_type) { - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_TIMESTAMP: - convert_to_datetime(t, row, len, field->type); - break; - case MYSQL_TYPE_DATE: - convert_to_datetime(t, row, len, field->type); - break; - case MYSQL_TYPE_TIME: - convert_to_datetime(t, row, len, field->type); - t->year= t->day= t->month= 0; - break; - case MYSQL_TYPE_YEAR: - { - MYSQL_TIME tm; - convert_to_datetime(&tm, row, len, field->type); - shortstore(r_param->buffer, tm.year); - break; - } - default: - { - char dtbuffer[60]; - MYSQL_TIME tm; - size_t length; - convert_to_datetime(&tm, row, len, field->type); - /* - if (tm.time_type== MYSQL_TIMESTAMP_TIME && tm.day) - { - tm.hour+= tm.day * 24; - tm.day=0; - } -*/ - switch(field->type) { - case MYSQL_TYPE_DATE: - length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day); - break; - case MYSQL_TYPE_TIME: - length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second); - if (field->decimals && field->decimals <= 6) - { - char ms[8]; - sprintf(ms, ".%06lu", tm.second_part); - if (field->decimals < 6) - ms[field->decimals + 1]= 0; - length+= strlen(ms); - strcat(dtbuffer, ms); - } - break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: - length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); - if (field->decimals && field->decimals <= 6) - { - char ms[8]; - sprintf(ms, ".%06lu", tm.second_part); - if (field->decimals < 6) - ms[field->decimals + 1]= 0; - length+= strlen(ms); - strcat(dtbuffer, ms); - } + convert_to_datetime(t, row, len, field->type); + break; + case MYSQL_TYPE_DATE: + convert_to_datetime(t, row, len, field->type); + break; + case MYSQL_TYPE_TIME: + convert_to_datetime(t, row, len, field->type); + t->year= t->day= t->month= 0; + break; + case MYSQL_TYPE_YEAR: + { + MYSQL_TIME tm; + convert_to_datetime(&tm, row, len, field->type); + shortstore(r_param->buffer, tm.year); + break; + } + default: + { + char dtbuffer[60]; + MYSQL_TIME tm; + size_t length; + convert_to_datetime(&tm, row, len, field->type); + + switch(field->type) { + case MYSQL_TYPE_DATE: + length= sprintf(dtbuffer, "%04u-%02u-%02u", tm.year, tm.month, tm.day); + break; + case MYSQL_TYPE_TIME: + length= sprintf(dtbuffer, "%s%02u:%02u:%02u", (tm.neg ? "-" : ""), tm.hour, tm.minute, tm.second); + if (field->decimals && field->decimals <= 6) + { + char ms[8]; + sprintf(ms, ".%06lu", tm.second_part); + if (field->decimals < 6) + ms[field->decimals + 1]= 0; + length+= strlen(ms); + strcat(dtbuffer, ms); + } + break; + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: + length= sprintf(dtbuffer, "%04u-%02u-%02u %02u:%02u:%02u", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); + if (field->decimals && field->decimals <= 6) + { + char ms[8]; + sprintf(ms, ".%06lu", tm.second_part); + if (field->decimals < 6) + ms[field->decimals + 1]= 0; + length+= strlen(ms); + strcat(dtbuffer, ms); + } + break; + default: + dtbuffer[0]= 0; + length= 0; + break; + } + convert_froma_string(r_param, dtbuffer, length); break; - default: - dtbuffer[0]= 0; - length= 0; - break; } - convert_froma_string(r_param, dtbuffer, length); - break; - } } (*row) += len; } @@ -1353,3 +1361,4 @@ void mysql_init_ps_subsystem(void) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ + diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index d1677a84..73c7e946 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -85,6 +85,7 @@ extern ulong net_buffer_length; /* net.c */ static MYSQL_PARAMETERS mariadb_internal_parameters= {&max_allowed_packet, &net_buffer_length, 0}; static my_bool mysql_client_init=0; static void mysql_close_options(MYSQL *mysql); +static void ma_clear_session_state(MYSQL *mysql); extern void release_configuration_dirs(); extern char **get_default_configuration_dirs(); extern my_bool ma_init_done; @@ -1906,6 +1907,7 @@ static void mysql_close_options(MYSQL *mysql) static void mysql_close_memory(MYSQL *mysql) { + ma_clear_session_state(mysql); free(mysql->host_info); free(mysql->host); free(mysql->user); @@ -1925,11 +1927,23 @@ void my_set_error(MYSQL *mysql, { va_list ap; + const char *errmsg; + + if (!format) + { + if (error_nr >= CR_MIN_ERROR && error_nr <= CR_MYSQL_LAST_ERROR) + errmsg= ER(error_nr); + else if (error_nr >= CER_MIN_ERROR && error_nr <= CR_MARIADB_LAST_ERROR) + errmsg= CER(error_nr); + else + errmsg= ER(CR_UNKNOWN_ERROR); + } + mysql->net.last_errno= error_nr; ma_strmake(mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH); va_start(ap, format); - vsnprintf(mysql->net.last_error, MYSQL_ERRMSG_SIZE, - format ? format : ER(error_nr), ap); + vsnprintf(mysql->net.last_error, MYSQL_ERRMSG_SIZE - 1, + format ? format : errmsg, ap); va_end(ap); return; } @@ -1947,7 +1961,7 @@ void mysql_close_slow_part(MYSQL *mysql) } } -void ma_clear_session_state(MYSQL *mysql) +static void ma_clear_session_state(MYSQL *mysql) { uint i; @@ -1956,7 +1970,6 @@ void ma_clear_session_state(MYSQL *mysql) for (i= SESSION_TRACK_BEGIN; i <= SESSION_TRACK_END; i++) { - /* we acquired memory via ma_multi_alloc, so we don't need to free data */ list_free(mysql->extension->session_state[i].list, 0); } memset(mysql->extension->session_state, 0, sizeof(struct st_mariadb_session_state) * SESSION_TRACK_TYPES); @@ -2080,12 +2093,13 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length) if (si_type != SESSION_TRACK_STATE_CHANGE) net_field_length(&pos); /* ignore total length, item length will follow next */ plen= net_field_length(&pos); - if (!ma_multi_malloc(0, + if (!(session_item= ma_multi_malloc(0, &session_item, sizeof(LIST), &str, sizeof(MYSQL_LEX_STRING), &data, plen, - NULL)) + NULL))) { + ma_clear_session_state(mysql); SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); return -1; } @@ -2111,12 +2125,13 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length) if (!strncmp(str->str, "character_set_client", str->length)) set_charset= 1; plen= net_field_length(&pos); - if (!ma_multi_malloc(0, + if (!(session_item= ma_multi_malloc(0, &session_item, sizeof(LIST), &str, sizeof(MYSQL_LEX_STRING), &data, plen, - NULL)) + NULL))) { + ma_clear_session_state(mysql); SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); return -1; } @@ -2172,7 +2187,7 @@ int mthd_my_read_query_result(MYSQL *mysql) if (mysql->options.extension && mysql->extension->auto_local_infile == ACCEPT_FILE_REQUEST) mysql->extension->auto_local_infile= WAIT_FOR_QUERY; - if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error) + if ((length = ma_net_safe_read(mysql)) == packet_error) { return(1); } diff --git a/libmariadb/mariadb_rpl.c b/libmariadb/mariadb_rpl.c index de7a72b8..ab87a884 100644 --- a/libmariadb/mariadb_rpl.c +++ b/libmariadb/mariadb_rpl.c @@ -387,12 +387,14 @@ MARIADB_RPL_EVENT * STDCALL mariadb_rpl_fetch(MARIADB_RPL *rpl, MARIADB_RPL_EVEN } break; default: + free(rpl_event); return NULL; break; } return rpl_event; } mem_error: + free(rpl_event); SET_CLIENT_ERROR(rpl->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); return 0; } @@ -458,6 +460,7 @@ int STDCALL mariadb_rpl_optionsv(MARIADB_RPL *rpl, goto end; } end: + va_end(ap); return rc; } @@ -501,8 +504,10 @@ int STDCALL mariadb_rpl_get_optionsv(MARIADB_RPL *rpl, break; } default: + va_end(ap); return 1; break; } + va_end(ap); return 0; } diff --git a/plugins/auth/caching_sha2_pw.c b/plugins/auth/caching_sha2_pw.c index b42f0d70..3b3d866c 100644 --- a/plugins/auth/caching_sha2_pw.c +++ b/plugins/auth/caching_sha2_pw.c @@ -212,13 +212,15 @@ static char *load_pub_key_file(const char *filename, int *pub_key_size) if (fseek(fp, 0, SEEK_END)) goto end; - *pub_key_size= ftell(fp); + if ((*pub_key_size= ftell(fp)) < 0) + goto end; + rewind(fp); if (!(buffer= malloc(*pub_key_size + 1))) goto end; - if (!fread(buffer, *pub_key_size, 1, fp)) + if (fread(buffer, *pub_key_size, 1, fp) != (size_t)*pub_key_size) goto end; error= 0; diff --git a/plugins/auth/my_auth.c b/plugins/auth/my_auth.c index 5154e6d3..f9a21e02 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -118,7 +118,7 @@ static int dummy_fallback_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql __attr unsigned int i, last_errno= ((MCPVIO_EXT *)vio)->mysql->net.last_errno; if (last_errno) strncpy(last_error, ((MCPVIO_EXT *)vio)->mysql->net.last_error, - sizeof(last_error)); + sizeof(last_error) - 1); /* safety-wise we only do 10 round-trips */ for (i=0; i < 10; i++) @@ -131,7 +131,7 @@ static int dummy_fallback_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql __attr } if (last_errno) strncpy(((MCPVIO_EXT *)vio)->mysql->net.last_error, last_error, - sizeof(((MCPVIO_EXT *)vio)->mysql->net.last_error)); + sizeof(((MCPVIO_EXT *)vio)->mysql->net.last_error) - 1); return CR_ERROR; } diff --git a/plugins/auth/old_password.c b/plugins/auth/old_password.c index 6cc47074..07756e92 100644 --- a/plugins/auth/old_password.c +++ b/plugins/auth/old_password.c @@ -83,7 +83,6 @@ static int auth_old_password(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) we use the old scramble. */ pkt= (uchar*)mysql->scramble_buff; - pkt_len= SCRAMBLE_LENGTH_323 + 1; } else { diff --git a/plugins/auth/ref10/pow22523.h b/plugins/auth/ref10/pow22523.h index 60ffe0d3..d476ed14 100644 --- a/plugins/auth/ref10/pow22523.h +++ b/plugins/auth/ref10/pow22523.h @@ -50,7 +50,11 @@ /* qhasm: z2 = z1^2^1 */ /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ -fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); +fe_sq(t0,z); + +/* covscan CWE-561 dead code: variable i can't be < 1 +for (i = 1;i < 1;++i) fe_sq(t0,t0); +*/ /* qhasm: z8 = z2^2^2 */ /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ @@ -70,7 +74,11 @@ fe_mul(t0,t0,t1); /* qhasm: z22 = z11^2^1 */ /* asm 1: fe_sq(>z22=fe#1,z22=fe#1,>z22=fe#1); */ /* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ -fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0); +fe_sq(t0,t0); + +/* covscan CWE-561 dead code: variable i can't be < 1 +for (i = 1;i < 1;++i) fe_sq(t0,t0); +*/ /* qhasm: z_5_0 = z9*z22 */ /* asm 1: fe_mul(>z_5_0=fe#1,z2=fe#1,z2=fe#1,>z2=fe#1); */ /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ -fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); +fe_sq(t0,z); +/* covscan CWE-561 dead code: variable i can't be < 1 +for (i = 1;i < 1;++i) fe_sq(t0,t0); +*/ /* qhasm: z8 = z2^2^2 */ /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ @@ -70,7 +73,10 @@ fe_mul(t0,t0,t1); /* qhasm: z22 = z11^2^1 */ /* asm 1: fe_sq(>z22=fe#3,z22=fe#3,>z22=fe#3); */ /* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */ -fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2); +fe_sq(t2,t0); +/* covscan CWE-561 dead code: variable i can't be < 1 +for (i = 1;i < 1;++i) fe_sq(t2,t2); +*/ /* qhasm: z_5_0 = z9*z22 */ /* asm 1: fe_mul(>z_5_0=fe#2,curl = curl_easy_init(); - curl_easy_setopt(rf->curl, CURLOPT_URL, url); - curl_easy_setopt(rf->curl, CURLOPT_WRITEDATA, file); - curl_easy_setopt(rf->curl, CURLOPT_VERBOSE, 0L); - curl_easy_setopt(rf->curl, CURLOPT_WRITEFUNCTION, rio_write_callback); + if (curl_easy_setopt(rf->curl, CURLOPT_URL, url) || + curl_easy_setopt(rf->curl, CURLOPT_WRITEDATA, file) || + curl_easy_setopt(rf->curl, CURLOPT_VERBOSE, 0L) || + curl_easy_setopt(rf->curl, CURLOPT_WRITEFUNCTION, rio_write_callback)) + { + free(file); + free(rf); + return NULL; + } curl_multi_add_handle(multi_handle, rf->curl); diff --git a/plugins/pvio/pvio_socket.c b/plugins/pvio/pvio_socket.c index 934a236c..8106b348 100644 --- a/plugins/pvio/pvio_socket.c +++ b/plugins/pvio/pvio_socket.c @@ -786,7 +786,13 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) else #endif { - strcpy(UNIXaddr.sun_path, cinfo->unix_socket); + size_t sun_path_size = sizeof(UNIXaddr.sun_path); + strncpy(UNIXaddr.sun_path, cinfo->unix_socket, sun_path_size - 1); + if (sun_path_size == strlen(UNIXaddr.sun_path) + 1 && UNIXaddr.sun_path[sun_path_size - 1] != '\0') + { + /* Making the string null-terminated */ + UNIXaddr.sun_path[sun_path_size - 1] = '\0'; + } port_length= sizeof(UNIXaddr); } if (pvio_socket_connect_sync_or_async(pvio, (struct sockaddr *) &UNIXaddr, port_length)) diff --git a/unittest/libmariadb/charset.c b/unittest/libmariadb/charset.c index 2463ba4e..969991e0 100644 --- a/unittest/libmariadb/charset.c +++ b/unittest/libmariadb/charset.c @@ -487,7 +487,6 @@ static int bug30472_retrieve_charset_info(MYSQL *con, row= mysql_fetch_row(rs); FAIL_IF(!row, "Couldn't fetch row"); strcpy(character_set_client, row[1]); - diag("cs: %s", row[1]); mysql_free_result(rs); rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"); diff --git a/unittest/libmariadb/ps.c b/unittest/libmariadb/ps.c index 8acc4489..a0e04057 100644 --- a/unittest/libmariadb/ps.c +++ b/unittest/libmariadb/ps.c @@ -2191,7 +2191,7 @@ static int test_bind_negative(MYSQL *mysql) rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); check_mysql_rc(rc, mysql); - rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)"); + rc= mysql_query(mysql, "create temporary table t1 (c1 int)"); check_mysql_rc(rc, mysql); rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)"); diff --git a/zlib/uncompr.c b/zlib/uncompr.c index ad98be3a..59798be5 100644 --- a/zlib/uncompr.c +++ b/zlib/uncompr.c @@ -27,7 +27,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen) const Bytef *source; uLong sourceLen; { - z_stream stream; + z_stream stream= {0}; int err; stream.next_in = (Bytef*)source;