mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-28 01:54:33 +00:00
lib/test_printf.c: check for out-of-bound writes
Add a few padding bytes on either side of the test buffer, and check that these (and the part of the buffer not used) are untouched by vsnprintf. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Acked-by: Kees Cook <keescook@chromium.org> Cc: Al Viro <viro@ZenIV.linux.org.uk> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Joe Perches <joe@perches.com> Cc: Maurizio Lombardi <mlombard@redhat.com> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
fd0515d50f
commit
331e4deb6d
1 changed files with 19 additions and 5 deletions
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
|
|
||||||
#define BUF_SIZE 256
|
#define BUF_SIZE 256
|
||||||
|
#define PAD_SIZE 16
|
||||||
#define FILL_CHAR '$'
|
#define FILL_CHAR '$'
|
||||||
|
|
||||||
#define PTR1 ((void*)0x01234567)
|
#define PTR1 ((void*)0x01234567)
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
static unsigned total_tests __initdata;
|
static unsigned total_tests __initdata;
|
||||||
static unsigned failed_tests __initdata;
|
static unsigned failed_tests __initdata;
|
||||||
static char *test_buffer __initdata;
|
static char *test_buffer __initdata;
|
||||||
|
static char *alloced_buffer __initdata;
|
||||||
|
|
||||||
static int __printf(4, 0) __init
|
static int __printf(4, 0) __init
|
||||||
do_test(int bufsize, const char *expect, int elen,
|
do_test(int bufsize, const char *expect, int elen,
|
||||||
|
@ -49,7 +51,7 @@ do_test(int bufsize, const char *expect, int elen,
|
||||||
|
|
||||||
total_tests++;
|
total_tests++;
|
||||||
|
|
||||||
memset(test_buffer, FILL_CHAR, BUF_SIZE);
|
memset(alloced_buffer, FILL_CHAR, BUF_SIZE + 2*PAD_SIZE);
|
||||||
va_copy(aq, ap);
|
va_copy(aq, ap);
|
||||||
ret = vsnprintf(test_buffer, bufsize, fmt, aq);
|
ret = vsnprintf(test_buffer, bufsize, fmt, aq);
|
||||||
va_end(aq);
|
va_end(aq);
|
||||||
|
@ -60,8 +62,13 @@ do_test(int bufsize, const char *expect, int elen,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (memchr_inv(alloced_buffer, FILL_CHAR, PAD_SIZE)) {
|
||||||
|
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote before buffer\n", bufsize, fmt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!bufsize) {
|
if (!bufsize) {
|
||||||
if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE)) {
|
if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE + PAD_SIZE)) {
|
||||||
pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
|
pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
|
||||||
fmt);
|
fmt);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -76,6 +83,12 @@ do_test(int bufsize, const char *expect, int elen,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (memchr_inv(test_buffer + written + 1, FILL_CHAR, BUF_SIZE + PAD_SIZE - (written + 1))) {
|
||||||
|
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n",
|
||||||
|
bufsize, fmt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (memcmp(test_buffer, expect, written)) {
|
if (memcmp(test_buffer, expect, written)) {
|
||||||
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
|
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
|
||||||
bufsize, fmt, test_buffer, written, expect);
|
bufsize, fmt, test_buffer, written, expect);
|
||||||
|
@ -342,16 +355,17 @@ test_pointer(void)
|
||||||
static int __init
|
static int __init
|
||||||
test_printf_init(void)
|
test_printf_init(void)
|
||||||
{
|
{
|
||||||
test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
|
alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL);
|
||||||
if (!test_buffer)
|
if (!alloced_buffer)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
test_buffer = alloced_buffer + PAD_SIZE;
|
||||||
|
|
||||||
test_basic();
|
test_basic();
|
||||||
test_number();
|
test_number();
|
||||||
test_string();
|
test_string();
|
||||||
test_pointer();
|
test_pointer();
|
||||||
|
|
||||||
kfree(test_buffer);
|
kfree(alloced_buffer);
|
||||||
|
|
||||||
if (failed_tests == 0)
|
if (failed_tests == 0)
|
||||||
pr_info("all %u tests passed\n", total_tests);
|
pr_info("all %u tests passed\n", total_tests);
|
||||||
|
|
Loading…
Add table
Reference in a new issue