Browse code

make the parser more sensitive to syntax errors (bb#238)

git-svn: trunk@3561

Tomasz Kojm authored on 2008/01/31 05:04:02
Showing 10 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Jan 30 20:45:38 CET 2008 (tk)
2
+---------------------------------
3
+  * libclamav/readdb.c: make the parser more sensitive to syntax errors (bb#238)
4
+
1 5
 Wed Jan 30 20:23:20 EET 2008 (edwin)
2 6
 ------------------------------------
3 7
   * libclamav/phishcheck.c, regex_list.c: when domain matchers, preserve full
... ...
@@ -46,6 +46,8 @@
46 46
 #include "shared/output.h"
47 47
 #include "shared/options.h"
48 48
 
49
+#include "libclamav/str.h"
50
+
49 51
 void help(void);
50 52
 
51 53
 #if defined(C_WINDOWS) && defined(CL_DEBUG)
... ...
@@ -147,7 +149,7 @@ int main(int argc, char **argv)
147 147
     if(opt_check(opt, "max-space")) {
148 148
 	pt = opt_arg(opt, "max-space");
149 149
 	if(!strchr(pt, 'M') && !strchr(pt, 'm')) {
150
-	    if(!isnumb(pt)) {
150
+	    if(!cli_isnumber(pt)) {
151 151
 		logg("!--max-space requires a natural number\n");
152 152
 		opt_free(opt);
153 153
 		return 40;
... ...
@@ -156,7 +158,7 @@ int main(int argc, char **argv)
156 156
     }
157 157
 
158 158
     if(opt_check(opt, "max-files")) {
159
-	if(!isnumb(opt_arg(opt, "max-files"))) {
159
+	if(!cli_isnumber(opt_arg(opt, "max-files"))) {
160 160
 	    logg("!--max-files requires a natural number\n");
161 161
 	    opt_free(opt);
162 162
 	    return 40;
... ...
@@ -164,7 +166,7 @@ int main(int argc, char **argv)
164 164
     }
165 165
 
166 166
     if(opt_check(opt, "max-recursion")) {
167
-	if(!isnumb(opt_arg(opt, "max-recursion"))) {
167
+	if(!cli_isnumber(opt_arg(opt, "max-recursion"))) {
168 168
 	    logg("!--max-recursion requires a natural number\n");
169 169
 	    opt_free(opt);
170 170
 	    return 40;
... ...
@@ -172,7 +174,7 @@ int main(int argc, char **argv)
172 172
     }
173 173
 
174 174
     if(opt_check(opt, "max-mail-recursion")) {
175
-	if(!isnumb(opt_arg(opt, "max-mail-recursion"))) {
175
+	if(!cli_isnumber(opt_arg(opt, "max-mail-recursion"))) {
176 176
 	    logg("!--max-mail-recursion requires a natural number\n");
177 177
 	    opt_free(opt);
178 178
 	    return 40;
... ...
@@ -180,7 +182,7 @@ int main(int argc, char **argv)
180 180
     }
181 181
 
182 182
     if(opt_check(opt, "max-dir-recursion")) {
183
-	if(!isnumb(opt_arg(opt, "max-dir-recursion"))) {
183
+	if(!cli_isnumber(opt_arg(opt, "max-dir-recursion"))) {
184 184
 	    logg("!--max-dir-recursion requires a natural number\n");
185 185
 	    opt_free(opt);
186 186
 	    return 40;
... ...
@@ -188,7 +190,7 @@ int main(int argc, char **argv)
188 188
     }
189 189
 
190 190
     if(opt_check(opt, "max-ratio")) {
191
-	if(!isnumb(opt_arg(opt, "max-ratio"))) {
191
+	if(!cli_isnumber(opt_arg(opt, "max-ratio"))) {
192 192
 	    logg("!--max-ratio requires a natural number\n");
193 193
 	    opt_free(opt);
194 194
 	    return 40;
... ...
@@ -969,7 +969,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
969 969
 	}
970 970
 
971 971
 	if(field && (pt = cli_strtok(dnsreply, field, ":"))) {
972
-	    if(!isnumb(pt)) {
972
+	    if(!cli_isnumber(pt)) {
973 973
 		logg("^Broken database version in TXT record.\n");
974 974
 	    } else {
975 975
 		newver = atoi(pt);
... ...
@@ -34,6 +34,7 @@ CLAMAV_PRIVATE {
34 34
     cli_regfree;
35 35
     cli_strrcpy;
36 36
     cli_strbcasestr;
37
+    cli_isnumber;
37 38
     cli_gentemp;
38 39
     cli_gentempfd;
39 40
     cli_rmdirs;
... ...
@@ -149,13 +149,13 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
149 149
 	    }
150 150
 
151 151
 	    if(!strchr(pt, '-')) {
152
-		if((mindist = maxdist = atoi(pt)) < 0) {
152
+		if(!cli_isnumber(pt) || (mindist = maxdist = atoi(pt)) < 0) {
153 153
 		    error = 1;
154 154
 		    break;
155 155
 		}
156 156
 	    } else {
157 157
 		if((n = cli_strtok(pt, 0, "-"))) {
158
-		    if((mindist = atoi(n)) < 0) {
158
+		    if(!cli_isnumber(n) || (mindist = atoi(n)) < 0) {
159 159
 			error = 1;
160 160
 			free(n);
161 161
 			break;
... ...
@@ -164,13 +164,18 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
164 164
 		}
165 165
 
166 166
 		if((n = cli_strtok(pt, 1, "-"))) {
167
-		    if((maxdist = atoi(n)) < 0) {
167
+		    if(!cli_isnumber(n) || (maxdist = atoi(n)) < 0) {
168 168
 			error = 1;
169 169
 			free(n);
170 170
 			break;
171 171
 		    }
172 172
 		    free(n);
173 173
 		}
174
+
175
+		if((n = cli_strtok(pt, 2, "-"))) { /* strict check */
176
+		    error = 1;
177
+		    free(n);
178
+		}
174 179
 	    }
175 180
 	}
176 181
 
... ...
@@ -406,7 +411,6 @@ static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
406 406
 	if(*pt == '=') continue;
407 407
 
408 408
 	if((ret = cli_parse_add(root, start, pt, 0, NULL, 0))) {
409
-	    cli_errmsg("Problem parsing signature at line %d\n", line);
410 409
 	    ret = CL_EMALFDB;
411 410
 	    break;
412 411
 	}
... ...
@@ -586,7 +590,6 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
586 586
 	}
587 587
 
588 588
 	if((ret = cli_parse_add(root, virname, sig, 0, offset, target))) {
589
-	    cli_errmsg("Problem parsing signature at line %d\n", line);
590 589
 	    ret = CL_EMALFDB;
591 590
 	    break;
592 591
 	}
... ...
@@ -437,3 +437,12 @@ void cli_strtokenize(char *buffer, const char delim, const size_t token_count, c
437 437
 	}
438 438
     }
439 439
 }
440
+
441
+int cli_isnumber(const char *str)
442
+{
443
+    while(*str++)
444
+	if(!strchr("0123456789", *str))
445
+	    return 0;
446
+
447
+    return 1;
448
+}
... ...
@@ -41,4 +41,5 @@ char *cli_strtokbuf(const char *input, int fieldno, const char *delim, char *out
41 41
 const char *cli_memstr(const char *haystack, int hs, const char *needle, int ns);
42 42
 char *cli_strrcpy(char *dest, const char *source);
43 43
 void cli_strtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens);
44
+int cli_isnumber(const char *str);
44 45
 #endif
... ...
@@ -258,7 +258,7 @@ struct cfgstruct *getcfg(const char *cfgfile, int verbose)
258 258
 				}
259 259
 				break;
260 260
 			    case OPT_NUM:
261
-				if(!arg || !isnumb(arg)) {
261
+				if(!arg || !cli_isnumber(arg)) {
262 262
 				    if(verbose)
263 263
 					fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical argument.\n", line, name);
264 264
 				    fclose(fs);
... ...
@@ -290,7 +290,7 @@ struct cfgstruct *getcfg(const char *cfgfile, int verbose)
290 290
 				if(ctype == 'm' || ctype == 'k') {
291 291
 				    char *cpy = (char *) calloc(strlen(arg), 1);
292 292
 				    strncpy(cpy, arg, strlen(arg) - 1);
293
-				    if(!isnumb(cpy)) {
293
+				    if(!cli_isnumber(cpy)) {
294 294
 					if(verbose)
295 295
 					    fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name);
296 296
 					fclose(fs);
... ...
@@ -305,7 +305,7 @@ struct cfgstruct *getcfg(const char *cfgfile, int verbose)
305 305
 					calc = atoi(cpy) * 1024;
306 306
 				    free(cpy);
307 307
 				} else {
308
-				    if(!isnumb(arg)) {
308
+				    if(!cli_isnumber(arg)) {
309 309
 					if(verbose)
310 310
 					    fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name);
311 311
 					fclose(fs);
... ...
@@ -248,17 +248,6 @@ int dircopy(const char *src, const char *dest)
248 248
 }
249 249
 #endif
250 250
 
251
-int isnumb(const char *str)
252
-{
253
-    while(*str) {
254
-	if(!isdigit(*str & 0xff))
255
-	    return 0;
256
-	str++;
257
-    }
258
-
259
-    return 1;
260
-}
261
-
262 251
 #ifndef CL_NOLIBCLAMAV
263 252
 int cvd_unpack(const char *cvd, const char *destdir)
264 253
 {
... ...
@@ -35,7 +35,6 @@
35 35
 char *freshdbdir(void);
36 36
 void print_version(const char *dbdir);
37 37
 int filecopy(const char *src, const char *dest);
38
-int isnumb(const char *str);
39 38
 int dircopy(const char *src, const char *dest);
40 39
 int cvd_unpack(const char *cvd, const char *destdir);
41 40
 int daemonize(void);