Re: [PATCH] kcsan: fix debugfs initcall return type

From: Nathan Chancellor
Date: Sun May 16 2021 - 01:28:25 EST


Hi Marco,

On Sat, May 15, 2021 at 01:01:31AM +0200, Marco Elver wrote:
> FWIW, this prompted me to see if I can convince the compiler to complain
> in all configs. The below is what I came up with and will send once the
> fix here has landed. Need to check a few other config+arch combinations
> (allyesconfig with gcc on x86_64 is good).
>
> Thanks,
> -- Marco
>
> ------ >8 ------
>
> >From 96c1c4e9902e96485268909d5ea8f91b9595e187 Mon Sep 17 00:00:00 2001
> From: Marco Elver <elver@xxxxxxxxxx>
> Date: Fri, 14 May 2021 21:08:50 +0200
> Subject: [PATCH] init: verify that function is initcall_t at compile-time
>
> In the spirit of making it hard to misuse an interface, add a
> compile-time assertion in the CONFIG_HAVE_ARCH_PREL32_RELOCATIONS case
> to verify the initcall function matches initcall_t, because the inline
> asm bypasses any type-checking the compiler would otherwise do. This
> will help developers catch incorrect API use in all configurations.
>
> A recent example of this is:
> https://lkml.kernel.org/r/20210514140015.2944744-1-arnd@xxxxxxxxxx
>
> Signed-off-by: Marco Elver <elver@xxxxxxxxxx>
> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> Cc: Arnd Bergmann <arnd@xxxxxxxx>
> Cc: Joe Perches <joe@xxxxxxxxxxx>
> Cc: Masahiro Yamada <masahiroy@xxxxxxxxxx>
> Cc: Miguel Ojeda <ojeda@xxxxxxxxxx>
> Cc: Nathan Chancellor <nathan@xxxxxxxxxx>
> Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxx>

Hi Marco,

I verified that I see an error without Arnd's patch with all supported
KCSAN compilers when I apply this patch.

clang-11: https://builds.tuxbuild.com/1sYcyUZoCS7hFS3qZMZsJgsA5bp/build.log
clang-12: https://builds.tuxbuild.com/1sYcyRDtvvkaQQbGX435X8FUb6o/build.log
clang-13: https://builds.tuxbuild.com/1sYcyPubVREo7Dl05zCKRRNh6RB/build.log

gcc-11 had to be done locally as TuxSuite appears not to support gcc-11
so no nifty link:

In file included from /home/nathan/cbl/src/korg-linux/include/asm-generic/atomic-instrumented.h:20,
from /home/nathan/cbl/src/korg-linux/include/linux/atomic.h:82,
from /home/nathan/cbl/src/korg-linux/kernel/kcsan/debugfs.c:10:
/home/nathan/cbl/src/korg-linux/include/linux/build_bug.h:78:41: error: static assertion failed: "__same_type(initcall_t, &kcsan_debugfs_init)"
78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
| ^~~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/include/linux/build_bug.h:77:34: note: in expansion of macro '__static_assert'
77 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
| ^~~~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/include/linux/init.h:246:9: note: in expansion of macro 'static_assert'
246 | static_assert(__same_type(initcall_t, &fn));
| ^~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/include/linux/init.h:254:9: note: in expansion of macro '____define_initcall'
254 | ____define_initcall(fn, \
| ^~~~~~~~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/include/linux/init.h:260:9: note: in expansion of macro '__unique_initcall'
260 | __unique_initcall(fn, id, __sec, __initcall_id(fn))
| ^~~~~~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/include/linux/init.h:262:35: note: in expansion of macro '___define_initcall'
262 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)
| ^~~~~~~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/include/linux/init.h:293:41: note: in expansion of macro '__define_initcall'
293 | #define late_initcall(fn) __define_initcall(fn, 7)
| ^~~~~~~~~~~~~~~~~
/home/nathan/cbl/src/korg-linux/kernel/kcsan/debugfs.c:274:1: note: in expansion of macro 'late_initcall'
274 | late_initcall(kcsan_debugfs_init);
| ^~~~~~~~~~~~~
make[3]: *** [/home/nathan/cbl/src/korg-linux/scripts/Makefile.build:273: kernel/kcsan/debugfs.o] Error 1

I did a series of builds against next-20210514 with gcc 8 through 10 and
clang 11 through 13 targeting arm, arm64, i386, powerpc, s390, and
x86_64 defconfig and allmodconfig with no errors with this patch on top
of Arnd's. Repo and TuxSuite configuration below in case anyone cares :)

https://git.kernel.org/pub/scm/linux/kernel/git/nathan/linux.git/log/?h=tuxsuite/initcall-static-assert
https://gist.github.com/nathanchance/eb71e1c2287561a0de79ef28c3c521384

When you formally send it, please feel free to add:

Reviewed-by: Nathan Chancellor <nathan@xxxxxxxxxx>
Tested-by: Nathan Chancellor <nathan@xxxxxxxxxx>

Cheers,
Nathan

> ---
> include/linux/init.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/init.h b/include/linux/init.h
> index 045ad1650ed1..d82b4b2e1d25 100644
> --- a/include/linux/init.h
> +++ b/include/linux/init.h
> @@ -242,7 +242,8 @@ extern bool initcall_debug;
> asm(".section \"" __sec "\", \"a\" \n" \
> __stringify(__name) ": \n" \
> ".long " __stringify(__stub) " - . \n" \
> - ".previous \n");
> + ".previous \n"); \
> + static_assert(__same_type(initcall_t, &fn));
> #else
> #define ____define_initcall(fn, __unused, __name, __sec) \
> static initcall_t __name __used \
> --
> 2.31.1.751.gd2f1c929bd-goog
>