kcsan: test: Adjust "expect" allocation type for kmalloc_obj
PATCH 1/1 kcsan: test: Adjust "expect" allocation type for kmalloc_obj
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect = kmalloc_obj(observed.lines);
| ^
Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsan
---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>
--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/kcsan/kcsan_test.c +1 -1
@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false; - expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);if (WARN_ON (!expect))return false;
Signature · 1 line
2.34.1
Marco Elver
maintainerQuoted 35 lines · Kees Cook
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect =kmalloc_obj(observed.lines);
| ^Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsanReported-by Nathan Chancellor <[email protected]>Fixes 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")Signed-off-by Kees Cook <[email protected]>---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/kcsan/kcsan_test.c +0
-0
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 5 lines
kernel/kcsan/kcsan_test.c +1
-1@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false; - expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);
This is wrong. Instead of allocating 3x512 bytes it's now only allocating 512 bytes, so we get OOB below with this change. 'expect' is a pointer to a 3-dimensional array of 512-char arrays (matching observed.lines).
Quoted 39 lines · Marco Elver
Quoted 38 lines · Kees Cook
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect =kmalloc_obj(observed.lines);
| ^Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsanReported-by Nathan Chancellor <[email protected]>Fixes 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")Signed-off-by Kees Cook <[email protected]>---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/kcsan/kcsan_test.c +0
-0@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false;
Quoted 7 lines
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 2 lines
kernel/kcsan/kcsan_test.c +1
-1- expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);This is wrong. Instead of allocating 3x512 bytes it's now only allocating 512 bytes, so we get OOB below with this change. 'expect' is a pointer to a 3-dimensional array of 512-char arrays (matching observed.lines).
Why did running the kunit test not trip over this? :(
Hmpf, getting arrays allocated without an explicit cast seems to be impossible. How about this:
kernel/kcsan/kcsan_test.c +1 -1
@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false; - expect =kmalloc_obj (*expect); + expect = (typeof (expect ))kmalloc_obj (observed.lines);if (WARN_ON (!expect))return false;
Signature · 1 line
Kees Cook
Marco Elver
maintainerQuoted 60 lines · Kees Cook
Quoted 39 lines · Marco Elver
Quoted 38 lines · Kees Cook
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect =kmalloc_obj(observed.lines);
| ^Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsanReported-by Nathan Chancellor <[email protected]>Fixes 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")Signed-off-by Kees Cook <[email protected]>---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/kcsan/kcsan_test.c +0
-0@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false;Quoted 7 lines
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 2 lines
kernel/kcsan/kcsan_test.c +1
-1- expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);This is wrong. Instead of allocating 3x512 bytes it's now only allocating 512 bytes, so we get OOB below with this change. 'expect' is a pointer to a 3-dimensional array of 512-char arrays (matching observed.lines).
Why did running the kunit test not trip over this? :(
Hmpf, getting arrays allocated without an explicit cast seems to be impossible. How about this:
kernel/kcsan/kcsan_test.c +0
-0
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 5 lines
kernel/kcsan/kcsan_test.c +1
-1@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false; - expect =kmalloc_obj (*expect); + expect = (typeof (expect ))kmalloc_obj (observed.lines);
That works - or why not revert it back to normal kmalloc? There's marginal benefit for kmalloc_obj() in this case, and this really is just a bunch of char buffers - not a complex object. If there's still a benefit to be had from kmalloc_obj() here, I'm fine with the typeof cast.
Thanks,
-- Marco
Quoted 64 lines · Marco Elver
Quoted 63 lines · Kees Cook
Quoted 39 lines · Marco Elver
Quoted 38 lines · Kees Cook
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect =kmalloc_obj(observed.lines);
| ^Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsanReported-by Nathan Chancellor <[email protected]>Fixes 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")Signed-off-by Kees Cook <[email protected]>---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/kcsan/kcsan_test.c +0
-0@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false;Quoted 7 lines
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 2 lines
kernel/kcsan/kcsan_test.c +1
-1- expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);This is wrong. Instead of allocating 3x512 bytes it's now only allocating 512 bytes, so we get OOB below with this change. 'expect' is a pointer to a 3-dimensional array of 512-char arrays (matching observed.lines).
Why did running the kunit test not trip over this? :(
Hmpf, getting arrays allocated without an explicit cast seems to be impossible. How about this:
kernel/kcsan/kcsan_test.c +0
-0@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false;
Quoted 8 lines
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 2 lines
kernel/kcsan/kcsan_test.c +1
-1- expect =kmalloc_obj (*expect); + expect = (typeof (expect ))kmalloc_obj (observed.lines);That works - or why not revert it back to normal kmalloc? There's marginal benefit for
kmalloc_obj()in this case, and this really is just a bunch of char buffers - not a complex object. If there's still a benefit to be had fromkmalloc_obj()here, I'm fine with the typeof cast.
Honestly... it's because I can't figure out how to make a exclusion for this (nor how to get multidimensional array types) in Coccinelle to avoid this case. (So re-running the conversion script will keep trying to change this case.) And it's the only place in the kernel doing this kind of thing. :P
I've sent v2 with the cast and a better commit log describing what's happening.
Signature · 1 line
Kees Cook
Quoted 59 lines · Kees Cook
Quoted 39 lines · Marco Elver
Quoted 38 lines · Kees Cook
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect =kmalloc_obj(observed.lines);
| ^Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsanReported-by Nathan Chancellor <[email protected]>Fixes 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")Signed-off-by Kees Cook <[email protected]>---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/kcsan/kcsan_test.c +0
-0@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false;Quoted 7 lines
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 2 lines
kernel/kcsan/kcsan_test.c +1
-1- expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);This is wrong. Instead of allocating 3x512 bytes it's now only allocating 512 bytes, so we get OOB below with this change. 'expect' is a pointer to a 3-dimensional array of 512-char arrays (matching observed.lines).
Why did running the kunit test not trip over this? :(
Hmpf, getting arrays allocated without an explicit cast seems to be impossible. How about this:
kernel/kcsan/kcsan_test.c +0
-0
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 173
Quoted 7 lines
kernel/kcsan/kcsan_test.c +1
-1@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false; - expect =kmalloc_obj (*expect); + expect = (typeof (expect ))kmalloc_obj (observed.lines);if (WARN_ON (!expect))return false;
Or:
expect = kmalloc_objs(*observed.lines, ARRAY_SIZE(observed.lines));
I think the quoted cast is probably better...
Signature · 1 line
Kees Cook
Marco Elver
maintainerQuoted 71 lines · Kees Cook
Quoted 59 lines · Kees Cook
Quoted 39 lines · Marco Elver
Quoted 38 lines · Kees Cook
Instead of depending on the implicit case between a pointer to pointers and pointer to arrays, use the assigned variable type for the allocation type so they correctly match. Solves the following build error:
../kernel/kcsan/kcsan_test.c: In function '__report_matches':../kernel/kcsan/kcsan_test.c:171:16: error: assignment to 'char (*)[512]' from incompatible pointer type 'char (*)[3][512]' [-Wincompatible-pointer-types]
171 | expect =kmalloc_obj(observed.lines);
| ^Tested with:
$ ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_KCSAN=y \ --kconfig_add CONFIG_KCSAN_KUNIT_TEST=y \ --arch=x86_64 --qemu_args '-smp 2' kcsanReported-by Nathan Chancellor <[email protected]>Fixes 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")Signed-off-by Kees Cook <[email protected]>---
Cc: Marco Elver <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: <[email protected]>--- kernel/kcsan/kcsan_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)kernel/kcsan/kcsan_test.c +0
-0@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false;Quoted 7 lines
kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 171
Quoted 2 lines
kernel/kcsan/kcsan_test.c +1
-1- expect =kmalloc_obj (observed.lines); + expect =kmalloc_obj (*expect);This is wrong. Instead of allocating 3x512 bytes it's now only allocating 512 bytes, so we get OOB below with this change. 'expect' is a pointer to a 3-dimensional array of 512-char arrays (matching observed.lines).
Why did running the kunit test not trip over this? :(
Hmpf, getting arrays allocated without an explicit cast seems to be impossible. How about this:
kernel/kcsan/kcsan_test.c +0
-0kernel/kcsan/kcsan_test.c static bool __report_matches(const struct expect_report *r) · line 173
Quoted 7 lines
kernel/kcsan/kcsan_test.c +1
-1@@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r)if (!report_available ())return false; - expect =kmalloc_obj (*expect); + expect = (typeof (expect ))kmalloc_obj (observed.lines);if (WARN_ON (!expect))return false;Or:
Quoted 3 lines
expect = kmalloc_objs(*observed.lines, ARRAY_SIZE(observed.lines));I think the quoted cast is probably better...
The cast is easier to read (no indirection needed to understand it's just allocating same size as observed.lines).