diff options
Diffstat (limited to 'scripts')
60 files changed, 1155 insertions, 288 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 9a15fbf66aa1..83a1637417e5 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -119,25 +119,21 @@ as-instr = $(call try-run,\ __cc-option = $(call try-run,\ $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) -# Do not attempt to build with gcc plugins during cc-option tests. -# (And this uses delayed resolution so the flags will be up to date.) -CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) - # cc-option # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) cc-option = $(call __cc-option, $(CC),\ - $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2)) + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2)) # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) cc-option-yn = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) # cc-disable-warning # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) cc-disable-warning = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) # cc-ifversion # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) diff --git a/scripts/Makefile b/scripts/Makefile index 95ecf970c74c..bc018e4b733e 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -3,14 +3,14 @@ # scripts contains sources for various helper programs used throughout # the kernel for the build process. -always-$(CONFIG_BUILD_BIN2C) += bin2c -always-$(CONFIG_KALLSYMS) += kallsyms -always-$(BUILD_C_RECORDMCOUNT) += recordmcount -always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable -always-$(CONFIG_ASN1) += asn1_compiler -always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file -always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert -always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert +hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c +hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms +hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount +hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable +hostprogs-always-$(CONFIG_ASN1) += asn1_compiler +hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file +hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert +hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include @@ -26,8 +26,6 @@ HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED HOSTLDLIBS_sorttable = -lpthread endif -hostprogs := $(always-y) $(always-m) - # The following programs are only built on demand hostprogs += unifdef diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 2e8810b7e5ed..a467b9323442 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -45,12 +45,15 @@ include $(kbuild-file) include scripts/Makefile.lib -# Do not include host rules unless needed -ifneq ($(hostprogs)$(hostcxxlibs-y)$(hostcxxlibs-m),) +# Do not include hostprogs rules unless needed. +# $(sort ...) is used here to remove duplicated words and excessive spaces. +hostprogs := $(sort $(hostprogs)) +ifneq ($(hostprogs),) include scripts/Makefile.host endif # Do not include userprogs rules unless needed. +# $(sort ...) is used here to remove duplicated words and excessive spaces. userprogs := $(sort $(userprogs)) ifneq ($(userprogs),) include scripts/Makefile.userprogs @@ -252,9 +255,9 @@ cmd_gen_ksymdeps = \ endif define rule_cc_o_c - $(call cmd,checksrc) $(call cmd_and_fixdep,cc_o_c) $(call cmd,gen_ksymdeps) + $(call cmd,checksrc) $(call cmd,checkdoc) $(call cmd,objtool) $(call cmd,modversions_c) @@ -277,8 +280,8 @@ endif # Built-in and composite module parts $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE - $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) cmd_mod = { \ echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \ @@ -515,15 +518,13 @@ existing-targets := $(wildcard $(sort $(targets))) -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -ifdef building_out_of_srctree # Create directories for object files if they do not exist -obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets)))) +obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets)))) # If targets exist, their directories apparently exist. Skip mkdir. existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets)))) obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs))) ifneq ($(obj-dirs),) $(shell mkdir -p $(obj-dirs)) endif -endif .PHONY: $(PHONY) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index e2c76122319d..d9e0ceace6a6 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -27,10 +27,15 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) # build a list of files to remove, usually relative to the current # directory -__clean-files := $(extra-y) $(extra-m) $(extra-) \ - $(always) $(always-y) $(always-m) $(always-) $(targets) $(clean-files) \ - $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs) \ - $(hostcxxlibs-y) $(hostcxxlibs-m) +__clean-files := \ + $(clean-files) $(targets) $(hostprogs) $(userprogs) \ + $(extra-y) $(extra-m) $(extra-) \ + $(always-y) $(always-m) $(always-) \ + $(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \ + $(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-) + +# deprecated +__clean-files += $(always) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 5f7df50cfe7a..952e46876329 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -33,6 +33,8 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -DSTACKLEAK_PLUGIN gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) ifdef CONFIG_GCC_PLUGIN_STACKLEAK DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable endif diff --git a/scripts/Makefile.host b/scripts/Makefile.host index c8a4a033dc3e..278b4d6ac945 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -38,39 +38,31 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE # Will compile qconf as a C++ program, and menu as a C program. # They are linked as C++ code to the executable qconf -__hostprogs := $(sort $(hostprogs)) -host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m)) - # C code # Executables compiled from a single .c file -host-csingle := $(foreach m,$(__hostprogs), \ +host-csingle := $(foreach m,$(hostprogs), \ $(if $($(m)-objs)$($(m)-cxxobjs),,$(m))) # C executables linked based on several .o files -host-cmulti := $(foreach m,$(__hostprogs),\ +host-cmulti := $(foreach m,$(hostprogs),\ $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) # Object (.o) files compiled from .c files -host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs))) +host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs))) # C++ code # C++ executables compiled from at least one .cc file # and zero or more .c files -host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m))) +host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m))) # C++ Object (.o) files compiled from .cc files host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) -# Object (.o) files used by the shared libaries -host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs)))) - host-csingle := $(addprefix $(obj)/,$(host-csingle)) host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) -host-cxxshlib := $(addprefix $(obj)/,$(host-cxxshlib)) -host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs)) ##### # Handle options to gcc. Support building with separate output directory @@ -136,25 +128,5 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE $(call if_changed_dep,host-cxxobjs) -# Compile .c file, create position independent .o file -# Note that plugin capable gcc versions can be either C or C++ based -# therefore plugin source files have to be compilable in both C and C++ mode. -# This is why a C++ compiler is invoked on a .c file. -# host-cxxshobjs -> .o -quiet_cmd_host-cxxshobjs = HOSTCXX -fPIC $@ - cmd_host-cxxshobjs = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $< -$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE - $(call if_changed_dep,host-cxxshobjs) - -# Link a shared library, based on position independent .o files -# *.o -> .so shared library (host-cxxshlib) -quiet_cmd_host-cxxshlib = HOSTLLD -shared $@ - cmd_host-cxxshlib = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \ - $(addprefix $(obj)/, $($(target-stem)-objs)) \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem).so) -$(host-cxxshlib): FORCE - $(call if_changed,host-cxxshlib) -$(call multi_depend, $(host-cxxshlib), .so, -objs) - -targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\ - $(host-cxxmulti) $(host-cxxobjs) $(host-cxxshlib) $(host-cxxshobjs) +targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ + $(host-cxxmulti) $(host-cxxobjs) diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 03757cc60e06..f4beee1b0013 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -44,7 +44,8 @@ else endif CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ - -mllvm -hwasan-instrument-stack=0 \ + -mllvm -hwasan-instrument-stack=$(CONFIG_KASAN_STACK) \ + -mllvm -hwasan-use-short-granules=0 \ $(instrumentation_flags) endif # CONFIG_KASAN_SW_TAGS diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov index 52b113302443..67e8cfe3474b 100644 --- a/scripts/Makefile.kcov +++ b/scripts/Makefile.kcov @@ -1,10 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -ifdef CONFIG_KCOV - kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so export CFLAGS_KCOV := $(kcov-flags-y) - -endif diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan index bd4da1af5953..c50f27b3ac56 100644 --- a/scripts/Makefile.kcsan +++ b/scripts/Makefile.kcsan @@ -1,12 +1,10 @@ # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_KCSAN - # GCC and Clang accept backend options differently. Do not wrap in cc-option, # because Clang accepts "--param" even if it is unused. ifdef CONFIG_CC_IS_CLANG cc-param = -mllvm -$(1) else -cc-param = --param -$(1) +cc-param = --param $(1) endif # Keep most options here optional, to allow enabling more compilers if absence @@ -15,5 +13,3 @@ CFLAGS_KCSAN := -fsanitize=thread \ $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit=0) -fno-optimize-sibling-calls) \ $(call cc-option,$(call cc-param,tsan-instrument-read-before-write=1)) \ $(call cc-param,tsan-distinguish-volatile=1) - -endif # CONFIG_KCSAN diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 916b2f7f7098..3d599716940c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -68,6 +68,17 @@ real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) always-y += $(always-m) +# hostprogs-always-y += foo +# ... is a shorthand for +# hostprogs += foo +# always-y += foo +hostprogs += $(hostprogs-always-y) $(hostprogs-always-m) +always-y += $(hostprogs-always-y) $(hostprogs-always-m) + +# userprogs-always-y is likewise. +userprogs += $(userprogs-always-y) $(userprogs-always-m) +always-y += $(userprogs-always-y) $(userprogs-always-m) + # DTB # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built extra-y += $(dtb-y) @@ -111,12 +122,14 @@ basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) -orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ - $(ccflags-y) $(CFLAGS_$(target-stem).o) -_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), $(orig_c_flags)) -orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \ - $(asflags-y) $(AFLAGS_$(target-stem).o) -_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), $(orig_a_flags)) +_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(ccflags-remove-y), \ + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ + $(CFLAGS_$(target-stem).o)) +_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(asflags-remove-y), \ + $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ + $(AFLAGS_$(target-stem).o)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds) # @@ -303,8 +316,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE $(call if_changed,dt_S_dtb) quiet_cmd_dtc = DTC $@ -cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ - $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ +cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(DTC) -O $(patsubst .%,%,$(suffix $@)) -o $@ -b 0 \ $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ @@ -413,6 +425,28 @@ quiet_cmd_xzkern = XZKERN $@ quiet_cmd_xzmisc = XZMISC $@ cmd_xzmisc = cat $(real-prereqs) | $(XZ) --check=crc32 --lzma2=dict=1MiB > $@ +# ZSTD +# --------------------------------------------------------------------------- +# Appends the uncompressed size of the data using size_append. The .zst +# format has the size information available at the beginning of the file too, +# but it's in a more complex format and it's good to avoid changing the part +# of the boot code that reads the uncompressed size. +# +# Note that the bytes added by size_append will make the zstd tool think that +# the file is corrupt. This is expected. +# +# zstd uses a maximum window size of 8 MB. zstd22 uses a maximum window size of +# 128 MB. zstd22 is used for kernel compression because it is decompressed in a +# single pass, so zstd doesn't need to allocate a window buffer. When streaming +# decompression is used, like initramfs decompression, zstd22 should likely not +# be used because it would require zstd to allocate a 128 MB buffer. + +quiet_cmd_zstd = ZSTD $@ + cmd_zstd = { cat $(real-prereqs) | $(ZSTD) -19; $(size_append); } > $@ + +quiet_cmd_zstd22 = ZSTD22 $@ + cmd_zstd22 = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@ + # ASM offsets # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 3651cbf6ad49..f54b6ac37ac2 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -124,9 +124,6 @@ existing-targets := $(wildcard $(sort $(targets))) -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -PHONY += FORCE -FORCE: - endif .PHONY: $(PHONY) diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 5b15bc425ec9..27348029b2b8 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_UBSAN - ifdef CONFIG_UBSAN_ALIGNMENT CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment) endif @@ -26,4 +24,3 @@ endif # -fsanitize=* options makes GCC less smart than usual and # increase number of 'maybe-uninitialized false-positives CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized) -endif diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index 290dd27d2809..eeb6a38c5551 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -2,5 +2,4 @@ # # fixdep: used to generate dependency information during build process -hostprogs := fixdep -always-y := $(hostprogs) +hostprogs-always-y += fixdep diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter index 8c965f6a9881..d7ca46c612b3 100755 --- a/scripts/bloat-o-meter +++ b/scripts/bloat-o-meter @@ -26,6 +26,8 @@ def getsizes(file, format): sym = {} with os.popen("nm --size-sort " + file) as f: for line in f: + if line.startswith("\n") or ":" in line: + continue size, type, name = line.split() if type in format: # strip generated symbols diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index 91fa668fa860..5bfa448b4704 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -404,6 +404,7 @@ class PrinterHelpers(Printer): type_fwds = [ 'struct bpf_fib_lookup', + 'struct bpf_sk_lookup', 'struct bpf_perf_event_data', 'struct bpf_perf_event_value', 'struct bpf_pidns_info', @@ -421,6 +422,12 @@ class PrinterHelpers(Printer): 'struct sockaddr', 'struct tcphdr', 'struct seq_file', + 'struct tcp6_sock', + 'struct tcp_sock', + 'struct tcp_timewait_sock', + 'struct tcp_request_sock', + 'struct udp6_sock', + 'struct task_struct', 'struct __sk_buff', 'struct sk_msg_md', @@ -444,6 +451,7 @@ class PrinterHelpers(Printer): 'struct bpf_perf_event_data', 'struct bpf_perf_event_value', 'struct bpf_pidns_info', + 'struct bpf_sk_lookup', 'struct bpf_sock', 'struct bpf_sock_addr', 'struct bpf_sock_ops', @@ -458,6 +466,12 @@ class PrinterHelpers(Printer): 'struct sockaddr', 'struct tcphdr', 'struct seq_file', + 'struct tcp6_sock', + 'struct tcp_sock', + 'struct tcp_timewait_sock', + 'struct tcp_request_sock', + 'struct udp6_sock', + 'struct task_struct', } mapped_types = { 'u8': '__u8', @@ -475,6 +489,11 @@ class PrinterHelpers(Printer): 'struct sk_msg_buff': 'struct sk_msg_md', 'struct xdp_buff': 'struct xdp_md', } + # Helpers overloaded for different context types. + overloaded_helpers = [ + 'bpf_get_socket_cookie', + 'bpf_sk_assign', + ] def print_header(self): header = '''\ @@ -531,7 +550,7 @@ class PrinterHelpers(Printer): for i, a in enumerate(proto['args']): t = a['type'] n = a['name'] - if proto['name'] == 'bpf_get_socket_cookie' and i == 0: + if proto['name'] in self.overloaded_helpers and i == 0: t = 'void' n = 'ctx' one_arg = '{}{}'.format(comma, self.map_type(t)) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4c820607540b..2cbeae6d9aee 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -59,7 +59,7 @@ my $spelling_file = "$D/spelling.txt"; my $codespell = 0; my $codespellfile = "/usr/share/codespell/dictionary.txt"; my $conststructsfile = "$D/const_structs.checkpatch"; -my $typedefsfile = ""; +my $typedefsfile; my $color = "auto"; my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE # git output parsing needs US English output, so first set backtick child process LANGUAGE @@ -588,6 +588,8 @@ our @mode_permission_funcs = ( ["__ATTR", 2], ); +my $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; + #Create a search pattern for all these functions to speed up a loop below our $mode_perms_search = ""; foreach my $entry (@mode_permission_funcs) { @@ -756,7 +758,7 @@ sub read_words { next; } - $$wordsRef .= '|' if ($$wordsRef ne ""); + $$wordsRef .= '|' if (defined $$wordsRef); $$wordsRef .= $line; } close($file); @@ -766,16 +768,18 @@ sub read_words { return 0; } -my $const_structs = ""; -read_words(\$const_structs, $conststructsfile) - or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; +my $const_structs; +if (show_type("CONST_STRUCT")) { + read_words(\$const_structs, $conststructsfile) + or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; +} -my $typeOtherTypedefs = ""; -if (length($typedefsfile)) { +if (defined($typedefsfile)) { + my $typeOtherTypedefs; read_words(\$typeOtherTypedefs, $typedefsfile) or warn "No additional types will be considered - file '$typedefsfile': $!\n"; + $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); } -$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); sub build_types { my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; @@ -840,7 +844,6 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; our $declaration_macros = qr{(?x: (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| - (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(| (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( )}; @@ -3311,6 +3314,42 @@ sub process { } } +# check for repeated words separated by a single space + if ($rawline =~ /^\+/) { + while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { + + my $first = $1; + my $second = $2; + + if ($first =~ /(?:struct|union|enum)/) { + pos($rawline) += length($first) + length($second) + 1; + next; + } + + next if ($first ne $second); + next if ($first eq 'long'); + + if (WARN("REPEATED_WORD", + "Possible repeated word: '$first'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; + } + } + + # if it's a repeated word on consecutive lines in a comment block + if ($prevline =~ /$;+\s*$/ && + $prevrawline =~ /($word_pattern)\s*$/) { + my $last_word = $1; + if ($rawline =~ /^\+\s*\*\s*$last_word /) { + if (WARN("REPEATED_WORD", + "Possible repeated word: '$last_word'\n" . $hereprev) && + $fix) { + $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; + } + } + } + } + # check for space before tabs. if ($rawline =~ /^\+/ && $rawline =~ / \t/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; @@ -5021,8 +5060,30 @@ sub process { my ($s, $c) = ($stat, $cond); if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { - ERROR("ASSIGN_IN_IF", - "do not use assignment in if condition\n" . $herecurr); + if (ERROR("ASSIGN_IN_IF", + "do not use assignment in if condition\n" . $herecurr) && + $fix && $perl_version_ok) { + if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { + my $space = $1; + my $not = $2; + my $statement = $3; + my $assigned = $4; + my $test = $8; + my $against = $9; + my $brace = $15; + fix_delete_line($fixlinenr, $rawline); + fix_insert_line($fixlinenr, "$space$statement;"); + my $newline = "${space}if ("; + $newline .= '!' if defined($not); + $newline .= '(' if (defined $not && defined($test) && defined($against)); + $newline .= "$assigned"; + $newline .= " $test $against" if (defined($test) && defined($against)); + $newline .= ')' if (defined $not && defined($test) && defined($against)); + $newline .= ')'; + $newline .= " {" if (defined($brace)); + fix_insert_line($fixlinenr + 1, $newline); + } + } } # Find out what is on the end of the line after the @@ -5903,8 +5964,7 @@ sub process { my $barriers = qr{ mb| rmb| - wmb| - read_barrier_depends + wmb }x; my $barrier_stems = qr{ mb__before_atomic| @@ -5953,12 +6013,6 @@ sub process { } } -# check for smp_read_barrier_depends and read_barrier_depends - if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { - WARN("READ_BARRIER_DEPENDS", - "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); - } - # check of hardware specific defines if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { CHK("ARCH_DEFINES", @@ -6330,8 +6384,7 @@ sub process { if (defined $cond) { substr($s, 0, length($cond), ''); } - if ($s =~ /^\s*;/ && - $function_name ne 'uninitialized_var') + if ($s =~ /^\s*;/) { WARN("AVOID_EXTERNS", "externs should be avoided in .c files\n" . $herecurr); @@ -6350,17 +6403,13 @@ sub process { } # check for function declarations that have arguments without identifier names -# while avoiding uninitialized_var(x) if (defined $stat && - $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && - (!defined($1) || - (defined($1) && $1 ne "uninitialized_var")) && - $2 ne "void") { - my $args = trim($2); + $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && + $1 ne "void") { + my $args = trim($1); while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { my $arg = trim($1); - if ($arg =~ /^$Type$/ && - $arg !~ /enum\s+$Ident$/) { + if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { WARN("FUNCTION_ARGUMENTS", "function definition argument '$arg' should also have an identifier name\n" . $herecurr); } @@ -6478,6 +6527,12 @@ sub process { } } +# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) + if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^CONFIG_/) { + WARN("IS_ENABLED_CONFIG", + "IS_ENABLED($1) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr); + } + # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { my $config = $1; @@ -6488,31 +6543,6 @@ sub process { } } -# check for case / default statements not preceded by break/fallthrough/switch - if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { - my $has_break = 0; - my $has_statement = 0; - my $count = 0; - my $prevline = $linenr; - while ($prevline > 1 && ($file || $count < 3) && !$has_break) { - $prevline--; - my $rline = $rawlines[$prevline - 1]; - my $fline = $lines[$prevline - 1]; - last if ($fline =~ /^\@\@/); - next if ($fline =~ /^\-/); - next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); - $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); - next if ($fline =~ /^.[\s$;]*$/); - $has_statement = 1; - $count++; - $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); - } - if (!$has_break && $has_statement) { - WARN("MISSING_BREAK", - "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); - } - } - # check for /* fallthrough */ like comment, prefer fallthrough; my @fallthroughs = ( 'fallthrough', @@ -6628,7 +6658,8 @@ sub process { # check for various structs that are normally const (ops, kgdb, device_tree) # and avoid what seem like struct definitions 'struct foo {' - if ($line !~ /\bconst\b/ && + if (defined($const_structs) && + $line !~ /\bconst\b/ && $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { WARN("CONST_STRUCT", "struct $1 should normally be const\n" . $herecurr); diff --git a/scripts/coccinelle/api/device_attr_show.cocci b/scripts/coccinelle/api/device_attr_show.cocci new file mode 100644 index 000000000000..d8ec4bb8ac41 --- /dev/null +++ b/scripts/coccinelle/api/device_attr_show.cocci @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// From Documentation/filesystems/sysfs.txt: +/// show() must not use snprintf() when formatting the value to be +/// returned to user space. If you can guarantee that an overflow +/// will never happen you can use sprintf() otherwise you must use +/// scnprintf(). +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// + +virtual report +virtual org +virtual context +virtual patch + +@r depends on !patch@ +identifier show, dev, attr, buf; +position p; +@@ + +ssize_t show(struct device *dev, struct device_attribute *attr, char *buf) +{ + <... +* return snprintf@p(...); + ...> +} + +@rp depends on patch@ +identifier show, dev, attr, buf; +@@ + +ssize_t show(struct device *dev, struct device_attribute *attr, char *buf) +{ + <... + return +- snprintf ++ scnprintf + (...); + ...> +} + +@script: python depends on report@ +p << r.p; +@@ + +coccilib.report.print_report(p[0], "WARNING: use scnprintf or sprintf") + +@script: python depends on org@ +p << r.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING: use scnprintf or sprintf") diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci index 19f2645e6076..3c6dc5469ee4 100644 --- a/scripts/coccinelle/api/kstrdup.cocci +++ b/scripts/coccinelle/api/kstrdup.cocci @@ -66,7 +66,7 @@ position p1,p2; * x = strlen(from) + 1; ... when != \( x = E1 \| from = E1 \) -* to = \(kmalloc@p1\|kzalloc@p2\)(x,flag); +* to = \(kmalloc@p1\|kzalloc@p1\)(x,flag); ... when != \(x = E2 \| from = E2 \| to = E2 \) if (to==NULL || ...) S ... when != \(x = E3 \| from = E3 \| to = E3 \) diff --git a/scripts/coccinelle/api/kzfree.cocci b/scripts/coccinelle/api/kzfree.cocci new file mode 100644 index 000000000000..33625bd7cec9 --- /dev/null +++ b/scripts/coccinelle/api/kzfree.cocci @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Use kzfree, kvfree_sensitive rather than memset or +/// memzero_explicit followed by kfree +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// +// Keywords: kzfree, kvfree_sensitive +// + +virtual context +virtual patch +virtual org +virtual report + +@initialize:python@ +@@ +# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access +filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive']) + +def relevant(p): + return not (filter & {el.current_element for el in p}) + +@cond@ +position ok; +@@ + +if (...) + \(memset@ok\|memzero_explicit@ok\)(...); + +@r depends on !patch forall@ +expression E; +position p : script:python() { relevant(p) }; +position m != cond.ok; +type T; +@@ + +( +* memset@m((T)E, 0, ...); +| +* memzero_explicit@m((T)E, ...); +) + ... when != E + when strict +* \(kfree\|vfree\|kvfree\)(E)@p; + +@rp_memzero depends on patch@ +expression E, size; +position p : script:python() { relevant(p) }; +position m != cond.ok; +type T; +@@ + +- memzero_explicit@m((T)E, size); + ... when != E + when strict +// TODO: uncomment when kfree_sensitive will be merged. +// Only this case is commented out because developers +// may not like patches like this since kzfree uses memset +// internally (not memzero_explicit). +//( +//- kfree(E)@p; +//+ kfree_sensitive(E); +//| +- \(vfree\|kvfree\)(E)@p; ++ kvfree_sensitive(E, size); +//) + +@rp_memset depends on patch@ +expression E, size; +position p : script:python() { relevant(p) }; +position m != cond.ok; +type T; +@@ + +- memset@m((T)E, 0, size); + ... when != E + when strict +( +- kfree(E)@p; ++ kzfree(E); +| +- \(vfree\|kvfree\)(E)@p; ++ kvfree_sensitive(E, size); +) + +@script:python depends on report@ +p << r.p; +@@ + +coccilib.report.print_report(p[0], + "WARNING: opportunity for kzfree/kvfree_sensitive") + +@script:python depends on org@ +p << r.p; +@@ + +coccilib.org.print_todo(p[0], + "WARNING: opportunity for kzfree/kvfree_sensitive") diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci index c809ab10bbce..e01e95108405 100644 --- a/scripts/coccinelle/api/memdup_user.cocci +++ b/scripts/coccinelle/api/memdup_user.cocci @@ -15,12 +15,22 @@ virtual context virtual org virtual report +@initialize:python@ +@@ +filter = frozenset(['memdup_user', 'vmemdup_user']) + +def relevant(p): + return not (filter & {el.current_element for el in p}) + @depends on patch@ expression from,to,size; identifier l1,l2; +position p : script:python() { relevant(p) }; @@ -- to = \(kmalloc\|kzalloc\)(size,GFP_KERNEL); +- to = \(kmalloc@p\|kzalloc@p\) +- (size,\(GFP_KERNEL\|GFP_USER\| +- \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\)); + to = memdup_user(from,size); if ( - to==NULL @@ -37,13 +47,49 @@ identifier l1,l2; - ...+> - } +@depends on patch@ +expression from,to,size; +identifier l1,l2; +position p : script:python() { relevant(p) }; +@@ + +- to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\)); ++ to = vmemdup_user(from,size); + if ( +- to==NULL ++ IS_ERR(to) + || ...) { + <+... when != goto l1; +- -ENOMEM ++ PTR_ERR(to) + ...+> + } +- if (copy_from_user(to, from, size) != 0) { +- <+... when != goto l2; +- -EFAULT +- ...+> +- } + @r depends on !patch@ expression from,to,size; -position p; +position p : script:python() { relevant(p) }; statement S1,S2; @@ -* to = \(kmalloc@p\|kzalloc@p\)(size,GFP_KERNEL); +* to = \(kmalloc@p\|kzalloc@p\) + (size,\(GFP_KERNEL\|GFP_USER\| + \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\)); + if (to==NULL || ...) S1 + if (copy_from_user(to, from, size) != 0) + S2 + +@rv depends on !patch@ +expression from,to,size; +position p : script:python() { relevant(p) }; +statement S1,S2; +@@ + +* to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\)); if (to==NULL || ...) S1 if (copy_from_user(to, from, size) != 0) S2 @@ -59,3 +105,15 @@ p << r.p; @@ coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user") + +@script:python depends on org@ +p << rv.p; +@@ + +coccilib.org.print_todo(p[0], "WARNING opportunity for vmemdup_user") + +@script:python depends on report@ +p << rv.p; +@@ + +coccilib.report.print_report(p[0], "WARNING opportunity for vmemdup_user") diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci index 3357bf4dbd7c..da80050b91ff 100644 --- a/scripts/coccinelle/free/devm_free.cocci +++ b/scripts/coccinelle/free/devm_free.cocci @@ -89,7 +89,7 @@ position p; ( kfree@p(x) | - kzfree@p(x) + kfree_sensitive@p(x) | krealloc@p(x, ...) | @@ -112,7 +112,7 @@ position p != safe.p; ( * kfree@p(x) | -* kzfree@p(x) +* kfree_sensitive@p(x) | * krealloc@p(x, ...) | diff --git a/scripts/coccinelle/free/ifnullfree.cocci b/scripts/coccinelle/free/ifnullfree.cocci index b3290c4ee239..2045391e36a0 100644 --- a/scripts/coccinelle/free/ifnullfree.cocci +++ b/scripts/coccinelle/free/ifnullfree.cocci @@ -21,7 +21,7 @@ expression E; ( kfree(E); | - kzfree(E); + kfree_sensitive(E); | debugfs_remove(E); | @@ -42,7 +42,7 @@ position p; @@ * if (E != NULL) -* \(kfree@p\|kzfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\| +* \(kfree@p\|kfree_sensitive@p\|debugfs_remove@p\|debugfs_remove_recursive@p\| * usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\| * dma_pool_destroy@p\)(E); diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci index e9d50e718e46..168568386034 100644 --- a/scripts/coccinelle/free/kfree.cocci +++ b/scripts/coccinelle/free/kfree.cocci @@ -24,7 +24,7 @@ position p1; ( * kfree@p1(E) | -* kzfree@p1(E) +* kfree_sensitive@p1(E) ) @print expression@ @@ -68,7 +68,7 @@ while (1) { ... ( * kfree@ok(E) | -* kzfree@ok(E) +* kfree_sensitive@ok(E) ) ... when != break; when != goto l; @@ -86,7 +86,7 @@ position free.p1!=loop.ok,p2!={print.p,sz.p}; ( * kfree@p1(E,...) | -* kzfree@p1(E,...) +* kfree_sensitive@p1(E,...) ) ... ( diff --git a/scripts/coccinelle/free/kfreeaddr.cocci b/scripts/coccinelle/free/kfreeaddr.cocci index cfaf308328d8..142af6337a04 100644 --- a/scripts/coccinelle/free/kfreeaddr.cocci +++ b/scripts/coccinelle/free/kfreeaddr.cocci @@ -20,7 +20,7 @@ position p; ( * kfree@p(&e->f) | -* kzfree@p(&e->f) +* kfree_sensitive@p(&e->f) ) @script:python depends on org@ diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci index 99e93a6c2e24..cbf1614163cb 100644 --- a/scripts/coccinelle/misc/add_namespace.cocci +++ b/scripts/coccinelle/misc/add_namespace.cocci @@ -6,6 +6,7 @@ /// add a missing namespace tag to a module source file. /// +virtual nsdeps virtual report @has_ns_import@ @@ -16,10 +17,15 @@ MODULE_IMPORT_NS(ns); // Add missing imports, but only adjacent to a MODULE_LICENSE statement. // That ensures we are adding it only to the main module source file. -@do_import depends on !has_ns_import@ +@do_import depends on !has_ns_import && nsdeps@ declarer name MODULE_LICENSE; expression license; identifier virtual.ns; @@ MODULE_LICENSE(license); + MODULE_IMPORT_NS(ns); + +// Dummy rule for report mode that would otherwise be empty and make spatch +// fail ("No rules apply.") +@script:python depends on report@ +@@ diff --git a/scripts/coccinelle/misc/array_size_dup.cocci b/scripts/coccinelle/misc/array_size_dup.cocci new file mode 100644 index 000000000000..fbc2ba1401d7 --- /dev/null +++ b/scripts/coccinelle/misc/array_size_dup.cocci @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Check for array_size(), array3_size(), struct_size() duplicates. +/// These patterns are detected: +/// 1. An opencoded expression is used before array_size() to compute the same size +/// 2. An opencoded expression is used after array_size() to compute the same size +/// From security point of view only first case is relevant. These functions +/// perform arithmetic overflow check. Thus, if we use an opencoded expression +/// before a call to the *_size() function we can miss an overflow. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers --no-loops + +virtual context +virtual report +virtual org + +@as@ +expression E1, E2; +@@ + +array_size(E1, E2) + +@as_next@ +expression subE1 <= as.E1; +expression subE2 <= as.E2; +expression as.E1, as.E2, E3; +assignment operator aop; +position p1, p2; +@@ + +* E1 * E2@p1 + ... when != \(subE1\|subE2\) aop E3 + when != &\(subE1\|subE2\) +* array_size(E1, E2)@p2 + +@script:python depends on report@ +p1 << as_next.p1; +p2 << as_next.p2; +@@ + +msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line) +coccilib.report.print_report(p1[0], msg) + +@script:python depends on org@ +p1 << as_next.p1; +p2 << as_next.p2; +@@ + +msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line) +coccilib.org.print_todo(p1[0], msg) + +@as_prev@ +expression subE1 <= as.E1; +expression subE2 <= as.E2; +expression as.E1, as.E2, E3; +assignment operator aop; +position p1, p2; +@@ + +* array_size(E1, E2)@p1 + ... when != \(subE1\|subE2\) aop E3 + when != &\(subE1\|subE2\) +* E1 * E2@p2 + +@script:python depends on report@ +p1 << as_prev.p1; +p2 << as_prev.p2; +@@ + +msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line) +coccilib.report.print_report(p2[0], msg) + +@script:python depends on org@ +p1 << as_prev.p1; +p2 << as_prev.p2; +@@ + +msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line) +coccilib.org.print_todo(p2[0], msg) + +@as3@ +expression E1, E2, E3; +@@ + +array3_size(E1, E2, E3) + +@as3_next@ +expression subE1 <= as3.E1; +expression subE2 <= as3.E2; +expression subE3 <= as3.E3; +expression as3.E1, as3.E2, as3.E3, E4; +assignment operator aop; +position p1, p2; +@@ + +* E1 * E2 * E3@p1 + ... when != \(subE1\|subE2\|subE3\) aop E4 + when != &\(subE1\|subE2\|subE3\) +* array3_size(E1, E2, E3)@p2 + +@script:python depends on report@ +p1 << as3_next.p1; +p2 << as3_next.p2; +@@ + +msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line) +coccilib.report.print_report(p1[0], msg) + +@script:python depends on org@ +p1 << as3_next.p1; +p2 << as3_next.p2; +@@ + +msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line) +coccilib.org.print_todo(p1[0], msg) + +@as3_prev@ +expression subE1 <= as3.E1; +expression subE2 <= as3.E2; +expression subE3 <= as3.E3; +expression as3.E1, as3.E2, as3.E3, E4; +assignment operator aop; +position p1, p2; +@@ + +* array3_size(E1, E2, E3)@p1 + ... when != \(subE1\|subE2\|subE3\) aop E4 + when != &\(subE1\|subE2\|subE3\) +* E1 * E2 * E3@p2 + +@script:python depends on report@ +p1 << as3_prev.p1; +p2 << as3_prev.p2; +@@ + +msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line) +coccilib.report.print_report(p2[0], msg) + +@script:python depends on org@ +p1 << as3_prev.p1; +p2 << as3_prev.p2; +@@ + +msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line) +coccilib.org.print_todo(p2[0], msg) + +@ss@ +expression E1, E2, E3; +@@ + +struct_size(E1, E2, E3) + +@ss_next@ +expression subE3 <= ss.E3; +expression ss.E1, ss.E2, ss.E3, E4; +assignment operator aop; +position p1, p2; +@@ + +* E1 * E2 + E3@p1 + ... when != subE3 aop E4 + when != &subE3 +* struct_size(E1, E2, E3)@p2 + +@script:python depends on report@ +p1 << ss_next.p1; +p2 << ss_next.p2; +@@ + +msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line) +coccilib.report.print_report(p1[0], msg) + +@script:python depends on org@ +p1 << ss_next.p1; +p2 << ss_next.p2; +@@ + +msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line) +coccilib.org.print_todo(p1[0], msg) + +@ss_prev@ +expression subE3 <= ss.E3; +expression ss.E1, ss.E2, ss.E3, E4; +assignment operator aop; +position p1, p2; +@@ + +* struct_size(E1, E2, E3)@p1 + ... when != subE3 aop E4 + when != &subE3 +* E1 * E2 + E3@p2 + +@script:python depends on report@ +p1 << ss_prev.p1; +p2 << ss_prev.p2; +@@ + +msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line) +coccilib.report.print_report(p2[0], msg) + +@script:python depends on org@ +p1 << ss_prev.p1; +p2 << ss_prev.p2; +@@ + +msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line) +coccilib.org.print_todo(p2[0], msg) diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch index ac5f1267151d..e9df9cc28a85 100644 --- a/scripts/const_structs.checkpatch +++ b/scripts/const_structs.checkpatch @@ -44,6 +44,7 @@ platform_hibernation_ops platform_suspend_ops proto_ops regmap_access_table +regulator_ops rpc_pipe_ops rtc_class_ops sd_desc diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index 0869def435ee..90398347e366 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -3,18 +3,68 @@ # (c) 2014, Sasha Levin <sasha.levin@oracle.com> #set -x -if [[ $# < 2 ]]; then +if [[ $# < 1 ]]; then echo "Usage:" - echo " $0 [vmlinux] [base path] [modules path]" + echo " $0 -r <release> | <vmlinux> [base path] [modules path]" exit 1 fi -vmlinux=$1 -basepath=$2 -modpath=$3 +if [[ $1 == "-r" ]] ; then + vmlinux="" + basepath="auto" + modpath="" + release=$2 + + for fn in {,/usr/lib/debug}/boot/vmlinux-$release{,.debug} /lib/modules/$release{,/build}/vmlinux ; do + if [ -e "$fn" ] ; then + vmlinux=$fn + break + fi + done + + if [[ $vmlinux == "" ]] ; then + echo "ERROR! vmlinux image for release $release is not found" >&2 + exit 2 + fi +else + vmlinux=$1 + basepath=${2-auto} + modpath=$3 + release="" +fi + declare -A cache declare -A modcache +find_module() { + if [[ "$modpath" != "" ]] ; then + for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do + if readelf -WS "$fn" | grep -qwF .debug_line ; then + echo $fn + return + fi + done + return 1 + fi + + modpath=$(dirname "$vmlinux") + find_module && return + + if [[ $release == "" ]] ; then + release=$(gdb -ex 'print init_uts_ns.name.release' -ex 'quit' -quiet -batch "$vmlinux" | sed -n 's/\$1 = "\(.*\)".*/\1/p') + fi + + for dn in {/usr/lib/debug,}/lib/modules/$release ; do + if [ -e "$dn" ] ; then + modpath="$dn" + find_module && return + fi + done + + modpath="" + return 1 +} + parse_symbol() { # The structure of symbol at this point is: # ([name]+[offset]/[total length]) @@ -27,12 +77,11 @@ parse_symbol() { elif [[ "${modcache[$module]+isset}" == "isset" ]]; then local objfile=${modcache[$module]} else - if [[ $modpath == "" ]]; then + local objfile=$(find_module) + if [[ $objfile == "" ]] ; then echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 return fi - local objfile=$(find "$modpath" -name "${module//_/[-_]}.ko*" -print -quit) - [[ $objfile == "" ]] && return modcache[$module]=$objfile fi @@ -56,7 +105,11 @@ parse_symbol() { if [[ "${cache[$module,$name]+isset}" == "isset" ]]; then local base_addr=${cache[$module,$name]} else - local base_addr=$(nm "$objfile" | grep -i ' t ' | awk "/ $name\$/ {print \$1}" | head -n1) + local base_addr=$(nm "$objfile" | awk '$3 == "'$name'" && ($2 == "t" || $2 == "T") {print $1; exit}') + if [[ $base_addr == "" ]] ; then + # address not found + return + fi cache[$module,$name]="$base_addr" fi # Let's start doing the math to get the exact address into the @@ -148,6 +201,14 @@ handle_line() { echo "${words[@]}" "$symbol $module" } +if [[ $basepath == "auto" ]] ; then + module="" + symbol="kernel_init+0x0/0x0" + parse_symbol + basepath=${symbol#kernel_init (} + basepath=${basepath%/init/main.c:*)} +fi + while read line; do # Let's see if we have an address in the line if [[ $line =~ \[\<([^]]+)\>\] ]] || diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 0b44917f981c..a698ece43fff 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -1,9 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # scripts/dtc makefile -hostprogs := dtc -always-$(CONFIG_DTC) += $(hostprogs) -always-$(CHECK_DT_BINDING) += $(hostprogs) +hostprogs-always-$(CONFIG_DTC) += dtc +hostprogs-always-$(CHECK_DT_BINDING) += dtc dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ srcpos.o checks.o util.o diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 4014ba7e2fbd..d66949bfeba4 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -1,22 +1,61 @@ # SPDX-License-Identifier: GPL-2.0 -GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) -HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti -HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb -HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat -HOST_EXTRACXXFLAGS += -Wno-format-diag - -$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h +$(obj)/randomize_layout_plugin.so: $(objtree)/$(obj)/randomize_layout_seed.h quiet_cmd_create_randomize_layout_seed = GENSEED $@ cmd_create_randomize_layout_seed = \ $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h $(objtree)/$(obj)/randomize_layout_seed.h: FORCE $(call if_changed,create_randomize_layout_seed) -targets = randomize_layout_seed.h randomize_layout_hash.h +targets += randomize_layout_seed.h randomize_layout_hash.h + +# Build rules for plugins +# +# No extra code is needed for single-file plugins. +# For multi-file plugins, use *-objs syntax to list the objects. +# +# If the plugin foo.so is compiled from foo.c and foo2.c, you can do: +# +# foo-objs := foo.o foo2.o + +always-y += $(GCC_PLUGIN) -hostcxxlibs-y := $(GCC_PLUGIN) -always-y := $(hostcxxlibs-y) +GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin) -$(foreach p,$(hostcxxlibs-y:%.so=%),$(eval $(p)-objs := $(p).o)) +plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \ + -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++98 \ + -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \ + -ggdb -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat \ + -Wno-format-diag +plugin_ldflags = -shared + +plugin-single := $(foreach m, $(GCC_PLUGIN), $(if $($(m:%.so=%-objs)),,$(m))) +plugin-multi := $(filter-out $(plugin-single), $(GCC_PLUGIN)) +plugin-objs := $(sort $(foreach m, $(plugin-multi), $($(m:%.so=%-objs)))) + +targets += $(plugin-single) $(plugin-multi) $(plugin-objs) clean-files += *.so + +plugin-single := $(addprefix $(obj)/, $(plugin-single)) +plugin-multi := $(addprefix $(obj)/, $(plugin-multi)) +plugin-objs := $(addprefix $(obj)/, $(plugin-objs)) + +quiet_cmd_plugin_cxx_so_c = HOSTCXX $@ + cmd_plugin_cxx_so_c = $(HOSTCXX) $(plugin_cxxflags) $(plugin_ldflags) -o $@ $< + +$(plugin-single): $(obj)/%.so: $(src)/%.c FORCE + $(call if_changed_dep,plugin_cxx_so_c) + +quiet_cmd_plugin_ld_so_o = HOSTLD $@ + cmd_plugin_ld_so_o = $(HOSTCXX) $(plugin_ldflags) -o $@ \ + $(addprefix $(obj)/, $($(target-stem)-objs)) + +$(plugin-multi): FORCE + $(call if_changed,plugin_ld_so_o) +$(foreach m, $(notdir $(plugin-multi)), $(eval $(obj)/$m: $(addprefix $(obj)/, $($(m:%.so=%-objs))))) + +quiet_cmd_plugin_cxx_o_c = HOSTCXX $@ + cmd_plugin_cxx_o_c = $(HOSTCXX) $(plugin_cxxflags) -c -o $@ $< + +$(plugin-objs): $(obj)/%.o: $(src)/%.c FORCE + $(call if_changed_dep,plugin_cxx_o_c) diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c b/scripts/gcc-plugins/cyc_complexity_plugin.c index 1909ec617431..73124c2b3edd 100644 --- a/scripts/gcc-plugins/cyc_complexity_plugin.c +++ b/scripts/gcc-plugins/cyc_complexity_plugin.c @@ -5,7 +5,7 @@ * Homepage: * https://github.com/ephox-gcc-plugins/cyclomatic_complexity * - * http://en.wikipedia.org/wiki/Cyclomatic_complexity + * https://en.wikipedia.org/wiki/Cyclomatic_complexity * The complexity M is then defined as: * M = E - N + 2P * where diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c index 0f98634c20a0..caff4a6c7e9a 100644 --- a/scripts/gcc-plugins/sancov_plugin.c +++ b/scripts/gcc-plugins/sancov_plugin.c @@ -11,7 +11,7 @@ * * You can read about it more here: * https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296 - * http://lwn.net/Articles/674854/ + * https://lwn.net/Articles/674854/ * https://github.com/google/syzkaller * https://lwn.net/Articles/677764/ * diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c index cc75eeba0be1..48e141e07956 100644 --- a/scripts/gcc-plugins/stackleak_plugin.c +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -20,7 +20,7 @@ * * Debugging: * - use fprintf() to stderr, debug_generic_expr(), debug_gimple_stmt(), - * print_rtl() and print_simple_rtl(); + * print_rtl_single() and debug_rtx(); * - add "-fdump-tree-all -fdump-rtl-all" to the plugin CFLAGS in * Makefile.gcc-plugins to see the verbose dumps of the gcc passes; * - use gcc -E to understand the preprocessing shenanigans; @@ -32,7 +32,10 @@ __visible int plugin_is_GPL_compatible; static int track_frame_size = -1; +static bool build_for_x86 = false; static const char track_function[] = "stackleak_track_stack"; +static bool disable = false; +static bool verbose = false; /* * Mark these global variables (roots) for gcc garbage collector since @@ -43,32 +46,32 @@ static GTY(()) tree track_function_decl; static struct plugin_info stackleak_plugin_info = { .version = "201707101337", .help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n" + "arch=target_arch\tspecify target build arch\n" "disable\t\tdo not activate the plugin\n" + "verbose\t\tprint info about the instrumentation\n" }; -static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after) +static void add_stack_tracking_gcall(gimple_stmt_iterator *gsi, bool after) { gimple stmt; - gcall *stackleak_track_stack; + gcall *gimple_call; cgraph_node_ptr node; basic_block bb; - /* Insert call to void stackleak_track_stack(void) */ + /* Insert calling stackleak_track_stack() */ stmt = gimple_build_call(track_function_decl, 0); - stackleak_track_stack = as_a_gcall(stmt); - if (after) { - gsi_insert_after(gsi, stackleak_track_stack, - GSI_CONTINUE_LINKING); - } else { - gsi_insert_before(gsi, stackleak_track_stack, GSI_SAME_STMT); - } + gimple_call = as_a_gcall(stmt); + if (after) + gsi_insert_after(gsi, gimple_call, GSI_CONTINUE_LINKING); + else + gsi_insert_before(gsi, gimple_call, GSI_SAME_STMT); /* Update the cgraph */ - bb = gimple_bb(stackleak_track_stack); + bb = gimple_bb(gimple_call); node = cgraph_get_create_node(track_function_decl); gcc_assert(node); cgraph_create_edge(cgraph_get_node(current_function_decl), node, - stackleak_track_stack, bb->count, + gimple_call, bb->count, compute_call_stmt_bb_frequency(current_function_decl, bb)); } @@ -85,6 +88,83 @@ static bool is_alloca(gimple stmt) return false; } +static tree get_current_stack_pointer_decl(void) +{ + varpool_node_ptr node; + + FOR_EACH_VARIABLE(node) { + tree var = NODE_DECL(node); + tree name = DECL_NAME(var); + + if (DECL_NAME_LENGTH(var) != sizeof("current_stack_pointer") - 1) + continue; + + if (strcmp(IDENTIFIER_POINTER(name), "current_stack_pointer")) + continue; + + return var; + } + + if (verbose) { + fprintf(stderr, "stackleak: missing current_stack_pointer in %s()\n", + DECL_NAME_POINTER(current_function_decl)); + } + return NULL_TREE; +} + +static void add_stack_tracking_gasm(gimple_stmt_iterator *gsi, bool after) +{ + gasm *asm_call = NULL; + tree sp_decl, input; + vec<tree, va_gc> *inputs = NULL; + + /* 'no_caller_saved_registers' is currently supported only for x86 */ + gcc_assert(build_for_x86); + + /* + * Insert calling stackleak_track_stack() in asm: + * asm volatile("call stackleak_track_stack" + * :: "r" (current_stack_pointer)) + * Use ASM_CALL_CONSTRAINT trick from arch/x86/include/asm/asm.h. + * This constraint is taken into account during gcc shrink-wrapping + * optimization. It is needed to be sure that stackleak_track_stack() + * call is inserted after the prologue of the containing function, + * when the stack frame is prepared. + */ + sp_decl = get_current_stack_pointer_decl(); + if (sp_decl == NULL_TREE) { + add_stack_tracking_gcall(gsi, after); + return; + } + input = build_tree_list(NULL_TREE, build_const_char_string(2, "r")); + input = chainon(NULL_TREE, build_tree_list(input, sp_decl)); + vec_safe_push(inputs, input); + asm_call = gimple_build_asm_vec("call stackleak_track_stack", + inputs, NULL, NULL, NULL); + gimple_asm_set_volatile(asm_call, true); + if (after) + gsi_insert_after(gsi, asm_call, GSI_CONTINUE_LINKING); + else + gsi_insert_before(gsi, asm_call, GSI_SAME_STMT); + update_stmt(asm_call); +} + +static void add_stack_tracking(gimple_stmt_iterator *gsi, bool after) +{ + /* + * The 'no_caller_saved_registers' attribute is used for + * stackleak_track_stack(). If the compiler supports this attribute for + * the target arch, we can add calling stackleak_track_stack() in asm. + * That improves performance: we avoid useless operations with the + * caller-saved registers in the functions from which we will remove + * stackleak_track_stack() call during the stackleak_cleanup pass. + */ + if (lookup_attribute_spec(get_identifier("no_caller_saved_registers"))) + add_stack_tracking_gasm(gsi, after); + else + add_stack_tracking_gcall(gsi, after); +} + /* * Work with the GIMPLE representation of the code. Insert the * stackleak_track_stack() call after alloca() and into the beginning @@ -94,7 +174,7 @@ static unsigned int stackleak_instrument_execute(void) { basic_block bb, entry_bb; bool prologue_instrumented = false, is_leaf = true; - gimple_stmt_iterator gsi; + gimple_stmt_iterator gsi = { 0 }; /* * ENTRY_BLOCK_PTR is a basic block which represents possible entry @@ -122,8 +202,13 @@ static unsigned int stackleak_instrument_execute(void) if (!is_alloca(stmt)) continue; + if (verbose) { + fprintf(stderr, "stackleak: be careful, alloca() in %s()\n", + DECL_NAME_POINTER(current_function_decl)); + } + /* Insert stackleak_track_stack() call after alloca() */ - stackleak_add_track_stack(&gsi, true); + add_stack_tracking(&gsi, true); if (bb == entry_bb) prologue_instrumented = true; } @@ -168,7 +253,7 @@ static unsigned int stackleak_instrument_execute(void) bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); } gsi = gsi_after_labels(bb); - stackleak_add_track_stack(&gsi, false); + add_stack_tracking(&gsi, false); return 0; } @@ -182,21 +267,10 @@ static bool large_stack_frame(void) #endif } -/* - * Work with the RTL representation of the code. - * Remove the unneeded stackleak_track_stack() calls from the functions - * which don't call alloca() and don't have a large enough stack frame size. - */ -static unsigned int stackleak_cleanup_execute(void) +static void remove_stack_tracking_gcall(void) { rtx_insn *insn, *next; - if (cfun->calls_alloca) - return 0; - - if (large_stack_frame()) - return 0; - /* * Find stackleak_track_stack() calls. Loop through the chain of insns, * which is an RTL representation of the code for a function. @@ -257,6 +331,102 @@ static unsigned int stackleak_cleanup_execute(void) } #endif } +} + +static bool remove_stack_tracking_gasm(void) +{ + bool removed = false; + rtx_insn *insn, *next; + + /* 'no_caller_saved_registers' is currently supported only for x86 */ + gcc_assert(build_for_x86); + + /* + * Find stackleak_track_stack() asm calls. Loop through the chain of + * insns, which is an RTL representation of the code for a function. + * + * The example of a matching insn: + * (insn 11 5 12 2 (parallel [ (asm_operands/v + * ("call stackleak_track_stack") ("") 0 + * [ (reg/v:DI 7 sp [ current_stack_pointer ]) ] + * [ (asm_input:DI ("r")) ] []) + * (clobber (reg:CC 17 flags)) ]) -1 (nil)) + */ + for (insn = get_insns(); insn; insn = next) { + rtx body; + + next = NEXT_INSN(insn); + + /* Check the expression code of the insn */ + if (!NONJUMP_INSN_P(insn)) + continue; + + /* + * Check the expression code of the insn body, which is an RTL + * Expression (RTX) describing the side effect performed by + * that insn. + */ + body = PATTERN(insn); + + if (GET_CODE(body) != PARALLEL) + continue; + + body = XVECEXP(body, 0, 0); + + if (GET_CODE(body) != ASM_OPERANDS) + continue; + + if (strcmp(ASM_OPERANDS_TEMPLATE(body), + "call stackleak_track_stack")) { + continue; + } + + delete_insn_and_edges(insn); + gcc_assert(!removed); + removed = true; + } + + return removed; +} + +/* + * Work with the RTL representation of the code. + * Remove the unneeded stackleak_track_stack() calls from the functions + * which don't call alloca() and don't have a large enough stack frame size. + */ +static unsigned int stackleak_cleanup_execute(void) +{ + const char *fn = DECL_NAME_POINTER(current_function_decl); + bool removed = false; + + /* + * Leave stack tracking in functions that call alloca(). + * Additional case: + * gcc before version 7 called allocate_dynamic_stack_space() from + * expand_stack_vars() for runtime alignment of constant-sized stack + * variables. That caused cfun->calls_alloca to be set for functions + * that in fact don't use alloca(). + * For more info see gcc commit 7072df0aae0c59ae437e. + * Let's leave such functions instrumented as well. + */ + if (cfun->calls_alloca) { + if (verbose) + fprintf(stderr, "stackleak: instrument %s(): calls_alloca\n", fn); + return 0; + } + + /* Leave stack tracking in functions with large stack frame */ + if (large_stack_frame()) { + if (verbose) + fprintf(stderr, "stackleak: instrument %s()\n", fn); + return 0; + } + + if (lookup_attribute_spec(get_identifier("no_caller_saved_registers"))) + removed = remove_stack_tracking_gasm(); + + if (!removed) + remove_stack_tracking_gcall(); return 0; } @@ -376,9 +546,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, /* Parse the plugin arguments */ for (i = 0; i < argc; i++) { - if (!strcmp(argv[i].key, "disable")) - return 0; - if (!strcmp(argv[i].key, "track-min-size")) { if (!argv[i].value) { error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), @@ -392,6 +559,19 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, plugin_name, argv[i].key, argv[i].value); return 1; } + } else if (!strcmp(argv[i].key, "arch")) { + 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].value, "x86")) + build_for_x86 = true; + } else if (!strcmp(argv[i].key, "disable")) { + disable = true; + } else if (!strcmp(argv[i].key, "verbose")) { + verbose = true; } else { error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); @@ -399,6 +579,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, } } + if (disable) { + if (verbose) + fprintf(stderr, "stackleak: disabled for this translation unit\n"); + return 0; + } + /* Give the information about the plugin */ register_callback(plugin_name, PLUGIN_INFO, NULL, &stackleak_plugin_info); diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index e89be8f5c859..b9ef2e162107 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -11,7 +11,7 @@ * otherwise leak kernel stack to userland if they aren't properly initialized * by later code * - * Homepage: http://pax.grsecurity.net/ + * Homepage: https://pax.grsecurity.net/ * * Options: * -fplugin-arg-structleak_plugin-disable diff --git a/scripts/gdb/linux/genpd.py b/scripts/gdb/linux/genpd.py index 6ca93bd2949e..39cd1abd8559 100644 --- a/scripts/gdb/linux/genpd.py +++ b/scripts/gdb/linux/genpd.py @@ -49,17 +49,17 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary''' else: status_string = 'off-{}'.format(genpd['state_idx']) - slave_names = [] + child_names = [] for link in list_for_each_entry( - genpd['master_links'], + genpd['parent_links'], device_link_type.get_type().pointer(), - 'master_node'): - slave_names.apend(link['slave']['name']) + 'parent_node'): + child_names.append(link['child']['name']) gdb.write('%-30s %-15s %s\n' % ( genpd['name'].string(), status_string, - ', '.join(slave_names))) + ', '.join(child_names))) # Print devices in domain for pm_data in list_for_each_entry(genpd['dev_list'], @@ -70,7 +70,7 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary''' gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev))) def invoke(self, arg, from_tty): - gdb.write('domain status slaves\n'); + gdb.write('domain status children\n'); gdb.write(' /device runtime status\n'); gdb.write('----------------------------------------------------------------------\n'); for genpd in list_for_each_entry( diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py index c4b991607917..fe462855eefd 100644 --- a/scripts/gdb/linux/rbtree.py +++ b/scripts/gdb/linux/rbtree.py @@ -17,7 +17,7 @@ def rb_first(root): raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) node = root['rb_node'] - if node is 0: + if node == 0: return None while node['rb_left']: @@ -33,7 +33,7 @@ def rb_last(root): raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) node = root['rb_node'] - if node is 0: + if node == 0: return None while node['rb_right']: diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index d328de1e10ee..ce4f99935de5 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -hostprogs := genksyms -always-y := $(hostprogs) +hostprogs-always-y += genksyms genksyms-objs := genksyms.o parse.tab.o lex.lex.o diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index 224f51012b6e..dd554bd436cc 100755 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh @@ -86,11 +86,9 @@ arch/x86/include/uapi/asm/auxvec.h:CONFIG_X86_64 arch/x86/include/uapi/asm/mman.h:CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS include/uapi/asm-generic/fcntl.h:CONFIG_64BIT include/uapi/linux/atmdev.h:CONFIG_COMPAT -include/uapi/linux/elfcore.h:CONFIG_BINFMT_ELF_FDPIC include/uapi/linux/eventpoll.h:CONFIG_PM_SLEEP include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS include/uapi/linux/pktcdvd.h:CONFIG_CDROM_PKTCDVD_WCACHE -include/uapi/linux/raw.h:CONFIG_MAX_RAW_DEVS " for c in $configs diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index 12a67fdab541..c3d537cd0275 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -*.moc +/qconf-moc.cc *conf-cfg # diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 426881ea954f..52b59bf9efe4 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -181,19 +181,22 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg # qconf: Used for the xconfig target based on Qt hostprogs += qconf -qconf-cxxobjs := qconf.o +qconf-cxxobjs := qconf.o qconf-moc.o qconf-objs := images.o $(common-objs) HOSTLDLIBS_qconf = $(shell . $(obj)/qconf-cfg && echo $$libs) HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/qconf-cfg && echo $$cflags) +HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags) -$(obj)/qconf.o: $(obj)/qconf-cfg $(obj)/qconf.moc +$(obj)/qconf.o: $(obj)/qconf-cfg quiet_cmd_moc = MOC $@ - cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) -i $< -o $@ + cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@ -$(obj)/%.moc: $(src)/%.h $(obj)/qconf-cfg - $(call cmd,moc) +$(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE + $(call if_changed,moc) + +targets += qconf-moc.cc # gconf: Used for the gconfig target based on GTK+ hostprogs += gconf diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 4a616128a154..23d1cb01a41a 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -23,7 +23,6 @@ #include "lkc.h" #include "qconf.h" -#include "qconf.moc" #include "images.h" @@ -308,10 +307,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name) setVerticalScrollMode(ScrollPerPixel); setHorizontalScrollMode(ScrollPerPixel); - if (mode == symbolMode) - setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value"); - else - setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); + setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); connect(this, SIGNAL(itemSelectionChanged(void)), SLOT(updateSelection(void))); @@ -392,11 +388,6 @@ void ConfigList::updateSelection(void) struct menu *menu; enum prop_type type; - if (mode == symbolMode) - setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value"); - else - setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value"); - if (selectedItems().count() == 0) return; @@ -437,14 +428,13 @@ void ConfigList::updateList(ConfigItem* item) if (rootEntry != &rootmenu && (mode == singleMode || (mode == symbolMode && rootEntry->parent != &rootmenu))) { item = (ConfigItem *)topLevelItem(0); - if (!item && mode != symbolMode) { + if (!item) item = new ConfigItem(this, 0, true); - last = item; - } + last = item; } if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && rootEntry->sym && rootEntry->prompt) { - item = last ? last->nextSibling() : firstChild(); + item = last ? last->nextSibling() : nullptr; if (!item) item = new ConfigItem(this, last, rootEntry, true); else @@ -1239,7 +1229,7 @@ void ConfigInfoView::clicked(const QUrl &url) if (count < 1) { qInfo() << "Clicked link is empty"; - delete data; + delete[] data; return; } @@ -1252,7 +1242,7 @@ void ConfigInfoView::clicked(const QUrl &url) result = sym_re_search(data); if (!result) { qInfo() << "Clicked symbol is invalid:" << data; - delete data; + delete[] data; return; } @@ -1735,7 +1725,6 @@ void ConfigMainWindow::listFocusChanged(void) void ConfigMainWindow::goBack(void) { -qInfo() << __FUNCTION__; if (configList->rootEntry == &rootmenu) return; diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index fb9e9729266f..5eeab4a8bb43 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -92,10 +92,6 @@ public: { return this; } - ConfigItem* firstChild() const - { - return (ConfigItem *)children().first(); - } void addColumn(colIdx idx) { showColumn(idx); diff --git a/scripts/kernel-doc b/scripts/kernel-doc index b4c963f8364e..d1b445665ad6 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -81,6 +81,7 @@ Output selection modifiers: Other parameters: -v Verbose output, more warnings and other information. -h Print this help. + -Werror Treat warnings as errors. EOF print $message; @@ -273,6 +274,7 @@ my $kernelversion; my $dohighlight = ""; my $verbose = 0; +my $Werror = 0; my $output_mode = "rst"; my $output_preformatted = 0; my $no_doc_sections = 0; @@ -319,6 +321,18 @@ if (defined($ENV{'KBUILD_VERBOSE'})) { $verbose = "$ENV{'KBUILD_VERBOSE'}"; } +if (defined($ENV{'KDOC_WERROR'})) { + $Werror = "$ENV{'KDOC_WERROR'}"; +} + +if (defined($ENV{'KCFLAGS'})) { + my $kcflags = "$ENV{'KCFLAGS'}"; + + if ($kcflags =~ /Werror/) { + $Werror = 1; + } +} + # Generated docbook code is inserted in a template at a point where # docbook v3.1 requires a non-zero sequence of RefEntry's; see: # https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html @@ -433,6 +447,8 @@ while ($ARGV[0] =~ m/^--?(.*)/) { push(@export_file_list, $file); } elsif ($cmd eq "v") { $verbose = 1; + } elsif ($cmd eq "Werror") { + $Werror = 1; } elsif (($cmd eq "h") || ($cmd eq "help")) { usage(); } elsif ($cmd eq 'no-doc-sections') { @@ -1083,7 +1099,9 @@ sub dump_struct($$) { $members =~ s/\s*__packed\s*/ /gos; $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos; $members =~ s/\s*____cacheline_aligned_in_smp/ /gos; + # replace DECLARE_BITMAP + $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos; $members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; # replace DECLARE_HASHTABLE $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; @@ -1769,6 +1787,11 @@ sub process_proto_function($$) { $prototype =~ s@/\*.*?\*/@@gos; # strip comments. $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. $prototype =~ s@^\s+@@gos; # strip leading spaces + + # Handle prototypes for function pointers like: + # int (*pcs_config)(struct foo) + $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos; + if ($prototype =~ /SYSCALL_DEFINE/) { syscall_munge(); } @@ -2255,4 +2278,9 @@ if ($verbose && $warnings) { print STDERR "$warnings warnings\n"; } -exit($output_mode eq "none" ? 0 : $errors); +if ($Werror && $warnings) { + print STDERR "$warnings warnings as Errors\n"; + exit($warnings); +} else { + exit($output_mode eq "none" ? 0 : $errors) +} diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 92dd745906f4..e6e2d9e5ff48 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -30,6 +30,10 @@ # Error out on error set -e +LD="$1" +KBUILD_LDFLAGS="$2" +LDFLAGS_vmlinux="$3" + # Nice output in kbuild format # Will be supressed by "make -s" info() @@ -336,6 +340,12 @@ fi vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} +# fill in BTF IDs +if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then +info BTFIDS vmlinux +${RESOLVE_BTFIDS} vmlinux +fi + if [ -n "${CONFIG_BUILDTIME_TABLE_SORT}" ]; then info SORTTAB vmlinux if ! sorttable vmlinux; then diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index 296b6a3878b2..78071681d924 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 OBJECT_FILES_NON_STANDARD := y -hostprogs := modpost mk_elfconfig -always-y := $(hostprogs) empty.o +hostprogs-always-y += modpost mk_elfconfig +always-y += empty.o modpost-objs := modpost.o file2alias.o sumversion.o diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 010be8ba2116..27007c18e754 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -216,6 +216,8 @@ int main(void) DEVID(sdw_device_id); DEVID_FIELD(sdw_device_id, mfg_id); DEVID_FIELD(sdw_device_id, part_id); + DEVID_FIELD(sdw_device_id, sdw_version); + DEVID_FIELD(sdw_device_id, class_id); DEVID(fsl_mc_device_id); DEVID_FIELD(fsl_mc_device_id, vendor); diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 9599e2a3f1e6..2417dd1dee33 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1258,15 +1258,19 @@ static int do_hda_entry(const char *filename, void *symval, char *alias) return 1; } -/* Looks like: sdw:mNpN */ +/* Looks like: sdw:mNpNvNcN */ static int do_sdw_entry(const char *filename, void *symval, char *alias) { DEF_FIELD(symval, sdw_device_id, mfg_id); DEF_FIELD(symval, sdw_device_id, part_id); + DEF_FIELD(symval, sdw_device_id, sdw_version); + DEF_FIELD(symval, sdw_device_id, class_id); strcpy(alias, "sdw:"); ADD(alias, "m", mfg_id != 0, mfg_id); ADD(alias, "p", part_id != 0, part_id); + ADD(alias, "v", sdw_version != 0, sdw_version); + ADD(alias, "c", class_id != 0, class_id); add_wildcard(alias); return 1; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 45f2ab2ec2d4..69341b36f271 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -144,6 +144,7 @@ char *get_line(char **stringp) if (!orig || *orig == '\0') return NULL; + /* don't use strsep here, it is not available everywhere */ next = strchr(orig, '\n'); if (next) *next++ = '\0'; diff --git a/scripts/nsdeps b/scripts/nsdeps index 03a8e7cbe6c7..dab4c1a0e27d 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -29,7 +29,7 @@ fi generate_deps_for_ns() { $SPATCH --very-quiet --in-place --sp-file \ - $srctree/scripts/coccinelle/misc/add_namespace.cocci -D ns=$1 $2 + $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2 } generate_deps() { diff --git a/scripts/package/buildtar b/scripts/package/buildtar index fb1578e72ab9..936198a90477 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -53,6 +53,18 @@ rm -rf -- "${tmpdir}" mkdir -p -- "${tmpdir}/boot" dirs=boot + +# +# Try to install dtbs +# +if grep -q '^CONFIG_OF_EARLY_FLATTREE=y' include/config/auto.conf; then + # Only some architectures with OF support have this target + if [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then + $MAKE ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_DTBS_PATH="${tmpdir}/boot/dtbs/${KERNELRELEASE}" dtbs_install + fi +fi + + # # Try to install modules # diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index df1adbfb8ead..48fbd3d0284a 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -175,7 +175,7 @@ Section: kernel Priority: optional Maintainer: $maintainer Build-Depends: bc, rsync, kmod, cpio, bison, flex | flex:native $extra_build_depends -Homepage: http://www.kernel.org/ +Homepage: https://www.kernel.org/ Package: $packagename Architecture: $debarch diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 8640c278f1aa..7c477ca7dc98 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -46,7 +46,7 @@ sed -e '/^DEL/d' -e 's/^\t*//' <<EOF License: GPL Group: System Environment/Kernel Vendor: The Linux Community - URL: http://www.kernel.org + URL: https://www.kernel.org $S Source: kernel-$__KERNELRELEASE.tar.gz Provides: $PROVIDES %define __spec_install_post /usr/lib/rpm/brp-compress || : diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 7225107a9aaf..b9c2ee7ab43f 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -42,6 +42,8 @@ #define R_ARM_THM_CALL 10 #define R_ARM_CALL 28 +#define R_AARCH64_CALL26 283 + static int fd_map; /* File descriptor for file being modified. */ static int mmap_failed; /* Boolean flag. */ static char gpfx; /* prefix for global symbol name (sometimes '_') */ @@ -434,6 +436,11 @@ static int arm_is_fake_mcount(Elf32_Rel const *rp) return 1; } +static int arm64_is_fake_mcount(Elf64_Rel const *rp) +{ + return ELF64_R_TYPE(w(rp->r_info)) != R_AARCH64_CALL26; +} + /* 64-bit EM_MIPS has weird ELF64_Rela.r_info. * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40] @@ -547,6 +554,7 @@ static int do_file(char const *const fname) make_nop = make_nop_arm64; rel_type_nop = R_AARCH64_NONE; ideal_nop = ideal_nop4_arm64; + is_fake_mcount64 = arm64_is_fake_mcount; break; case EM_IA_64: reltype = R_IA64_IMM64; break; case EM_MIPS: /* reltype: e_class */ break; diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile index 70cf8d95d07c..1faf7f07e8db 100644 --- a/scripts/selinux/genheaders/Makefile +++ b/scripts/selinux/genheaders/Makefile @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -hostprogs := genheaders +hostprogs-always-y += genheaders HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ -I$(srctree)/security/selinux/include - -always-y := $(hostprogs) diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile index 3026f3c2aa2b..d61058ddd15c 100644 --- a/scripts/selinux/mdp/Makefile +++ b/scripts/selinux/mdp/Makefile @@ -1,8 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 -hostprogs := mdp +hostprogs-always-y += mdp HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ -I$(srctree)/security/selinux/include -I$(objtree)/include -always-y := $(hostprogs) clean-files := policy.* file_contexts diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c index 576d11a60417..6ceb88eb9b59 100644 --- a/scripts/selinux/mdp/mdp.c +++ b/scripts/selinux/mdp/mdp.c @@ -67,8 +67,14 @@ int main(int argc, char *argv[]) initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); /* print out the sids */ - for (i = 1; i < initial_sid_to_string_len; i++) - fprintf(fout, "sid %s\n", initial_sid_to_string[i]); + for (i = 1; i < initial_sid_to_string_len; i++) { + const char *name = initial_sid_to_string[i]; + + if (name) + fprintf(fout, "sid %s\n", name); + else + fprintf(fout, "sid unused%d\n", i); + } fprintf(fout, "\n"); /* print out the class permissions */ @@ -126,9 +132,16 @@ int main(int argc, char *argv[]) #define OBJUSERROLETYPE "user_u:object_r:base_t" /* default sids */ - for (i = 1; i < initial_sid_to_string_len; i++) - fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", - initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); + for (i = 1; i < initial_sid_to_string_len; i++) { + const char *name = initial_sid_to_string[i]; + + if (name) + fprintf(fout, "sid %s ", name); + else + fprintf(fout, "sid unused%d\n", i); + fprintf(fout, SUBJUSERROLETYPE "%s\n", + mls ? ":" SYSTEMLOW : ""); + } fprintf(fout, "\n"); #define FS_USE(behavior, fstype) \ diff --git a/scripts/sorttable.c b/scripts/sorttable.c index ec6b5e81eba1..0ef3abfc4a51 100644 --- a/scripts/sorttable.c +++ b/scripts/sorttable.c @@ -255,6 +255,45 @@ static void x86_sort_relative_table(char *extab_image, int image_size) } } +static void s390_sort_relative_table(char *extab_image, int image_size) +{ + int i; + + for (i = 0; i < image_size; i += 16) { + char *loc = extab_image + i; + uint64_t handler; + + w(r((uint32_t *)loc) + i, (uint32_t *)loc); + w(r((uint32_t *)(loc + 4)) + (i + 4), (uint32_t *)(loc + 4)); + /* + * 0 is a special self-relative handler value, which means that + * handler should be ignored. It is safe, because it means that + * handler field points to itself, which should never happen. + * When creating extable-relative values, keep it as 0, since + * this should never occur either: it would mean that handler + * field points to the first extable entry. + */ + handler = r8((uint64_t *)(loc + 8)); + if (handler) + handler += i + 8; + w8(handler, (uint64_t *)(loc + 8)); + } + + qsort(extab_image, image_size / 16, 16, compare_relative_table); + + for (i = 0; i < image_size; i += 16) { + char *loc = extab_image + i; + uint64_t handler; + + w(r((uint32_t *)loc) - i, (uint32_t *)loc); + w(r((uint32_t *)(loc + 4)) - (i + 4), (uint32_t *)(loc + 4)); + handler = r8((uint64_t *)(loc + 8)); + if (handler) + handler -= i + 8; + w8(handler, (uint64_t *)(loc + 8)); + } +} + static int do_file(char const *const fname, void *addr) { int rc = -1; @@ -297,6 +336,8 @@ static int do_file(char const *const fname, void *addr) custom_sort = x86_sort_relative_table; break; case EM_S390: + custom_sort = s390_sort_relative_table; + break; case EM_AARCH64: case EM_PARISC: case EM_PPC: diff --git a/scripts/spelling.txt b/scripts/spelling.txt index c45e9afaab2d..f253681e7e2a 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -149,6 +149,7 @@ arbitary||arbitrary architechture||architecture arguement||argument arguements||arguments +arithmatic||arithmetic aritmetic||arithmetic arne't||aren't arraival||arrival @@ -454,6 +455,7 @@ destorys||destroys destroied||destroyed detabase||database deteced||detected +detectt||detect develope||develop developement||development developped||developed @@ -545,6 +547,7 @@ entires||entries entites||entities entrys||entries enocded||encoded +enought||enough enterily||entirely enviroiment||environment enviroment||environment @@ -556,11 +559,14 @@ equivelant||equivalent equivilant||equivalent eror||error errorr||error +errror||error estbalishment||establishment etsablishment||establishment etsbalishment||establishment +evalution||evaluation excecutable||executable exceded||exceeded +exceds||exceeds exceeed||exceed excellant||excellent execeeded||exceeded @@ -583,6 +589,7 @@ explictly||explicitly expresion||expression exprimental||experimental extened||extended +exteneded||extended||extended extensability||extensibility extention||extension extenstion||extension @@ -610,10 +617,12 @@ feautures||features fetaure||feature fetaures||features fileystem||filesystem +fimrware||firmware fimware||firmware firmare||firmware firmaware||firmware firware||firmware +firwmare||firmware finanize||finalize findn||find finilizes||finalizes @@ -661,6 +670,7 @@ globel||global grabing||grabbing grahical||graphical grahpical||graphical +granularty||granularity grapic||graphic grranted||granted guage||gauge @@ -906,6 +916,7 @@ miximum||maximum mmnemonic||mnemonic mnay||many modfiy||modify +modifer||modifier modulues||modules momery||memory memomry||memory @@ -915,6 +926,7 @@ monochromo||monochrome monocrome||monochrome mopdule||module mroe||more +multipler||multiplier mulitplied||multiplied multidimensionnal||multidimensional multipe||multiple @@ -952,6 +964,7 @@ occassionally||occasionally occationally||occasionally occurance||occurrence occurances||occurrences +occurd||occurred occured||occurred occurence||occurrence occure||occurred @@ -1058,6 +1071,7 @@ precission||precision preemptable||preemptible prefered||preferred prefferably||preferably +prefitler||prefilter premption||preemption prepaired||prepared preperation||preparation @@ -1101,6 +1115,7 @@ pronunce||pronounce propery||property propigate||propagate propigation||propagation +propogation||propagation propogate||propagate prosess||process protable||portable @@ -1316,6 +1331,7 @@ sturcture||structure subdirectoires||subdirectories suble||subtle substract||subtract +submited||submitted submition||submission suceed||succeed succesfully||successfully @@ -1324,6 +1340,7 @@ successed||succeeded successfull||successful successfuly||successfully sucessfully||successfully +sucessful||successful sucess||success superflous||superfluous superseeded||superseded @@ -1409,6 +1426,7 @@ transormed||transformed trasfer||transfer trasmission||transmission treshold||threshold +triggerd||triggered trigerred||triggered trigerring||triggering trun||turn @@ -1421,6 +1439,7 @@ uknown||unknown usccess||success usupported||unsupported uncommited||uncommitted +uncompatible||incompatible unconditionaly||unconditionally undeflow||underflow underun||underrun diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index c680c3efb176..40fa6923e80a 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -323,10 +323,6 @@ sub check_sphinx() $rec_sphinx_upgrade = 1; return; } - if ($cur_version lt $min_pdf_version) { - $rec_sphinx_upgrade = 1; - return; - } # On version check mode, just assume Sphinx has all mandatory deps exit (0) if ($version_check); diff --git a/scripts/tags.sh b/scripts/tags.sh index 4e18ae5282a6..32d3f53af10b 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -91,20 +91,10 @@ all_sources() all_compiled_sources() { - for i in $(all_sources); do - case "$i" in - *.[cS]) - j=${i/\.[cS]/\.o} - j="${j#$tree}" - if [ -e $j ]; then - echo $i - fi - ;; - *) - echo $i - ;; - esac - done + realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) \ + include/generated/autoconf.h $(find -name "*.cmd" -exec \ + grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | + awk '!a[$0]++') | sort -u } all_target_sources() |