vsprintf: Remove %n handling
Subsystems (2)
PATCH 1/1 vsprintf: Remove %n handling
All in kernel users of %n in format strings have now been removed and the %n directive is ignored. Remove the handling of %n so that it is treated the same as any other invalid format string directive. Keep a warning in place to deter new instances of %n in format strings.
Signed-off-by Ryan Mallon <[email protected]>
Acked-by Kees Cook <[email protected]>
---
lib/vsprintf.c +9 -36
@@ -364,7 +364,6 @@ enum format_type {FORMAT_TYPE_SHORT ,FORMAT_TYPE_UINT ,FORMAT_TYPE_INT , -FORMAT_TYPE_NRCHARS ,FORMAT_TYPE_SIZE_T , FORMAT_TYPE_PTRDIFF };
@@ -1512,10 +1511,6 @@ qualifier:return fmt - start;/* skip alnum */ -case 'n' : - spec->type =FORMAT_TYPE_NRCHARS ; -return ++fmt - start; -case '%' : spec->type =FORMAT_TYPE_PERCENT_CHAR ;return ++fmt - start;
@@ -1538,6 +1533,15 @@ qualifier:case 'u' :break ; +case 'n' : +/* +* Since %n poses a greater security risk than utility, treat +* it as an invalid format specifier. Warn about its use so +* that new instances don't get added. +*/ +WARN_ONCE (1 ,"Please remove ignored %%n in '%s'\n" , fmt); +/* Fall-through */ +default : spec->type =FORMAT_TYPE_INVALID ;return fmt - start;
@@ -1711,20 +1715,6 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++str;break ; -case FORMAT_TYPE_NRCHARS : { -/* -* Since %n poses a greater security risk than -* utility, ignore %n and skip its argument. -*/ -void *skip_arg; - -WARN_ONCE (1 ,"Please remove ignored %%n in '%s'\n" , - old_fmt); - - skip_arg = va_arg(args, void *); -break ; - } -default :switch (spec.type) {case FORMAT_TYPE_LONG_LONG :
@@ -1999,19 +1989,6 @@ do { \ fmt++;break ; -case FORMAT_TYPE_NRCHARS : { -/* skip %n 's argument */ -u8 qualifier = spec.qualifier; -void *skip_arg; -if (qualifier =='l' ) - skip_arg = va_arg(args, long *); -else if (_tolower (qualifier) =='z' ) - skip_arg = va_arg(args, size_t *); -else - skip_arg = va_arg(args, int *); -break ; - } -default :switch (spec.type) {
@@ -2170,10 +2147,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) ++str;break ; -case FORMAT_TYPE_NRCHARS : -/* skip */ -break ; -default : {unsigned long long num;