diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile.btf | 2 | ||||
-rw-r--r-- | scripts/Makefile.extrawarn | 9 | ||||
-rw-r--r-- | scripts/Makefile.gcc-plugins | 8 | ||||
-rw-r--r-- | scripts/Makefile.lib | 18 | ||||
-rw-r--r-- | scripts/Makefile.ubsan | 6 | ||||
-rw-r--r-- | scripts/basic/Makefile | 5 | ||||
-rwxr-xr-x | scripts/bpf_doc.py | 119 | ||||
-rwxr-xr-x | scripts/checkpatch.pl | 4 | ||||
-rw-r--r-- | scripts/gcc-plugins/Kconfig | 4 | ||||
-rw-r--r-- | scripts/gcc-plugins/Makefile | 4 | ||||
-rw-r--r-- | scripts/gcc-plugins/arm_ssp_per_task_plugin.c | 107 | ||||
-rw-r--r-- | scripts/gcc-plugins/randomize_layout_plugin.c | 18 |
12 files changed, 144 insertions, 160 deletions
diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index fbaaec2187e5..db76335dd917 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -23,6 +23,8 @@ else # Switch to using --btf_features for v1.26 and later. pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func,decl_tag_kfuncs +pahole-flags-$(call test-ge, $(pahole-ver), 130) += --btf_features=attributes + ifneq ($(KBUILD_EXTMOD),) module-pahole-flags-$(call test-ge, $(pahole-ver), 128) += --btf_features=distilled_base endif diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 540f3db5cd86..dca175fffcab 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -58,8 +58,13 @@ endif # These result in bogus false positives KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) -# Variable Length Arrays (VLAs) should not be used anywhere in the kernel -KBUILD_CFLAGS += -Wvla +# Stack Variable Length Arrays (VLAs) must not be used in the kernel. +# Function array parameters should, however, be usable, but -Wvla will +# warn for those. Clang has no way yet to distinguish between the VLA +# types, so depend on GCC for now to keep stack VLAs out of the tree. +# https://github.com/llvm/llvm-project/issues/57098 +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98217 +KBUILD_CFLAGS += $(call cc-option,-Wvla-larger-than=1) # disable pointer signed / unsigned warnings in gcc 4.0 KBUILD_CFLAGS += -Wno-pointer-sign diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index e4deaf5fa571..e50dc931be49 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -36,15 +36,9 @@ ifdef CONFIG_GCC_PLUGIN_STACKLEAK endif export DISABLE_STACKLEAK_PLUGIN -gcc-plugin-$(CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK) += arm_ssp_per_task_plugin.so -ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK - DISABLE_ARM_SSP_PER_TASK_PLUGIN += -fplugin-arg-arm_ssp_per_task_plugin-disable -endif -export DISABLE_ARM_SSP_PER_TASK_PLUGIN - # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS. -GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) +GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) -DGCC_PLUGINS export GCC_PLUGINS_CFLAGS # Add the flags to the build! diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2fe73cda0bdd..6fc2a82ee3bb 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -296,6 +296,19 @@ $(foreach m, $1, \ $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3)))) endef +# Remove ".." and "." from a path, without using "realpath" +# Usage: +# $(call normalize_path,path/to/../file) +define normalize_path +$(strip $(eval elements :=) \ +$(foreach elem,$(subst /, ,$1), \ + $(if $(filter-out .,$(elem)), \ + $(if $(filter ..,$(elem)), \ + $(eval elements := $(wordlist 2,$(words $(elements)),x $(elements))), \ + $(eval elements := $(elements) $(elem))))) \ +$(subst $(space),/,$(elements))) +endef + # Build commands # =========================================================================== # These are shared by some Makefile.* files. @@ -343,6 +356,11 @@ quiet_cmd_copy = COPY $@ $(obj)/%: $(src)/%_shipped $(call cmd,copy) +# Touch a file +# =========================================================================== +quiet_cmd_touch = TOUCH $(call normalize_path,$@) + cmd_touch = touch $@ + # Commands useful for building a boot image # =========================================================================== # diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 9e35198edbf0..734a102e6b56 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -1,5 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 +# Shared with KVM/arm64. +export CFLAGS_UBSAN_TRAP := $(call cc-option,-fsanitize-trap=undefined,-fsanitize-undefined-trap-on-error) + # Enable available and selected UBSAN features. ubsan-cflags-$(CONFIG_UBSAN_ALIGNMENT) += -fsanitize=alignment ubsan-cflags-$(CONFIG_UBSAN_BOUNDS_STRICT) += -fsanitize=bounds-strict @@ -10,11 +13,12 @@ ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO) += -fsanitize=integer-divide-by-zero ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE) += -fsanitize=unreachable ubsan-cflags-$(CONFIG_UBSAN_BOOL) += -fsanitize=bool ubsan-cflags-$(CONFIG_UBSAN_ENUM) += -fsanitize=enum -ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(call cc-option,-fsanitize-trap=undefined,-fsanitize-undefined-trap-on-error) +ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(CFLAGS_UBSAN_TRAP) export CFLAGS_UBSAN := $(ubsan-cflags-y) ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ + -DINTEGER_WRAP \ -fsanitize-undefined-ignore-overflow-pattern=all \ -fsanitize=signed-integer-overflow \ -fsanitize=unsigned-integer-overflow \ diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index dd289a6725ac..fb8e2c38fbc7 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -14,3 +14,8 @@ cmd_create_randstruct_seed = \ $(obj)/randstruct.seed: $(gen-randstruct-seed) FORCE $(call if_changed,create_randstruct_seed) always-$(CONFIG_RANDSTRUCT) += randstruct.seed + +# integer-wrap: if the .scl file changes, we need to do a full rebuild. +$(obj)/../../include/generated/integer-wrap.h: $(srctree)/scripts/integer-wrap-ignore.scl FORCE + $(call if_changed,touch) +always-$(CONFIG_UBSAN_INTEGER_WRAP) += ../../include/generated/integer-wrap.h diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index e74a01a85070..c77dc40f7689 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -8,6 +8,7 @@ from __future__ import print_function import argparse +import json import re import sys, os import subprocess @@ -37,11 +38,17 @@ class APIElement(object): @desc: textual description of the symbol @ret: (optional) description of any associated return value """ - def __init__(self, proto='', desc='', ret='', attrs=[]): + def __init__(self, proto='', desc='', ret=''): self.proto = proto self.desc = desc self.ret = ret - self.attrs = attrs + + def to_dict(self): + return { + 'proto': self.proto, + 'desc': self.desc, + 'ret': self.ret + } class Helper(APIElement): @@ -51,8 +58,9 @@ class Helper(APIElement): @desc: textual description of the helper function @ret: description of the return value of the helper function """ - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + def __init__(self, proto='', desc='', ret='', attrs=[]): + super().__init__(proto, desc, ret) + self.attrs = attrs self.enum_val = None def proto_break_down(self): @@ -81,6 +89,12 @@ class Helper(APIElement): return res + def to_dict(self): + d = super().to_dict() + d["attrs"] = self.attrs + d.update(self.proto_break_down()) + return d + ATTRS = { '__bpf_fastcall': 'bpf_fastcall' @@ -675,7 +689,7 @@ COMMANDS self.print_elem(command) -class PrinterHelpers(Printer): +class PrinterHelpersHeader(Printer): """ A printer for dumping collected information about helpers as C header to be included from BPF program. @@ -896,6 +910,43 @@ class PrinterHelpers(Printer): print(') = (void *) %d;' % helper.enum_val) print('') + +class PrinterHelpersJSON(Printer): + """ + A printer for dumping collected information about helpers as a JSON file. + @parser: A HeaderParser with Helper objects + """ + + def __init__(self, parser): + self.elements = parser.helpers + self.elem_number_check( + parser.desc_unique_helpers, + parser.define_unique_helpers, + "helper", + "___BPF_FUNC_MAPPER", + ) + + def print_all(self): + helper_dicts = [helper.to_dict() for helper in self.elements] + out_dict = {'helpers': helper_dicts} + print(json.dumps(out_dict, indent=4)) + + +class PrinterSyscallJSON(Printer): + """ + A printer for dumping collected syscall information as a JSON file. + @parser: A HeaderParser with APIElement objects + """ + + def __init__(self, parser): + self.elements = parser.commands + self.elem_number_check(parser.desc_syscalls, parser.enum_syscalls, 'syscall', 'bpf_cmd') + + def print_all(self): + syscall_dicts = [syscall.to_dict() for syscall in self.elements] + out_dict = {'syscall': syscall_dicts} + print(json.dumps(out_dict, indent=4)) + ############################################################################### # If script is launched from scripts/ from kernel tree and can access @@ -905,9 +956,17 @@ script = os.path.abspath(sys.argv[0]) linuxRoot = os.path.dirname(os.path.dirname(script)) bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h') +# target -> output format -> printer printers = { - 'helpers': PrinterHelpersRST, - 'syscall': PrinterSyscallRST, + 'helpers': { + 'rst': PrinterHelpersRST, + 'json': PrinterHelpersJSON, + 'header': PrinterHelpersHeader, + }, + 'syscall': { + 'rst': PrinterSyscallRST, + 'json': PrinterSyscallJSON + }, } argParser = argparse.ArgumentParser(description=""" @@ -917,6 +976,8 @@ rst2man utility. """) argParser.add_argument('--header', action='store_true', help='generate C header file') +argParser.add_argument('--json', action='store_true', + help='generate a JSON') if (os.path.isfile(bpfh)): argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h', default=bpfh) @@ -924,17 +985,35 @@ else: argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h') argParser.add_argument('target', nargs='?', default='helpers', choices=printers.keys(), help='eBPF API target') -args = argParser.parse_args() - -# Parse file. -headerParser = HeaderParser(args.filename) -headerParser.run() -# Print formatted output to standard output. -if args.header: - if args.target != 'helpers': - raise NotImplementedError('Only helpers header generation is supported') - printer = PrinterHelpers(headerParser) -else: - printer = printers[args.target](headerParser) -printer.print_all() +def error_die(message: str): + argParser.print_usage(file=sys.stderr) + print('Error: {}'.format(message), file=sys.stderr) + exit(1) + +def parse_and_dump(): + args = argParser.parse_args() + + # Parse file. + headerParser = HeaderParser(args.filename) + headerParser.run() + + if args.header and args.json: + error_die('Use either --header or --json, not both') + + output_format = 'rst' + if args.header: + output_format = 'header' + elif args.json: + output_format = 'json' + + try: + printer = printers[args.target][output_format](headerParser) + # Print formatted output to standard output. + printer.print_all() + except KeyError: + error_die('Unsupported target/format combination: "{}", "{}"' + .format(args.target, output_format)) + +if __name__ == "__main__": + parse_and_dump() diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index b3b1939ccd19..966813c2573c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4806,7 +4806,7 @@ sub process { } # do not use BUG() or variants - if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) { + if ($line =~ /\b(?!AA_|BUILD_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) { my $msg_level = \&WARN; $msg_level = \&CHK if ($file); &{$msg_level}("AVOID_BUG", @@ -6893,7 +6893,7 @@ sub process { ($extension eq "f" && defined $qualifier && $qualifier !~ /^w/) || ($extension eq "4" && - defined $qualifier && $qualifier !~ /^cc/)) { + defined $qualifier && $qualifier !~ /^c(?:[hlbc]|hR)$/)) { $bad_specifier = $specifier; last; } diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index e383cda05367..231f4a20d617 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -46,8 +46,4 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ -config GCC_PLUGIN_ARM_SSP_PER_TASK - bool - depends on GCC_PLUGINS && ARM - endif diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 320afd3cf8e8..05b14aba41ef 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -66,3 +66,7 @@ quiet_cmd_plugin_cxx_o_c = HOSTCXX $@ $(plugin-objs): $(obj)/%.o: $(src)/%.c FORCE $(call if_changed_dep,plugin_cxx_o_c) + +$(obj)/../../include/generated/gcc-plugins.h: $(plugin-single) $(plugin-multi) FORCE + $(call if_changed,touch) +always-y += ../../include/generated/gcc-plugins.h diff --git a/scripts/gcc-plugins/arm_ssp_per_task_plugin.c b/scripts/gcc-plugins/arm_ssp_per_task_plugin.c deleted file mode 100644 index 7328d037f975..000000000000 --- a/scripts/gcc-plugins/arm_ssp_per_task_plugin.c +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include "gcc-common.h" - -__visible int plugin_is_GPL_compatible; - -static unsigned int canary_offset; - -static unsigned int arm_pertask_ssp_rtl_execute(void) -{ - rtx_insn *insn; - - for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) { - const char *sym; - rtx body; - rtx current; - - /* - * Find a SET insn involving a SYMBOL_REF to __stack_chk_guard - */ - if (!INSN_P(insn)) - continue; - body = PATTERN(insn); - if (GET_CODE(body) != SET || - GET_CODE(SET_SRC(body)) != SYMBOL_REF) - continue; - sym = XSTR(SET_SRC(body), 0); - if (strcmp(sym, "__stack_chk_guard")) - continue; - - /* - * Replace the source of the SET insn with an expression that - * produces the address of the current task's stack canary value - */ - current = gen_reg_rtx(Pmode); - - emit_insn_before(gen_load_tp_hard(current), insn); - - SET_SRC(body) = gen_rtx_PLUS(Pmode, current, - GEN_INT(canary_offset)); - } - return 0; -} - -#define PASS_NAME arm_pertask_ssp_rtl - -#define NO_GATE -#include "gcc-generate-rtl-pass.h" - -#if BUILDING_GCC_VERSION >= 9000 -static bool no(void) -{ - return false; -} - -static void arm_pertask_ssp_start_unit(void *gcc_data, void *user_data) -{ - targetm.have_stack_protect_combined_set = no; - targetm.have_stack_protect_combined_test = no; -} -#endif - -__visible int plugin_init(struct plugin_name_args *plugin_info, - struct plugin_gcc_version *version) -{ - const char * const plugin_name = plugin_info->base_name; - const int argc = plugin_info->argc; - const struct plugin_argument *argv = plugin_info->argv; - int i; - - if (!plugin_default_version_check(version, &gcc_version)) { - error(G_("incompatible gcc/plugin versions")); - return 1; - } - - for (i = 0; i < argc; ++i) { - if (!strcmp(argv[i].key, "disable")) - return 0; - - /* all remaining options require a value */ - if (!argv[i].value) { - error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), - plugin_name, argv[i].key); - return 1; - } - - if (!strcmp(argv[i].key, "offset")) { - canary_offset = atoi(argv[i].value); - continue; - } - error(G_("unknown option '-fplugin-arg-%s-%s'"), - plugin_name, argv[i].key); - return 1; - } - - PASS_INFO(arm_pertask_ssp_rtl, "expand", 1, PASS_POS_INSERT_AFTER); - - register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, - NULL, &arm_pertask_ssp_rtl_pass_info); - -#if BUILDING_GCC_VERSION >= 9000 - register_callback(plugin_info->base_name, PLUGIN_START_UNIT, - arm_pertask_ssp_start_unit, NULL); -#endif - - return 0; -} diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 5694df3da2e9..971a1908a8cc 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -344,29 +344,13 @@ static int relayout_struct(tree type) shuffle(type, (tree *)newtree, shuffle_length); - /* - * set up a bogus anonymous struct field designed to error out on unnamed struct initializers - * as gcc provides no other way to detect such code - */ - list = make_node(FIELD_DECL); - TREE_CHAIN(list) = newtree[0]; - TREE_TYPE(list) = void_type_node; - DECL_SIZE(list) = bitsize_zero_node; - DECL_NONADDRESSABLE_P(list) = 1; - DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node; - DECL_SIZE_UNIT(list) = size_zero_node; - DECL_FIELD_OFFSET(list) = size_zero_node; - DECL_CONTEXT(list) = type; - // to satisfy the constify plugin - TREE_READONLY(list) = 1; - for (i = 0; i < num_fields - 1; i++) TREE_CHAIN(newtree[i]) = newtree[i+1]; TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE; main_variant = TYPE_MAIN_VARIANT(type); for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) { - TYPE_FIELDS(variant) = list; + TYPE_FIELDS(variant) = newtree[0]; TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant)); TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant)); TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant)); |