Skip to content

Commit 9a3bfa0

Browse files
Villemoespmladek
authored andcommitted
lib/test_printf.c: split write-beyond-buffer check in two
Before each invocation of vsnprintf(), do_test() memsets the entire allocated buffer to a sentinel value. That buffer includes leading and trailing padding which is never included in the buffer area handed to vsnprintf (spaces merely for clarity): pad test_buffer pad **** **************** **** Then vsnprintf() is invoked with a bufsize argument <= BUF_SIZE. Suppose bufsize=10, then we'd have e.g. |pad | test_buffer |pad | **** pizza0 **** ****** **** A B C D E where vsnprintf() was given the area from B to D. It is obviously a bug for vsnprintf to touch anything between A and B or between D and E. The former is checked for as one would expect. But for the latter, we are actually a little stricter in that we check the area between C and E. Split that check in two, providing a clearer error message in case it was a genuine buffer overrun and not merely a write within the provided buffer, but after the end of the generated string. So far, no part of the vsnprintf() implementation has had any use for using the whole buffer as scratch space, but it's not unreasonable to allow that, as long as the result is properly nul-terminated and the return value is the right one. However, it is somewhat unusual, and most %<something> won't need this, so keep the [C,D] check, but make it easy for a later patch to make that part opt-out for certain tests. Signed-off-by: Rasmus Villemoes <[email protected]> Tested-by: Jia He <[email protected]> Signed-off-by: Jia He <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 9d88235 commit 9a3bfa0

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

lib/test_printf.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,17 @@ do_test(int bufsize, const char *expect, int elen,
7878
return 1;
7979
}
8080

81-
if (memchr_inv(test_buffer + written + 1, FILL_CHAR, BUF_SIZE + PAD_SIZE - (written + 1))) {
81+
if (memchr_inv(test_buffer + written + 1, FILL_CHAR, bufsize - (written + 1))) {
8282
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator\n",
8383
bufsize, fmt);
8484
return 1;
8585
}
8686

87+
if (memchr_inv(test_buffer + bufsize, FILL_CHAR, BUF_SIZE + PAD_SIZE - bufsize)) {
88+
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond buffer\n", bufsize, fmt);
89+
return 1;
90+
}
91+
8792
if (memcmp(test_buffer, expect, written)) {
8893
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
8994
bufsize, fmt, test_buffer, written, expect);

0 commit comments

Comments
 (0)