changeset 17563:2ed2ab04b63d

pop3: pop3-commands - harden integer parsers against integer overflow In get_msgnum(), the invalid input "4772185884" (2^32*10/9) would be parsed as being valid. In get_size(), the invalid input "204963823041217240178" (2^64*10/9) would be parsed as being valid. We have helpers now, so use them. Signed-off-by: Phil Carmody <phil@dovecot.fi>
author Phil Carmody <phil@dovecot.fi>
date Wed, 02 Jul 2014 18:21:24 +0300
parents 2051de7285c4
children d77d880c1385
files src/pop3/pop3-commands.c
diffstat 1 files changed, 6 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/pop3/pop3-commands.c	Wed Jul 02 18:21:24 2014 +0300
+++ b/src/pop3/pop3-commands.c	Wed Jul 02 18:21:24 2014 +0300
@@ -28,24 +28,20 @@
 static const char *get_msgnum(struct client *client, const char *args,
 			      unsigned int *msgnum)
 {
-	unsigned int num, last_num;
+	unsigned int num;
 
-	num = 0;
-	while (*args != '\0' && *args != ' ') {
+	if (*args != '\0' && *args != ' ') {
 		if (*args < '0' || *args > '9') {
 			client_send_line(client,
 				"-ERR Invalid message number: %s", args);
 			return NULL;
 		}
 
-		last_num = num;
-		num = num*10 + (*args - '0');
-		if (num < last_num) {
+		if (str_parse_uint(args, &num, &args) < 0) {
 			client_send_line(client,
 				"-ERR Message number too large: %s", args);
 			return NULL;
 		}
-		args++;
 	}
 
 	if (num == 0 || num > client->messages_count) {
@@ -72,24 +68,20 @@
 static const char *get_size(struct client *client, const char *args,
 			    uoff_t *size)
 {
-	uoff_t num, last_num;
+	uoff_t num;
 
-	num = 0;
-	while (*args != '\0' && *args != ' ') {
+	if (*args != '\0' && *args != ' ') {
 		if (*args < '0' || *args > '9') {
 			client_send_line(client, "-ERR Invalid size: %s",
 					 args);
 			return NULL;
 		}
 
-		last_num = num;
-		num = num*10 + (*args - '0');
-		if (num < last_num) {
+		if (str_parse_uoff(args, &num, &args) < 0) {
 			client_send_line(client, "-ERR Size too large: %s",
 					 args);
 			return NULL;
 		}
-		args++;
 	}
 
 	while (*args == ' ') args++;