]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Fix several possible sprintf buffer overflows
authorFrederic Marchal <fmarchal@users.sourceforge.net>
Wed, 18 Feb 2015 19:04:14 +0000 (20:04 +0100)
committerFrederic Marchal <fmarchal@users.sourceforge.net>
Wed, 18 Feb 2015 19:04:14 +0000 (20:04 +0100)
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

include/defs.h
index.c
log.c
useragent.c
util.c

index 7bd43cbbfe0ff97b48a579121dad2e11c576f52a..630cdbd7f70b4813920152a0707d1f31048d3697 100644 (file)
@@ -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 7febbe70ffb23cd840b80ad41a61077f358ef472..c6f41c3ce3b8afd540fe98e182892417f0ccada2 100644 (file)
--- 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 c2b8d37bca780291fce4fc86875d99ffc0db897d..bd1227510e2e90aa0a609f36ee7eadb2a7d8ed27 100644 (file)
--- 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));
index 763cd7ddc82e032834bf9dda21f0d50d888939e4..bb8f6a336ed1d597239cf3344b353624fed1cd63 100644 (file)
@@ -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 (ndate<dfrom) continue;
                if (ndate>duntil) break;
diff --git a/util.c b/util.c
index 32adf30b643d6e031f68d61341b5363ff4f234d3..b946c5dee552433324c6608edd445a368feea0c3 100644 (file)
--- 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;
 }