From c527d0ec189bc3493c15dee15fcfd635b8fa54ff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 22 Jul 2018 16:52:44 +0200 Subject: [PATCH] kernel: backport fixes for GCC 8 errors in syscall definitions Signed-off-by: Felix Fietkau --- ...-for-controlling-warnings-to-linux-c.patch | 140 +++++++++++++++++ ...te-alias-warning-for-SYSCALL_DEFINEx.patch | 88 +++++++++++ ...-for-controlling-warnings-to-linux-c.patch | 141 ++++++++++++++++++ ...te-alias-warning-for-SYSCALL_DEFINEx.patch | 88 +++++++++++ 4 files changed, 457 insertions(+) create mode 100644 target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch create mode 100644 target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch create mode 100644 target/linux/generic/backport-4.9/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch create mode 100644 target/linux/generic/backport-4.9/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch diff --git a/target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch b/target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch new file mode 100644 index 0000000000..6b56a68b31 --- /dev/null +++ b/target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch @@ -0,0 +1,140 @@ +From: Arnd Bergmann +Date: Tue, 19 Jun 2018 13:14:56 -0700 +Subject: [PATCH] kbuild: add macro for controlling warnings to + linux/compiler.h + +I have occasionally run into a situation where it would make sense to +control a compiler warning from a source file rather than doing so from +a Makefile using the $(cc-disable-warning, ...) or $(cc-option, ...) +helpers. + +The approach here is similar to what glibc uses, using __diag() and +related macros to encapsulate a _Pragma("GCC diagnostic ...") statement +that gets turned into the respective "#pragma GCC diagnostic ..." by +the preprocessor when the macro gets expanded. + +Like glibc, I also have an argument to pass the affected compiler +version, but decided to actually evaluate that one. For now, this +supports GCC_4_6, GCC_4_7, GCC_4_8, GCC_4_9, GCC_5, GCC_6, GCC_7, +GCC_8 and GCC_9. Adding support for CLANG_5 and other interesting +versions is straightforward here. GNU compilers starting with gcc-4.2 +could support it in principle, but "#pragma GCC diagnostic push" +was only added in gcc-4.6, so it seems simpler to not deal with those +at all. The same versions show a large number of warnings already, +so it seems easier to just leave it at that and not do a more +fine-grained control for them. + +The use cases I found so far include: + +- turning off the gcc-8 -Wattribute-alias warning inside of the + SYSCALL_DEFINEx() macro without having to do it globally. + +- Reducing the build time for a simple re-make after a change, + once we move the warnings from ./Makefile and + ./scripts/Makefile.extrawarn into linux/compiler.h + +- More control over the warnings based on other configurations, + using preprocessor syntax instead of Makefile syntax. This should make + it easier for the average developer to understand and change things. + +- Adding an easy way to turn the W=1 option on unconditionally + for a subdirectory or a specific file. This has been requested + by several developers in the past that want to have their subsystems + W=1 clean. + +- Integrating clang better into the build systems. Clang supports + more warnings than GCC, and we probably want to classify them + as default, W=1, W=2 etc, but there are cases in which the + warnings should be classified differently due to excessive false + positives from one or the other compiler. + +- Adding a way to turn the default warnings into errors (e.g. using + a new "make E=0" tag) while not also turning the W=1 warnings into + errors. + +This patch for now just adds the minimal infrastructure in order to +do the first of the list above. As the #pragma GCC diagnostic +takes precedence over command line options, the next step would be +to convert a lot of the individual Makefiles that set nonstandard +options to use __diag() instead. + +[paul.burton@mips.com: + - Rebase atop current master. + - Add __diag_GCC, or more generally __diag_, abstraction to + avoid code outside of linux/compiler-gcc.h needing to duplicate + knowledge about different GCC versions. + - Add a comment argument to __diag_{ignore,warn,error} which isn't + used in the expansion of the macros but serves to push people to + document the reason for using them - per feedback from Kees Cook. + - Translate severity to GCC-specific pragmas in linux/compiler-gcc.h + rather than using GCC-specific in linux/compiler_types.h. + - Drop all but GCC 8 macros, since we only need to define macros for + versions that we need to introduce pragmas for, and as of this + series that's just GCC 8. + - Capitalize comments in linux/compiler-gcc.h to match the style of + the rest of the file. + - Line up macro definitions with tabs in linux/compiler-gcc.h.] + +Signed-off-by: Arnd Bergmann +Signed-off-by: Paul Burton +Tested-by: Christophe Leroy +Tested-by: Stafford Horne +Signed-off-by: Masahiro Yamada +--- + +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -343,3 +343,28 @@ + * code + */ + #define uninitialized_var(x) x = x ++ ++/* ++ * Turn individual warnings and errors on and off locally, depending ++ * on version. ++ */ ++#define __diag_GCC(version, severity, s) \ ++ __diag_GCC_ ## version(__diag_GCC_ ## severity s) ++ ++/* Severity used in pragma directives */ ++#define __diag_GCC_ignore ignored ++#define __diag_GCC_warn warning ++#define __diag_GCC_error error ++ ++/* Compilers before gcc-4.6 do not understand "#pragma GCC diagnostic push" */ ++#if GCC_VERSION >= 40600 ++#define __diag_str1(s) #s ++#define __diag_str(s) __diag_str1(s) ++#define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) ++#endif ++ ++#if GCC_VERSION >= 80000 ++#define __diag_GCC_8(s) __diag(s) ++#else ++#define __diag_GCC_8(s) ++#endif +--- a/include/linux/compiler_types.h ++++ b/include/linux/compiler_types.h +@@ -271,4 +271,22 @@ struct ftrace_likely_data { + # define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) + #endif + ++#ifndef __diag ++#define __diag(string) ++#endif ++ ++#ifndef __diag_GCC ++#define __diag_GCC(version, severity, string) ++#endif ++ ++#define __diag_push() __diag(push) ++#define __diag_pop() __diag(pop) ++ ++#define __diag_ignore(compiler, version, option, comment) \ ++ __diag_ ## compiler(version, ignore, option) ++#define __diag_warn(compiler, version, option, comment) \ ++ __diag_ ## compiler(version, warn, option) ++#define __diag_error(compiler, version, option, comment) \ ++ __diag_ ## compiler(version, error, option) ++ + #endif /* __LINUX_COMPILER_TYPES_H */ diff --git a/target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch b/target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch new file mode 100644 index 0000000000..2440ed8c0d --- /dev/null +++ b/target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch @@ -0,0 +1,88 @@ +From: Arnd Bergmann +Date: Tue, 19 Jun 2018 13:14:57 -0700 +Subject: [PATCH] disable -Wattribute-alias warning for SYSCALL_DEFINEx() + +gcc-8 warns for every single definition of a system call entry +point, e.g.: + +include/linux/compat.h:56:18: error: 'compat_sys_rt_sigprocmask' alias between functions of incompatible types 'long int(int, compat_sigset_t *, compat_sigset_t *, compat_size_t)' {aka 'long int(int, struct *, struct *, unsigned int)'} and 'long int(long int, long int, long int, long int)' [-Werror=attribute-alias] + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ + ^~~~~~~~~~ +include/linux/compat.h:45:2: note: in expansion of macro 'COMPAT_SYSCALL_DEFINEx' + COMPAT_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) + ^~~~~~~~~~~~~~~~~~~~~~ +kernel/signal.c:2601:1: note: in expansion of macro 'COMPAT_SYSCALL_DEFINE4' + COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, + ^~~~~~~~~~~~~~~~~~~~~~ +include/linux/compat.h:60:18: note: aliased declaration here + asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ + ^~~~~~~~~~ + +The new warning seems reasonable in principle, but it doesn't +help us here, since we rely on the type mismatch to sanitize the +system call arguments. After I reported this as GCC PR82435, a new +-Wno-attribute-alias option was added that could be used to turn the +warning off globally on the command line, but I'd prefer to do it a +little more fine-grained. + +Interestingly, turning a warning off and on again inside of +a single macro doesn't always work, in this case I had to add +an extra statement inbetween and decided to copy the __SC_TEST +one from the native syscall to the compat syscall macro. See +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 for more details +about this. + +[paul.burton@mips.com: + - Rebase atop current master. + - Split GCC & version arguments to __diag_ignore() in order to match + changes to the preceding patch. + - Add the comment argument to match the preceding patch.] + +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82435 +Signed-off-by: Arnd Bergmann +Signed-off-by: Paul Burton +Tested-by: Christophe Leroy +Tested-by: Stafford Horne +Signed-off-by: Masahiro Yamada +--- + +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -48,6 +48,9 @@ + COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) + + #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ ++ __diag_push(); \ ++ __diag_ignore(GCC, 8, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments");\ + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ + __attribute__((alias(__stringify(compat_SyS##name)))); \ + static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ +@@ -56,6 +59,7 @@ + { \ + return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ + } \ ++ __diag_pop(); \ + static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + + #ifndef compat_user_stack_pointer +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -208,6 +208,9 @@ static inline int is_syscall_trace_event + + #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__) + #define __SYSCALL_DEFINEx(x, name, ...) \ ++ __diag_push(); \ ++ __diag_ignore(GCC, 8, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments");\ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(SyS##name)))); \ + static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ +@@ -219,6 +222,7 @@ static inline int is_syscall_trace_event + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ + } \ ++ __diag_pop(); \ + static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + + /* diff --git a/target/linux/generic/backport-4.9/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch b/target/linux/generic/backport-4.9/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch new file mode 100644 index 0000000000..0511a92eeb --- /dev/null +++ b/target/linux/generic/backport-4.9/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch @@ -0,0 +1,141 @@ +From: Arnd Bergmann +Date: Tue, 19 Jun 2018 13:14:56 -0700 +Subject: [PATCH] kbuild: add macro for controlling warnings to + linux/compiler.h + +I have occasionally run into a situation where it would make sense to +control a compiler warning from a source file rather than doing so from +a Makefile using the $(cc-disable-warning, ...) or $(cc-option, ...) +helpers. + +The approach here is similar to what glibc uses, using __diag() and +related macros to encapsulate a _Pragma("GCC diagnostic ...") statement +that gets turned into the respective "#pragma GCC diagnostic ..." by +the preprocessor when the macro gets expanded. + +Like glibc, I also have an argument to pass the affected compiler +version, but decided to actually evaluate that one. For now, this +supports GCC_4_6, GCC_4_7, GCC_4_8, GCC_4_9, GCC_5, GCC_6, GCC_7, +GCC_8 and GCC_9. Adding support for CLANG_5 and other interesting +versions is straightforward here. GNU compilers starting with gcc-4.2 +could support it in principle, but "#pragma GCC diagnostic push" +was only added in gcc-4.6, so it seems simpler to not deal with those +at all. The same versions show a large number of warnings already, +so it seems easier to just leave it at that and not do a more +fine-grained control for them. + +The use cases I found so far include: + +- turning off the gcc-8 -Wattribute-alias warning inside of the + SYSCALL_DEFINEx() macro without having to do it globally. + +- Reducing the build time for a simple re-make after a change, + once we move the warnings from ./Makefile and + ./scripts/Makefile.extrawarn into linux/compiler.h + +- More control over the warnings based on other configurations, + using preprocessor syntax instead of Makefile syntax. This should make + it easier for the average developer to understand and change things. + +- Adding an easy way to turn the W=1 option on unconditionally + for a subdirectory or a specific file. This has been requested + by several developers in the past that want to have their subsystems + W=1 clean. + +- Integrating clang better into the build systems. Clang supports + more warnings than GCC, and we probably want to classify them + as default, W=1, W=2 etc, but there are cases in which the + warnings should be classified differently due to excessive false + positives from one or the other compiler. + +- Adding a way to turn the default warnings into errors (e.g. using + a new "make E=0" tag) while not also turning the W=1 warnings into + errors. + +This patch for now just adds the minimal infrastructure in order to +do the first of the list above. As the #pragma GCC diagnostic +takes precedence over command line options, the next step would be +to convert a lot of the individual Makefiles that set nonstandard +options to use __diag() instead. + +[paul.burton@mips.com: + - Rebase atop current master. + - Add __diag_GCC, or more generally __diag_, abstraction to + avoid code outside of linux/compiler-gcc.h needing to duplicate + knowledge about different GCC versions. + - Add a comment argument to __diag_{ignore,warn,error} which isn't + used in the expansion of the macros but serves to push people to + document the reason for using them - per feedback from Kees Cook. + - Translate severity to GCC-specific pragmas in linux/compiler-gcc.h + rather than using GCC-specific in linux/compiler_types.h. + - Drop all but GCC 8 macros, since we only need to define macros for + versions that we need to introduce pragmas for, and as of this + series that's just GCC 8. + - Capitalize comments in linux/compiler-gcc.h to match the style of + the rest of the file. + - Line up macro definitions with tabs in linux/compiler-gcc.h.] + +Signed-off-by: Arnd Bergmann +Signed-off-by: Paul Burton +Tested-by: Christophe Leroy +Tested-by: Stafford Horne +Signed-off-by: Masahiro Yamada +--- + +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -315,3 +315,28 @@ + * code + */ + #define uninitialized_var(x) x = x ++ ++/* ++ * Turn individual warnings and errors on and off locally, depending ++ * on version. ++ */ ++#define __diag_GCC(version, severity, s) \ ++ __diag_GCC_ ## version(__diag_GCC_ ## severity s) ++ ++/* Severity used in pragma directives */ ++#define __diag_GCC_ignore ignored ++#define __diag_GCC_warn warning ++#define __diag_GCC_error error ++ ++/* Compilers before gcc-4.6 do not understand "#pragma GCC diagnostic push" */ ++#if GCC_VERSION >= 40600 ++#define __diag_str1(s) #s ++#define __diag_str(s) __diag_str1(s) ++#define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) ++#endif ++ ++#if GCC_VERSION >= 80000 ++#define __diag_GCC_8(s) __diag(s) ++#else ++#define __diag_GCC_8(s) ++#endif +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -578,4 +578,23 @@ static __always_inline void __write_once + # define __kprobes + # define nokprobe_inline inline + #endif ++ ++#ifndef __diag ++#define __diag(string) ++#endif ++ ++#ifndef __diag_GCC ++#define __diag_GCC(version, severity, string) ++#endif ++ ++#define __diag_push() __diag(push) ++#define __diag_pop() __diag(pop) ++ ++#define __diag_ignore(compiler, version, option, comment) \ ++ __diag_ ## compiler(version, ignore, option) ++#define __diag_warn(compiler, version, option, comment) \ ++ __diag_ ## compiler(version, warn, option) ++#define __diag_error(compiler, version, option, comment) \ ++ __diag_ ## compiler(version, error, option) ++ + #endif /* __LINUX_COMPILER_H */ diff --git a/target/linux/generic/backport-4.9/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch b/target/linux/generic/backport-4.9/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch new file mode 100644 index 0000000000..fc2a26d7cd --- /dev/null +++ b/target/linux/generic/backport-4.9/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch @@ -0,0 +1,88 @@ +From: Arnd Bergmann +Date: Tue, 19 Jun 2018 13:14:57 -0700 +Subject: [PATCH] disable -Wattribute-alias warning for SYSCALL_DEFINEx() + +gcc-8 warns for every single definition of a system call entry +point, e.g.: + +include/linux/compat.h:56:18: error: 'compat_sys_rt_sigprocmask' alias between functions of incompatible types 'long int(int, compat_sigset_t *, compat_sigset_t *, compat_size_t)' {aka 'long int(int, struct *, struct *, unsigned int)'} and 'long int(long int, long int, long int, long int)' [-Werror=attribute-alias] + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ + ^~~~~~~~~~ +include/linux/compat.h:45:2: note: in expansion of macro 'COMPAT_SYSCALL_DEFINEx' + COMPAT_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) + ^~~~~~~~~~~~~~~~~~~~~~ +kernel/signal.c:2601:1: note: in expansion of macro 'COMPAT_SYSCALL_DEFINE4' + COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, + ^~~~~~~~~~~~~~~~~~~~~~ +include/linux/compat.h:60:18: note: aliased declaration here + asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ + ^~~~~~~~~~ + +The new warning seems reasonable in principle, but it doesn't +help us here, since we rely on the type mismatch to sanitize the +system call arguments. After I reported this as GCC PR82435, a new +-Wno-attribute-alias option was added that could be used to turn the +warning off globally on the command line, but I'd prefer to do it a +little more fine-grained. + +Interestingly, turning a warning off and on again inside of +a single macro doesn't always work, in this case I had to add +an extra statement inbetween and decided to copy the __SC_TEST +one from the native syscall to the compat syscall macro. See +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 for more details +about this. + +[paul.burton@mips.com: + - Rebase atop current master. + - Split GCC & version arguments to __diag_ignore() in order to match + changes to the preceding patch. + - Add the comment argument to match the preceding patch.] + +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82435 +Signed-off-by: Arnd Bergmann +Signed-off-by: Paul Burton +Tested-by: Christophe Leroy +Tested-by: Stafford Horne +Signed-off-by: Masahiro Yamada +--- + +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -47,6 +47,9 @@ + COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) + + #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ ++ __diag_push(); \ ++ __diag_ignore(GCC, 8, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments");\ + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ + __attribute__((alias(__stringify(compat_SyS##name)))); \ + static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ +@@ -55,6 +58,7 @@ + { \ + return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ + } \ ++ __diag_pop(); \ + static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + + #ifndef compat_user_stack_pointer +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -192,6 +192,9 @@ extern struct trace_event_functions exit + + #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__) + #define __SYSCALL_DEFINEx(x, name, ...) \ ++ __diag_push(); \ ++ __diag_ignore(GCC, 8, "-Wattribute-alias", \ ++ "Type aliasing is used to sanitize syscall arguments");\ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ + __attribute__((alias(__stringify(SyS##name)))); \ + static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ +@@ -203,6 +206,7 @@ extern struct trace_event_functions exit + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ + } \ ++ __diag_pop(); \ + static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + + asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, -- 2.25.1