dovecot-2.2: lib: strnum - harden str_to_uintmax against overflows

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 2 15:23:20 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/1d873182d5a8
changeset: 17552:1d873182d5a8
user:      Phil Carmody <phil at dovecot.fi>
date:      Wed Jul 02 18:21:24 2014 +0300
description:
lib: strnum - harden str_to_uintmax against overflows
The invalid number "20496382304121724020" (2^64*10/9) will be parsed as valid.
2049638230412172402 * 10 does not noticably wrap, it becomes 2049638230412172404

Do not perform operations which might wrap, and then try to detect the issue,
just compare with the known fixed bounds before doing the multiplication.

Signed-off-by: Phil Carmody <phil at dovecot.fi>

diffstat:

 src/lib/strnum.c |  13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diffs (29 lines):

diff -r 6c1e44033e60 -r 1d873182d5a8 src/lib/strnum.c
--- a/src/lib/strnum.c	Wed Jul 02 18:21:24 2014 +0300
+++ b/src/lib/strnum.c	Wed Jul 02 18:21:24 2014 +0300
@@ -84,18 +84,19 @@
 
 int str_to_uintmax(const char *str, uintmax_t *num_r)
 {
-	uintmax_t next, n = 0;
+	uintmax_t n = 0;
 
 	if (*str < '0' || *str > '9')
 		return -1;
 
 	for (; *str >= '0' && *str <= '9'; str++) {
-		next = n*10;
-		if (next < n) {
-			/* overflow */
-			return -1;
+		if (n >= ((uintmax_t)-1 / 10)) {
+			if (n > (uintmax_t)-1 / 10)
+				return -1;
+			if ((uintmax_t)(*str - '0') > ((uintmax_t)-1 % 10))
+				return -1;
 		}
-		n = next + (*str - '0');
+		n = n * 10 + (*str - '0');
 	}
 	if (*str != '\0')
 		return -1;


More information about the dovecot-cvs mailing list