[Skiboot] [PATCH] vsscanf: Fix out of bound write

Kamalesh Babulal kamalesh at linux.vnet.ibm.com
Thu Jul 9 18:59:02 AEST 2015


Fix of out of bound write in _scanf() by limiting write in to
tbuf[0..255]. Also, re-format the code to 80 column width
and remove trailing white spaces.

Fixes Coverity defect#97845.

Signed-off-by: Kamalesh Babulal <kamalesh at linux.vnet.ibm.com>
---
 libc/stdio/vsscanf.c | 51 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/libc/stdio/vsscanf.c b/libc/stdio/vsscanf.c
index b9603e9..393dcce 100644
--- a/libc/stdio/vsscanf.c
+++ b/libc/stdio/vsscanf.c
@@ -21,18 +21,20 @@ _scanf(const char **buffer, const char *fmt, va_list *ap)
 	int i;
 	int length = 0;
 
-	fmt++;	
+	fmt++;
 
 	while(*fmt != '\0') {
-		
+
 		char tbuf[256];
 
 		switch(*fmt) {
 			case 'd':
 			case 'i':
 				if(length == 0) length = 256;
-				
-				for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+
+				for(i = 0; **buffer != ' ' && **buffer != '\t'
+					&& **buffer != '\n'
+					&& i < (length - 1); i++) {
 					tbuf[i] = **buffer;
 					*buffer += 1;
 				}
@@ -43,20 +45,24 @@ _scanf(const char **buffer, const char *fmt, va_list *ap)
 			case 'X':
 			case 'x':
 				if(length == 0) length = 256;
-				
-				for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+
+				for(i = 0; **buffer != ' ' && **buffer != '\t'
+					&& **buffer != '\n'
+					&& i < (length - 1); i++) {
 					tbuf[i] = **buffer;
 					*buffer += 1;
 				}
 				tbuf[i] = '\0';
-					
+
 				*(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16);
 				break;
 			case 'O':
 			case 'o':
 				if(length == 0) length = 256;
-				
-				for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+
+				for(i = 0; **buffer != ' ' && **buffer != '\t'
+					&& **buffer != '\n'
+					&& i < (length - 1); i++) {
 					tbuf[i] = **buffer;
 					*buffer += 1;
 				}
@@ -73,8 +79,10 @@ _scanf(const char **buffer, const char *fmt, va_list *ap)
 				break;
 			case 's':
 				if(length == 0) length = 256;
-				
-				for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+
+				for(i = 0; **buffer != ' ' && **buffer != '\t'
+					&& **buffer != '\n'
+					&& i < (length - 1); i++) {
 					tbuf[i] = **buffer;
 					*buffer += 1;
 				}
@@ -84,7 +92,7 @@ _scanf(const char **buffer, const char *fmt, va_list *ap)
 				strcpy(va_arg(*ap, char *), tbuf);
 				break;
 			default:
-				if(*fmt >= '0' && *fmt <= '9') 
+				if(*fmt >= '0' && *fmt <= '9')
 					length += *fmt - '0';
 				break;
 		}
@@ -99,28 +107,31 @@ vsscanf(const char *buffer, const char *fmt, va_list ap)
 {
 
 	while(*fmt != '\0') {
-		
+
 		if(*fmt == '%') {
-			
+
 			char formstr[20];
 			int i=0;
-			
+
 			do {
 				formstr[i] = *fmt;
 				fmt++;
 				i++;
-			} while(!(*fmt == 'd' || *fmt == 'i' || *fmt == 'x' || *fmt == 'X'
-						|| *fmt == 'p' || *fmt == 'c' || *fmt == 's' || *fmt == '%'
-						|| *fmt == 'O' || *fmt == 'o' )); 
+			} while(!(*fmt == 'd' || *fmt == 'i' || *fmt == 'x'
+					      || *fmt == 'X' || *fmt == 'p'
+					      || *fmt == 'c' || *fmt == 's'
+					      || *fmt == '%' || *fmt == 'O'
+					      || *fmt == 'o' ));
 			formstr[i++] = *fmt;
 			formstr[i] = '\0';
 			if(*fmt != '%') {
-				while(*buffer == ' ' || *buffer == '\t' || *buffer == '\n')
+				while(*buffer == ' ' || *buffer == '\t'
+						     || *buffer == '\n')
 					buffer++;
 				_scanf(&buffer, formstr, &ap);
 			}
 
-		} 
+		}
 
 		fmt++;
 
-- 
2.1.2



More information about the Skiboot mailing list