From: Frederic Marchal Date: Wed, 18 Feb 2015 19:04:14 +0000 (+0100) Subject: Fix several possible sprintf buffer overflows X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e080560d3bcf29ce987863c880214344f2748f77;p=thirdparty%2Fsarg.git Fix several possible sprintf buffer overflows At least one of those sprintf was producing a segfault when a very long elapsed time was encountered. Thanks to Ricardo Fregati for reporting this bug and Marc Cesarine for solving it. Conflicts: log.c --- diff --git a/include/defs.h b/include/defs.h index 7bd43cb..630cdbd 100644 --- a/include/defs.h +++ b/include/defs.h @@ -256,8 +256,8 @@ int getnumlist(char *, numlist *, const int, const int); void name_month(char *month,int month_len); int conv_month(const char *month); const char *conv_month_name(int month); -void buildymd(const char *dia, const char *mes, const char *ano, char *wdata); -void date_from(char *date, int *dfrom, int *duntil); +void buildymd(const char *dia, const char *mes, const char *ano, char *wdata,int wdata_size); +void date_from(char *date,int date_size, int *dfrom, int *duntil); char *fixnum(long long int value, int n); char *fixnum2(long long int value, int n); void fixnone(char *str); diff --git a/index.c b/index.c index 7febbe7..c6f41c3 100644 --- a/index.c +++ b/index.c @@ -389,7 +389,7 @@ static void make_file_index(void) debuga(_("Invalid time in file \"%s%s/sarg-date\"\n"),outdir,direntp->d_name); exit(EXIT_FAILURE); } - buildymd(day,mon,year,ftime); + buildymd(day,mon,year,ftime,sizeof(ftime)); snprintf(item->creationdate,sizeof(item->creationdate),"%s%02d%02d%02d",ftime, ihour, iminute, isecond); } item->dirname=strdup(direntp->d_name); diff --git a/log.c b/log.c index c2b8d37..bd12275 100644 --- a/log.c +++ b/log.c @@ -404,7 +404,7 @@ int main(int argc,char *argv[]) break; case 'd': safe_strcpy(date,optarg,sizeof(date)); - date_from(date, &dfrom, &duntil); + date_from(date, sizeof(date), &dfrom, &duntil); break; case 'e': safe_strcpy(email,optarg,sizeof(email)); diff --git a/useragent.c b/useragent.c index 763cd7d..bb8f6a3 100644 --- a/useragent.c +++ b/useragent.c @@ -89,7 +89,7 @@ void useragent(void) debuga(_("Invalid date in file \"%s\"\n"),UserAgentLog); exit(EXIT_FAILURE); } - buildymd(day,month,year,wdate); + buildymd(day,month,year,wdate,sizeof(wdate)); ndate=atoi(wdate); if (ndateduntil) break; diff --git a/util.c b/util.c index 32adf30..b946c5d 100644 --- a/util.c +++ b/util.c @@ -410,12 +410,12 @@ int builddia(int day, int month, int year) } -void buildymd(const char *dia, const char *mes, const char *ano, char *wdata) +void buildymd(const char *dia, const char *mes, const char *ano, char *wdata,int wdata_size) { int nmes; nmes=month2num(mes); - sprintf(wdata,"%04d%02d%02d",atoi(ano),nmes+1,atoi(dia)); + snprintf(wdata,wdata_size,"%04d%02d%02d",atoi(ano),nmes+1,atoi(dia)); } @@ -670,18 +670,16 @@ char *fixnum2(long long int value, int n) char *buildtime(long long int elap) { - int num = elap / 1000; + long int num = elap / 1000LL; int hor = 0; int min = 0; int sec = 0; - static char buf[12]; + static char buf[20]; - buf[0]='\0'; - - hor=num / 3600; - min=(num % 3600) / 60; - sec=num % 60; - sprintf(buf,"%02d:%02d:%02d",hor,min,sec); + hor=num / 3600L; + min=(num % 3600L) / 60L; + sec=num % 60L; + snprintf(buf,sizeof(buf),"%02d:%02d:%02d",hor,min,sec); return(buf); } @@ -703,9 +701,15 @@ int obtdate(const char *dirname, const char *name, char *data) FILE *fp_in; char wdir[MAXLEN]; - sprintf(wdir,"%s%s/sarg-date",dirname,name); + if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-date",dirname,name)>=sizeof(wdir)) { + debuga(_("Buffer to small to store %s%s/sarg-date"),dirname,name); + exit(EXIT_FAILURE); + } if ((fp_in = fopen(wdir, "rt")) == 0) { - sprintf(wdir,"%s%s/date",dirname,name); + if (snprintf(wdir,sizeof(wdir),"%s%s/date",dirname,name)>=sizeof(wdir)) { + debuga(_("Buffer to small to store %s%s/date"),dirname,name); + exit(EXIT_FAILURE); + } if ((fp_in = fopen(wdir, "rt")) == 0) { data[0]='\0'; return(-1); @@ -762,9 +766,15 @@ int obtuser(const char *dirname, const char *name) char tuser[20]; int nuser; - sprintf(wdir,"%s%s/sarg-users",dirname,name); + if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-users",dirname,name)>=sizeof(wdir)) { + debuga(_("Buffer too small to store %s%s/sarg-users"),dirname,name); + exit(EXIT_FAILURE); + } if((fp_in=fopen(wdir,"r"))==NULL) { - sprintf(wdir,"%s%s/users",dirname,name); + if (snprintf(wdir,sizeof(wdir),"%s%s/users",dirname,name)>=sizeof(wdir)) { + debuga(_("Buffer too small to store %s%s/users"),dirname,name); + exit(EXIT_FAILURE); + } if((fp_in=fopen(wdir,"r"))==NULL) { return(0); } @@ -796,9 +806,15 @@ void obttotal(const char *dirname, const char *name, int nuser, long long int *t *tbytes=0; *media=0; - sprintf(wdir,"%s%s/sarg-general",dirname,name); + if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-general",dirname,name)>=sizeof(wdir)) { + debuga(_("Buffer too small to store %s%s/sarg-general"),dirname,name); + exit(EXIT_FAILURE); + } if ((fp_in = fopen(wdir, "r")) == 0) { - sprintf(wdir,"%s%s/general",dirname,name); + if (snprintf(wdir,sizeof(wdir),"%s%s/general",dirname,name)>=sizeof(wdir)) { + debuga(_("Buffer too small to store %s%s/general"),dirname,name); + exit(EXIT_FAILURE); + } if ((fp_in = fopen(wdir, "r")) == 0) { return; } @@ -1003,13 +1019,19 @@ static void copy_images(void) while ((direntp = readdir( dirp )) != NULL ){ if(direntp->d_name[0]=='.') continue; - sprintf(srcfile,"%s/%s",imgdir,direntp->d_name); + if (snprintf(srcfile,sizeof(srcfile),"%s/%s",imgdir,direntp->d_name)>=sizeof(srcfile)) { + debuga(_("Buffer too small to store %s/%s"),imgdir,direntp->d_name); + exit(EXIT_FAILURE); + } if (stat(srcfile,&info)) { debuga(_("Cannot stat \"%s\": %s\n"),srcfile,strerror(errno)); continue; } if (S_ISREG(info.st_mode)) { - sprintf(dstfile,"%s/%s",images,direntp->d_name); + if (snprintf(dstfile,sizeof(dstfile),"%s/%s",images,direntp->d_name)>=sizeof(dstfile)) { + debuga(_("Buffer too small to store %s/%s"),images,direntp->d_name); + exit(EXIT_FAILURE); + } img_in = fopen(srcfile, "rb"); if(img_in!=NULL) { img_ou = fopen(dstfile, "wb"); @@ -1151,7 +1173,10 @@ int vrfydir(const struct periodstruct *per1, const char *addr, const char *site, strcpy(dirname2,wdir); - sprintf(wdir,"%s/sarg-date",outdirname); + if (snprintf(wdir,sizeof(wdir),"%s/sarg-date",outdirname)>=sizeof(wdir)) { + debuga(_("Buffer too small to store %s/sarg-date"),outdirname); + exit(EXIT_FAILURE); + } if ((fp_ou = fopen(wdir, "wt")) == 0) { debuga(_("Cannot open file \"%s\": %s\n"),wdir,strerror(errno)); perror("SARG:"); @@ -1235,26 +1260,26 @@ void zdate(char *ftime,int ftimesize, const char *DateFormat) char *fixtime(long long int elap) { - int num = elap / 1000; + long int num = elap / 1000LL; int hor = 0; int min = 0; int sec = 0; - static char buf[12]; + static char buf[20]; - hor=num / 3600; - min=(num % 3600) / 60; - sec=num % 60; + hor=num / 3600L; + min=(num % 3600L) / 60L; + sec=num % 60L; if(hor==0 && min==0 && sec==0) strcpy(buf,"0"); else - sprintf(buf,"%d:%02d:%02d",hor,min,sec); + snprintf(buf,sizeof(buf),"%d:%02d:%02d",hor,min,sec); return buf; } -void date_from(char *date, int *dfrom, int *duntil) +void date_from(char *date,int date_size, int *dfrom, int *duntil) { int d0=0; int m0=0; @@ -1389,7 +1414,7 @@ void date_from(char *date, int *dfrom, int *duntil) *dfrom=y0*10000+m0*100+d0; *duntil=y1*10000+m1*100+d1; - sprintf(date,"%02d/%02d/%04d-%02d/%02d/%04d",d0,m0,y0,d1,m1,y1); + snprintf(date,date_size,"%02d/%02d/%04d-%02d/%02d/%04d",d0,m0,y0,d1,m1,y1); return; }