[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