This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] vfprint: validate nargs and argument-based offsets


The nargs value can overflow when doing allocations, and argument-based
offsets are not bounds-checked, allowing arbitrary memory writes via
format strings, bypassing _FORTIFY_SOURCE protections:
http://www.phrack.org/issues.html?issue=67&id=9

This checks for nargs overflow and validates argument-based array offsets.


2012-01-30  Kees Cook  <keescook@chromium.org>

	* stdio-common/vfprintf.c (vfprintf): Check for nargs overflow and
	validate argument-based array offsets.

diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 952886b..37ab6e4 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1700,6 +1700,13 @@ do_positional:
     /* Determine the number of arguments the format string consumes.  */
     nargs = MAX (nargs, max_ref_arg);
 
+    /* Check for potential integer overflow. */
+    if (nargs > SIZE_MAX / (2 * sizeof (int) + sizeof (union printf_arg)))
+      {
+         done = -1;
+         goto all_done;
+      }
+
     /* Allocate memory for the argument descriptions.  */
     args_type = alloca (nargs * sizeof (int));
     memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0',
@@ -1715,13 +1722,17 @@ do_positional:
     for (cnt = 0; cnt < nspecs; ++cnt)
       {
 	/* If the width is determined by an argument this is an int.  */
-	if (specs[cnt].width_arg != -1)
+	if (specs[cnt].width_arg != -1 && specs[cnt].width_arg < nargs)
 	  args_type[specs[cnt].width_arg] = PA_INT;
 
 	/* If the precision is determined by an argument this is an int.  */
-	if (specs[cnt].prec_arg != -1)
+	if (specs[cnt].prec_arg != -1 && specs[cnt].prec_arg < nargs)
 	  args_type[specs[cnt].prec_arg] = PA_INT;
 
+	/* Sanity-check the data_arg location. */
+	if (specs[cnt].ndata_args && specs[cnt].data_arg >= nargs)
+	  continue;
+
 	switch (specs[cnt].ndata_args)
 	  {
 	  case 0:		/* No arguments.  */
-- 
1.7.5.4


-- 
Kees Cook
ChromeOS Security


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]