diff options
author | Ryan Mallon <rmallon@gmail.com> | 2014-04-03 17:48:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 19:21:07 -0400 |
commit | 708d96fd060bd1e729fc93048cea8901f8bacb7c (patch) | |
tree | 1dc1656df18d946b6521f1c1c6b676dd8b2b465b /lib | |
parent | 28ab49ff7f3dcaf4df8d2bd0d4099b8c08285ed7 (diff) |
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 <rmallon@gmail.com>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vsprintf.c | 45 |
1 files changed, 9 insertions, 36 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 5e2cf6f342f8..0648291cdafe 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -364,7 +364,6 @@ enum format_type { | |||
364 | FORMAT_TYPE_SHORT, | 364 | FORMAT_TYPE_SHORT, |
365 | FORMAT_TYPE_UINT, | 365 | FORMAT_TYPE_UINT, |
366 | FORMAT_TYPE_INT, | 366 | FORMAT_TYPE_INT, |
367 | FORMAT_TYPE_NRCHARS, | ||
368 | FORMAT_TYPE_SIZE_T, | 367 | FORMAT_TYPE_SIZE_T, |
369 | FORMAT_TYPE_PTRDIFF | 368 | FORMAT_TYPE_PTRDIFF |
370 | }; | 369 | }; |
@@ -1538,10 +1537,6 @@ qualifier: | |||
1538 | return fmt - start; | 1537 | return fmt - start; |
1539 | /* skip alnum */ | 1538 | /* skip alnum */ |
1540 | 1539 | ||
1541 | case 'n': | ||
1542 | spec->type = FORMAT_TYPE_NRCHARS; | ||
1543 | return ++fmt - start; | ||
1544 | |||
1545 | case '%': | 1540 | case '%': |
1546 | spec->type = FORMAT_TYPE_PERCENT_CHAR; | 1541 | spec->type = FORMAT_TYPE_PERCENT_CHAR; |
1547 | return ++fmt - start; | 1542 | return ++fmt - start; |
@@ -1564,6 +1559,15 @@ qualifier: | |||
1564 | case 'u': | 1559 | case 'u': |
1565 | break; | 1560 | break; |
1566 | 1561 | ||
1562 | case 'n': | ||
1563 | /* | ||
1564 | * Since %n poses a greater security risk than utility, treat | ||
1565 | * it as an invalid format specifier. Warn about its use so | ||
1566 | * that new instances don't get added. | ||
1567 | */ | ||
1568 | WARN_ONCE(1, "Please remove ignored %%n in '%s'\n", fmt); | ||
1569 | /* Fall-through */ | ||
1570 | |||
1567 | default: | 1571 | default: |
1568 | spec->type = FORMAT_TYPE_INVALID; | 1572 | spec->type = FORMAT_TYPE_INVALID; |
1569 | return fmt - start; | 1573 | return fmt - start; |
@@ -1737,20 +1741,6 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1737 | ++str; | 1741 | ++str; |
1738 | break; | 1742 | break; |
1739 | 1743 | ||
1740 | case FORMAT_TYPE_NRCHARS: { | ||
1741 | /* | ||
1742 | * Since %n poses a greater security risk than | ||
1743 | * utility, ignore %n and skip its argument. | ||
1744 | */ | ||
1745 | void *skip_arg; | ||
1746 | |||
1747 | WARN_ONCE(1, "Please remove ignored %%n in '%s'\n", | ||
1748 | old_fmt); | ||
1749 | |||
1750 | skip_arg = va_arg(args, void *); | ||
1751 | break; | ||
1752 | } | ||
1753 | |||
1754 | default: | 1744 | default: |
1755 | switch (spec.type) { | 1745 | switch (spec.type) { |
1756 | case FORMAT_TYPE_LONG_LONG: | 1746 | case FORMAT_TYPE_LONG_LONG: |
@@ -2025,19 +2015,6 @@ do { \ | |||
2025 | fmt++; | 2015 | fmt++; |
2026 | break; | 2016 | break; |
2027 | 2017 | ||
2028 | case FORMAT_TYPE_NRCHARS: { | ||
2029 | /* skip %n 's argument */ | ||
2030 | u8 qualifier = spec.qualifier; | ||
2031 | void *skip_arg; | ||
2032 | if (qualifier == 'l') | ||
2033 | skip_arg = va_arg(args, long *); | ||
2034 | else if (_tolower(qualifier) == 'z') | ||
2035 | skip_arg = va_arg(args, size_t *); | ||
2036 | else | ||
2037 | skip_arg = va_arg(args, int *); | ||
2038 | break; | ||
2039 | } | ||
2040 | |||
2041 | default: | 2018 | default: |
2042 | switch (spec.type) { | 2019 | switch (spec.type) { |
2043 | 2020 | ||
@@ -2196,10 +2173,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) | |||
2196 | ++str; | 2173 | ++str; |
2197 | break; | 2174 | break; |
2198 | 2175 | ||
2199 | case FORMAT_TYPE_NRCHARS: | ||
2200 | /* skip */ | ||
2201 | break; | ||
2202 | |||
2203 | default: { | 2176 | default: { |
2204 | unsigned long long num; | 2177 | unsigned long long num; |
2205 | 2178 | ||