From b15775c48abb36de1b048ed03dd48b4c914c50c9 Mon Sep 17 00:00:00 2001 From: ru Date: Sat, 19 Apr 2008 07:18:22 +0000 Subject: Better strfmon(3) conversion specifiers sanity checking. There were no checks for left and right precisions at all, and a check for field width had integer overflow bug. Reported by: Maksymilian Arciemowicz Security: http://securityreason.com/achievement_securityalert/53 Submitted by: Maxim Dounin MFC after: 3 days --- lib/libc/stdlib/strfmon.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/libc/stdlib/strfmon.c') diff --git a/lib/libc/stdlib/strfmon.c b/lib/libc/stdlib/strfmon.c index 7ebded7..abfa332 100644 --- a/lib/libc/stdlib/strfmon.c +++ b/lib/libc/stdlib/strfmon.c @@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$"); while (isdigit((unsigned char)*fmt)) { \ VAR *= 10; \ VAR += *fmt - '0'; \ + if (VAR < 0) \ + goto e2big_error; \ fmt++; \ } \ } while (0) @@ -187,7 +189,7 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, /* Do we have enough space to put number with * required width ? */ - if (dst + width >= s + maxsize) + if ((unsigned int)width >= maxsize - (dst - s)) goto e2big_error; } @@ -196,6 +198,8 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, if (!isdigit((unsigned char)*++fmt)) goto format_error; GET_NUMBER(left_prec); + if ((unsigned int)left_prec >= maxsize - (dst - s)) + goto e2big_error; } /* Right precision */ @@ -203,6 +207,9 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, if (!isdigit((unsigned char)*++fmt)) goto format_error; GET_NUMBER(right_prec); + if ((unsigned int)right_prec >= maxsize - (dst - s) - + left_prec) + goto e2big_error; } /* Conversion Characters */ -- cgit v1.1