]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Fix several possible sprintf buffer overflows
authorFrederic Marchal <fmarchal@users.sourceforge.net>
Tue, 23 Jul 2013 11:02:13 +0000 (13:02 +0200)
committerFrederic Marchal <fmarchal@users.sourceforge.net>
Tue, 23 Jul 2013 11:02:13 +0000 (13:02 +0200)
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.

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

index f7234838b26b88429010e2d9c3279bab57192bf0..b59859d3b6c8bf936d20fbae2469cc572b476d1d 100755 (executable)
@@ -347,8 +347,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 86a2a7a6b898eb7b3990bc0ee5e986fd688d0ff3..64d9f646345efdbe1c0f87cbb35d1cc56b0ed504 100644 (file)
--- a/index.c
+++ b/index.c
@@ -395,7 +395,7 @@ static void make_file_index(void)
                                debuga(_("Maybe you have a broken time in your %s%s/sarg-date file\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 46e8cae710785a1c9b5ed632c1b2fc3efaa603b3..e70ff82f475c3e9ca3a57563b9bf8cedae024f0c 100644 (file)
--- a/log.c
+++ b/log.c
@@ -300,7 +300,7 @@ int main(int argc,char *argv[])
                                break;
                        case 'd':
                                safe_strcpy(ReadFilter.DateRange,optarg,sizeof(ReadFilter.DateRange));
-                               date_from(ReadFilter.DateRange, &dfrom, &duntil);
+                               date_from(ReadFilter.DateRange,sizeof(ReadFilter.DateRange), &dfrom, &duntil);
                                break;
                        case 'e':
                                safe_strcpy(email,optarg,sizeof(email));
index 4ada2e81baaecd2bd32089e1c3bd8583d48358ad..77a9acfdbd8f707d47e69443a4abad5a1f30e3ff 100644 (file)
@@ -89,7 +89,7 @@ void useragent(void)
                        debuga(_("Maybe you have a broken date in your %s file\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 895337fe9f2081cae53d453ff54ea43ab2c09292..0aff2c61564affd2fc05719aeda559c8510d3794 100644 (file)
--- a/util.c
+++ b/util.c
@@ -498,12 +498,12 @@ int compare_date(struct tm *date1,struct tm *date2)
        return(0);
 }
 
-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));
 }
 
 
@@ -723,18 +723,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);
 }
@@ -756,9 +754,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);
@@ -813,9 +817,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);
                }
@@ -845,9 +855,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;
                }
@@ -1068,13 +1084,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");
@@ -1219,7 +1241,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 %s for writing: %s\n"),wdir,strerror(errno));
                perror("SARG:");
@@ -1302,26 +1327,26 @@ void zdate(char *ftime,int ftimesize, 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;
@@ -1456,7 +1481,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;
 }