Skip to content

Commit 0dbd5a8

Browse files
Bug#21973610: BUFFER OVERFLOW ISSUES
Description : Incorrect usage of sprintf/strcpy caused possible buffer overflow issues at various places. Solution : - Fixed mysql_plugin and mysqlshow - Fixed regex library issues Reviewed-By : Georgi Kodinov <[email protected]> Reviewed-By : Venkata S Murthy Sidagam <[email protected]>
1 parent fd98314 commit 0dbd5a8

File tree

4 files changed

+42
-24
lines changed

4 files changed

+42
-24
lines changed

client/mysql_plugin.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -406,7 +406,7 @@ static int get_default_values()
406406
static void usage(void)
407407
{
408408
PRINT_VERSION;
409-
puts("Copyright (c) 2011, Oracle and/or its affiliates. "
409+
puts("Copyright (c) 2011, 2015, Oracle and/or its affiliates. "
410410
"All rights reserved.\n");
411411
puts("Enable or disable plugins.");
412412
printf("\nUsage: %s [options] <plugin> ENABLE|DISABLE\n\nOptions:\n",
@@ -757,6 +757,11 @@ static int check_options(int argc, char **argv, char *operation)
757757
/* read the plugin config file and check for match against argument */
758758
else
759759
{
760+
if (strlen(argv[i]) + 4 + 1 > FN_REFLEN)
761+
{
762+
fprintf(stderr, "ERROR: argument is too long.\n");
763+
return 1;
764+
}
760765
strcpy(plugin_name, argv[i]);
761766
strcpy(config_file, argv[i]);
762767
strcat(config_file, ".ini");
@@ -848,6 +853,7 @@ static int process_options(int argc, char *argv[], char *operation)
848853
if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2)
849854
{
850855
char buff[FN_REFLEN];
856+
memset(buff, 0, sizeof(buff));
851857

852858
strncpy(buff, opt_basedir, sizeof(buff) - 1);
853859
#ifdef __WIN__

client/mysqlshow.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ list_dbs(MYSQL *mysql,const char *wild)
377377
uint length, counter = 0;
378378
ulong rowcount = 0L;
379379
char tables[NAME_LEN+1], rows[NAME_LEN+1];
380-
char query[255];
380+
char query[NAME_LEN + 100];
381381
MYSQL_FIELD *field;
382382
MYSQL_RES *result;
383383
MYSQL_ROW row= NULL, rrow;
@@ -444,7 +444,8 @@ list_dbs(MYSQL *mysql,const char *wild)
444444
MYSQL_ROW trow;
445445
while ((trow = mysql_fetch_row(tresult)))
446446
{
447-
sprintf(query,"SELECT COUNT(*) FROM `%s`",trow[0]);
447+
my_snprintf(query, sizeof(query),
448+
"SELECT COUNT(*) FROM `%s`", trow[0]);
448449
if (!(mysql_query(mysql,query)))
449450
{
450451
MYSQL_RES *rresult;
@@ -500,7 +501,7 @@ list_tables(MYSQL *mysql,const char *db,const char *table)
500501
{
501502
const char *header;
502503
uint head_length, counter = 0;
503-
char query[255], rows[NAME_LEN], fields[16];
504+
char query[NAME_LEN + 100], rows[NAME_LEN], fields[16];
504505
MYSQL_FIELD *field;
505506
MYSQL_RES *result;
506507
MYSQL_ROW row, rrow;
@@ -585,7 +586,8 @@ list_tables(MYSQL *mysql,const char *db,const char *table)
585586
if (opt_verbose > 1)
586587
{
587588
/* Print the count of rows for each table */
588-
sprintf(query,"SELECT COUNT(*) FROM `%s`",row[0]);
589+
my_snprintf(query, sizeof(query), "SELECT COUNT(*) FROM `%s`",
590+
row[0]);
589591
if (!(mysql_query(mysql,query)))
590592
{
591593
if ((rresult = mysql_store_result(mysql)))
@@ -645,13 +647,15 @@ list_tables(MYSQL *mysql,const char *db,const char *table)
645647
static int
646648
list_table_status(MYSQL *mysql,const char *db,const char *wild)
647649
{
648-
char query[1024],*end;
650+
char query[NAME_LEN + 100];
651+
int len;
649652
MYSQL_RES *result;
650653
MYSQL_ROW row;
651654

652-
end=strxmov(query,"show table status from `",db,"`",NullS);
653-
if (wild && wild[0])
654-
strxmov(end," like '",wild,"'",NullS);
655+
len= sizeof(query);
656+
len-= my_snprintf(query, len, "show table status from `%s`", db);
657+
if (wild && wild[0] && len)
658+
strxnmov(query + strlen(query), len, " like '", wild, "'", NullS);
655659
if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
656660
{
657661
fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n",
@@ -683,7 +687,8 @@ static int
683687
list_fields(MYSQL *mysql,const char *db,const char *table,
684688
const char *wild)
685689
{
686-
char query[1024],*end;
690+
char query[NAME_LEN + 100];
691+
int len;
687692
MYSQL_RES *result;
688693
MYSQL_ROW row;
689694
ulong UNINIT_VAR(rows);
@@ -697,7 +702,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table,
697702

698703
if (opt_count)
699704
{
700-
sprintf(query,"select count(*) from `%s`", table);
705+
my_snprintf(query, sizeof(query), "select count(*) from `%s`", table);
701706
if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
702707
{
703708
fprintf(stderr,"%s: Cannot get record count for db: %s, table: %s: %s\n",
@@ -709,9 +714,11 @@ list_fields(MYSQL *mysql,const char *db,const char *table,
709714
mysql_free_result(result);
710715
}
711716

712-
end=strmov(strmov(strmov(query,"show /*!32332 FULL */ columns from `"),table),"`");
713-
if (wild && wild[0])
714-
strxmov(end," like '",wild,"'",NullS);
717+
len= sizeof(query);
718+
len-= my_snprintf(query, len, "show /*!32332 FULL */ columns from `%s`",
719+
table);
720+
if (wild && wild[0] && len)
721+
strxnmov(query + strlen(query), len, " like '", wild, "'", NullS);
715722
if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
716723
{
717724
fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n",
@@ -732,7 +739,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table,
732739
print_res_top(result);
733740
if (opt_show_keys)
734741
{
735-
end=strmov(strmov(strmov(query,"show keys from `"),table),"`");
742+
my_snprintf(query, sizeof(query), "show keys from `%s`", table);
736743
if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
737744
{
738745
fprintf(stderr,"%s: Cannot list keys in db: %s, table: %s: %s\n",

libmysql/conf_to_src.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -118,7 +118,7 @@ print_arrays_for(char *set)
118118
{
119119
FILE *f;
120120

121-
sprintf(buf, "%s.conf", set);
121+
snprintf(buf, sizeof(buf), "%s.conf", set);
122122

123123
if ((f = fopen(buf, "r")) == NULL) {
124124
fprintf(stderr, "%s: can't read conf file for charset %s\n", prog, set);

regex/main.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,8 @@ char *should;
425425
(sub.rm_so != -1 && sub.rm_eo == -1) ||
426426
(sub.rm_so != -1 && sub.rm_so < 0) ||
427427
(sub.rm_eo != -1 && sub.rm_eo < 0) ) {
428-
sprintf(grump, "start %ld end %ld", (long)sub.rm_so,
428+
snprintf(grump, sizeof(grump),
429+
"start %ld end %ld", (long)sub.rm_so,
429430
(long)sub.rm_eo);
430431
return(grump);
431432
}
@@ -438,7 +439,8 @@ char *should;
438439

439440
/* check for in range */
440441
if ((int) sub.rm_eo > (int) strlen(str)) {
441-
sprintf(grump, "start %ld end %ld, past end of string",
442+
snprintf(grump, sizeof(grump),
443+
"start %ld end %ld, past end of string",
442444
(long)sub.rm_so, (long)sub.rm_eo);
443445
return(grump);
444446
}
@@ -449,13 +451,15 @@ char *should;
449451

450452
/* check for not supposed to match */
451453
if (should == NULL) {
452-
sprintf(grump, "matched `%.*s'", len, p);
454+
snprintf(grump, sizeof(grump),
455+
"matched `%.*s'", len, p);
453456
return(grump);
454457
}
455458

456459
/* check for wrong match */
457460
if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
458-
sprintf(grump, "matched `%.*s' instead", len, p);
461+
snprintf(grump, sizeof(grump),
462+
"matched `%.*s' instead", len, p);
459463
return(grump);
460464
}
461465
if (shlen > 0)
@@ -468,7 +472,8 @@ char *should;
468472
if (shlen == 0)
469473
shlen = 1; /* force check for end-of-string */
470474
if (strncmp(p, at, shlen) != 0) {
471-
sprintf(grump, "matched null at `%.20s'", p);
475+
snprintf(grump, sizeof(grump),
476+
"matched null at `%.20s'", p);
472477
return(grump);
473478
}
474479
return(NULL);
@@ -501,7 +506,7 @@ char *name;
501506
static char efbuf[100];
502507
my_regex_t re;
503508

504-
sprintf(efbuf, "REG_%s", name);
509+
snprintf(efbuf, sizeof(efbuf), "REG_%s", name);
505510
assert(strlen(efbuf) < sizeof(efbuf));
506511
re.re_endp = efbuf;
507512
(void) my_regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));

0 commit comments

Comments
 (0)