Module Name:    src
Committed By:   christos
Date:           Sat Oct 22 22:08:48 UTC 2011

Modified Files:
        src/lib/libc/stdlib: strsuftoll.c

Log Message:
Put a recursion limit to avoid DoS attacks (Maksymilian Arciemowicz)
While there do minor KNF, and do as the manual says: exit with EXIT_FAILURE


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/lib/libc/stdlib/strsuftoll.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/stdlib/strsuftoll.c
diff -u src/lib/libc/stdlib/strsuftoll.c:1.8 src/lib/libc/stdlib/strsuftoll.c:1.9
--- src/lib/libc/stdlib/strsuftoll.c:1.8	Mon Apr 28 16:23:00 2008
+++ src/lib/libc/stdlib/strsuftoll.c	Sat Oct 22 18:08:47 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: strsuftoll.c,v 1.8 2008/04/28 20:23:00 martin Exp $	*/
+/*	$NetBSD: strsuftoll.c,v 1.9 2011/10/22 22:08:47 christos Exp $	*/
 /*-
  * Copyright (c) 2001-2002,2004 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -67,7 +67,7 @@
 #include <sys/cdefs.h>
 
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: strsuftoll.c,v 1.8 2008/04/28 20:23:00 martin Exp $");
+__RCSID("$NetBSD: strsuftoll.c,v 1.9 2011/10/22 22:08:47 christos Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef _LIBC
@@ -121,8 +121,8 @@ strsuftoll(const char *desc, const char 
 
 	result = strsuftollx(desc, val, min, max, errbuf, sizeof(errbuf));
 	if (*errbuf != '\0')
-		errx(1, "%s", errbuf);
-	return (result);
+		errx(EXIT_FAILURE, "%s", errbuf);
+	return result;
 }
 
 /*
@@ -130,9 +130,9 @@ strsuftoll(const char *desc, const char 
  * rather than exiting with it.
  */
 /* LONGLONG */
-long long
-strsuftollx(const char *desc, const char *val,
-    long long min, long long max, char *ebuf, size_t ebuflen)
+static long long
+__strsuftollx(const char *desc, const char *val,
+    long long min, long long max, char *ebuf, size_t ebuflen, size_t depth)
 {
 	long long num, t;
 	char	*expr;
@@ -141,12 +141,15 @@ strsuftollx(const char *desc, const char
 	_DIAGASSERT(val != NULL);
 	_DIAGASSERT(ebuf != NULL);
 
-	errno = 0;
-	ebuf[0] = '\0';
+	if (depth > 16) {
+		snprintf(ebuf, ebuflen, "%s: Recursion limit exceeded", desc);
+		return 0;
+	}
 
 	while (isspace((unsigned char)*val))	/* Skip leading space */
 		val++;
 
+	errno = 0;
 	num = strtoll(val, &expr, 10);
 	if (errno == ERANGE)
 		goto erange;			/* Overflow */
@@ -205,36 +208,42 @@ strsuftollx(const char *desc, const char
 	case '*':				/* Backward compatible */
 	case 'x':
 		t = num;
-		num *= strsuftollx(desc, expr + 1, min, max, ebuf, ebuflen);
+		num *= __strsuftollx(desc, expr + 1, min, max, ebuf, ebuflen,
+			depth + 1);
 		if (*ebuf != '\0')
-			return (0);
+			return 0;
 		if (t > num) {
  erange:	 	
-			snprintf(ebuf, ebuflen,
-			    "%s: %s", desc, strerror(ERANGE));
-			return (0);
+			errno = ERANGE;
+			snprintf(ebuf, ebuflen, "%s: %s", desc, strerror(errno));
+			return 0;
 		}
 		break;
 	default:
- badnum:	snprintf(ebuf, ebuflen,
-		    "%s `%s': illegal number", desc, val);
-		return (0);
+ badnum:
+		snprintf(ebuf, ebuflen, "%s `%s': illegal number", desc, val);
+		return 0;
 	}
 	if (num < min) {
-			/* LONGLONG */
+		/* LONGLONG */
 		snprintf(ebuf, ebuflen, "%s %lld is less than %lld.",
 		    desc, (long long)num, (long long)min);
-		return (0);
+		return 0;
 	}
 	if (num > max) {
-			/* LONGLONG */
-		snprintf(ebuf, ebuflen,
-		    "%s %lld is greater than %lld.",
+		/* LONGLONG */
+		snprintf(ebuf, ebuflen, "%s %lld is greater than %lld.",
 		    desc, (long long)num, (long long)max);
-		return (0);
+		return 0;
 	}
 	*ebuf = '\0';
-	return (num);
+	return num;
 }
 
+long long
+strsuftollx(const char *desc, const char *val,
+    long long min, long long max, char *ebuf, size_t ebuflen)
+{
+	return __strsuftollx(desc, val, min, max, ebuf, ebuflen, 0);
+}
 #endif /* !HAVE_STRSUFTOLL */

Reply via email to