diff options
Diffstat (limited to 'scripts')
66 files changed, 1424 insertions, 369 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 7484b9d8272f..e2de6c4dce90 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -138,11 +138,6 @@ cc-disable-warning = $(call try-run,\ # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) -# cc-ldoption -# Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) -cc-ldoption = $(call try-run,\ - $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) - # ld-option # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) @@ -192,14 +187,6 @@ clean := -f $(srctree)/scripts/Makefile.clean obj # $(Q)$(MAKE) $(hdr-inst)=dir hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj -# Prefix -I with $(srctree) if it is not an absolute path. -# skip if -I has no parameter -addtree = $(if $(patsubst -I%,%,$(1)), \ -$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1)) - -# Find all -I options and call addtree -flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) - # echo command. # Short version is used, if $(quiet) equals `quiet_', otherwise full one. echo-cmd = $(if $($(quiet)cmd_$(1)),\ diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 87ff1dcc6bd5..8a5c4d645eb1 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # Kconfig helper macros # Convenient variables @@ -18,6 +19,10 @@ if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)") # Return y if <command> exits with 0, n otherwise success = $(if-success,$(1),y,n) +# $(failure,<command>) +# Return n if <command> exits with 0, y otherwise +failure = $(if-success,$(1),n,y) + # $(cc-option,<flag>) # Return y if the compiler supports <flag>, n otherwise cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) @@ -26,5 +31,9 @@ cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) # Return y if the linker supports <flag>, n otherwise ld-option = $(success,$(LD) -v $(1)) +# check if $(CC) and $(LD) exist +$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found) +$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) + # gcc version including patch level gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 76ca30cc4791..ae9cf740633e 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -222,6 +222,9 @@ endif ifdef CONFIG_RETPOLINE objtool_args += --retpoline endif +ifdef CONFIG_X86_SMAP + objtool_args += --uaccess +endif # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file @@ -501,7 +504,7 @@ existing-targets := $(wildcard $(sort $(targets))) -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -ifneq ($(KBUILD_SRC),) +ifneq ($(srctree),.) # Create directories for object files if they do not exist obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets)))) # If targets exist, their directories apparently exist. Skip mkdir. diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 768306add591..3ab8d1a303cd 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -23,15 +23,16 @@ warning- := $(empty) warning-1 := -Wextra -Wunused -Wno-unused-parameter warning-1 += -Wmissing-declarations warning-1 += -Wmissing-format-attribute -warning-1 += $(call cc-option, -Wmissing-prototypes) +warning-1 += -Wmissing-prototypes warning-1 += -Wold-style-definition -warning-1 += $(call cc-option, -Wmissing-include-dirs) +warning-1 += -Wmissing-include-dirs warning-1 += $(call cc-option, -Wunused-but-set-variable) warning-1 += $(call cc-option, -Wunused-const-variable) warning-1 += $(call cc-option, -Wpacked-not-aligned) warning-1 += $(call cc-option, -Wstringop-truncation) -warning-1 += $(call cc-disable-warning, missing-field-initializers) -warning-1 += $(call cc-disable-warning, sign-compare) +# The following turn off the warnings enabled by -Wextra +warning-1 += -Wno-missing-field-initializers +warning-1 += -Wno-sign-compare warning-2 := -Waggregate-return warning-2 += -Wcast-align @@ -39,8 +40,8 @@ warning-2 += -Wdisabled-optimization warning-2 += -Wnested-externs warning-2 += -Wshadow warning-2 += $(call cc-option, -Wlogical-op) -warning-2 += $(call cc-option, -Wmissing-field-initializers) -warning-2 += $(call cc-option, -Wsign-compare) +warning-2 += -Wmissing-field-initializers +warning-2 += -Wsign-compare warning-2 += $(call cc-option, -Wmaybe-uninitialized) warning-2 += $(call cc-option, -Wunused-macros) @@ -66,11 +67,11 @@ KBUILD_CFLAGS += $(warning) else ifdef CONFIG_CC_IS_CLANG -KBUILD_CFLAGS += $(call cc-disable-warning, initializer-overrides) -KBUILD_CFLAGS += $(call cc-disable-warning, unused-value) -KBUILD_CFLAGS += $(call cc-disable-warning, format) -KBUILD_CFLAGS += $(call cc-disable-warning, sign-compare) -KBUILD_CFLAGS += $(call cc-disable-warning, format-zero-length) -KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized) +KBUILD_CFLAGS += -Wno-initializer-overrides +KBUILD_CFLAGS += -Wno-unused-value +KBUILD_CFLAGS += -Wno-format +KBUILD_CFLAGS += -Wno-sign-compare +KBUILD_CFLAGS += -Wno-format-zero-length +KBUILD_CFLAGS += -Wno-uninitialized endif endif diff --git a/scripts/Makefile.host b/scripts/Makefile.host index a115259b57e7..b6a54bdf0965 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -67,18 +67,16 @@ _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ $(HOSTCXXFLAGS_$(basetarget).o) -__hostc_flags = $(_hostc_flags) -__hostcxx_flags = $(_hostcxx_flags) - +# $(objtree)/$(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) -ifneq ($(KBUILD_SRC),) -__hostc_flags = -I$(obj) $(call flags,_hostc_flags) -__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags) +ifneq ($(srctree),.) +_hostc_flags += -I $(objtree)/$(obj) +_hostcxx_flags += -I $(objtree)/$(obj) endif endif -hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags) -hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags) +hostc_flags = -Wp,-MD,$(depfile) $(_hostc_flags) +hostcxx_flags = -Wp,-MD,$(depfile) $(_hostcxx_flags) ##### # Compile programs on the host diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov index 3d61c4bfcbee..52b113302443 100644 --- a/scripts/Makefile.kcov +++ b/scripts/Makefile.kcov @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only ifdef CONFIG_KCOV kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8a1f64f17740..f1f38c8cdc74 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -137,36 +137,26 @@ _c_flags += $(if $(patsubst n%,, \ $(CFLAGS_KCOV)) endif -__c_flags = $(_c_flags) -__a_flags = $(_a_flags) -__cpp_flags = $(_cpp_flags) - -# If building the kernel in a separate objtree expand all occurrences -# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). +# $(srctree)/$(src) for including checkin headers from generated source files +# $(objtree)/$(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) -ifneq ($(KBUILD_SRC),) - -# -I$(obj) locates generated .h files -# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files -# and locates generated .h files -# FIXME: Replace both with specific CFLAGS* statements in the makefiles -__c_flags = $(if $(obj),$(call addtree,-I$(src)) -I$(obj)) \ - $(call flags,_c_flags) -__a_flags = $(call flags,_a_flags) -__cpp_flags = $(call flags,_cpp_flags) +ifneq ($(srctree),.) +_c_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) +_a_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) +_cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) endif endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ -include $(srctree)/include/linux/compiler_types.h \ - $(__c_flags) $(modkern_cflags) \ + $(_c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ - $(__a_flags) $(modkern_aflags) + $(_a_flags) $(modkern_aflags) cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ - $(__cpp_flags) + $(_cpp_flags) ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) @@ -308,7 +298,7 @@ DT_BINDING_DIR := Documentation/devicetree/bindings DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.yaml quiet_cmd_dtb_check = CHECK $@ - cmd_dtb_check = $(DT_CHECKER) -p $(DT_TMP_SCHEMA) $@ ; + cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ ; define rule_dtc_dt_yaml $(call cmd_and_fixdep,dtc,yaml) diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin index a072a4267746..ea90a90b41a0 100644 --- a/scripts/Makefile.modbuiltin +++ b/scripts/Makefile.modbuiltin @@ -15,7 +15,7 @@ include include/config/tristate.conf include scripts/Kbuild.include -ifneq ($(KBUILD_SRC),) +ifneq ($(srctree),.) # Create output directory if not already present _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) endif diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 6b7f354f189a..fec6ec2ffa47 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -78,7 +78,7 @@ modpost = scripts/mod/modpost \ $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ - $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) + $(if $(KBUILD_MODPOST_WARN),-w) MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS))) diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 38b2b4818e8e..019771b845c5 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -3,7 +3,6 @@ ifdef CONFIG_UBSAN CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift) CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero) CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable) - CFLAGS_UBSAN += $(call cc-option, -fsanitize=vla-bound) CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow) CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds) CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size) diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c index 1b28787028d3..adabd4145264 100644 --- a/scripts/asn1_compiler.c +++ b/scripts/asn1_compiler.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* Simplified ASN.1 notation parser * * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. */ #include <stdarg.h> diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh index 27400b0cd732..000dc6437893 100644 --- a/scripts/atomic/gen-atomics.sh +++ b/scripts/atomic/gen-atomics.sh @@ -13,7 +13,7 @@ gen-atomic-long.sh asm-generic/atomic-long.h gen-atomic-fallback.sh linux/atomic-fallback.h EOF while read script header; do - ${ATOMICDIR}/${script} ${ATOMICTBL} > ${LINUXDIR}/include/${header} + /bin/sh ${ATOMICDIR}/${script} ${ATOMICTBL} > ${LINUXDIR}/include/${header} HASH="$(sha1sum ${LINUXDIR}/include/${header})" HASH="${HASH%% *}" printf "// %s\n" "${HASH}" >> ${LINUXDIR}/include/${header} diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index af49b446f17d..548aeb592806 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only ### # This Makefile lists the most basic programs used during the build process. # The programs listed herein are what are needed to do the basic stuff, diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py index 5010a4d5bfba..894cc58c1a03 100755 --- a/scripts/bpf_helpers_doc.py +++ b/scripts/bpf_helpers_doc.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 # SPDX-License-Identifier: GPL-2.0-only # -# Copyright (C) 2018 Netronome Systems, Inc. +# Copyright (C) 2018-2019 Netronome Systems, Inc. # In case user attempts to run with Python 2. from __future__ import print_function @@ -39,7 +39,7 @@ class Helper(object): Break down helper function protocol into smaller chunks: return type, name, distincts arguments. """ - arg_re = re.compile('((const )?(struct )?(\w+|...))( (\**)(\w+))?$') + arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$') res = {} proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') @@ -54,8 +54,8 @@ class Helper(object): capture = arg_re.match(a) res['args'].append({ 'type' : capture.group(1), - 'star' : capture.group(6), - 'name' : capture.group(7) + 'star' : capture.group(5), + 'name' : capture.group(6) }) return res diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a09333fd7cef..342c7c781ba5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2687,6 +2687,24 @@ sub process { } else { $signatures{$sig_nospace} = 1; } + +# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email + if ($sign_off =~ /^co-developed-by:$/i) { + if ($email eq $author) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); + } + if (!defined $lines[$linenr]) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); + } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } elsif ($1 ne $email) { + WARN("BAD_SIGN_OFF", + "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } + } } # Check email subject for common tools that don't need to be mentioned @@ -3009,7 +3027,7 @@ sub process { my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; my $dt_path = $root . "/Documentation/devicetree/bindings/"; - my $vp_file = $dt_path . "vendor-prefixes.txt"; + my $vp_file = $dt_path . "vendor-prefixes.yaml"; foreach my $compat (@compats) { my $compat2 = $compat; @@ -3024,7 +3042,7 @@ sub process { next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; my $vendor = $1; - `grep -Eq "^$vendor\\b" $vp_file`; + `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; if ( $? >> 8 ) { WARN("UNDOCUMENTED_DT_STRING", "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); diff --git a/scripts/coccinelle/api/stream_open.cocci b/scripts/coccinelle/api/stream_open.cocci new file mode 100644 index 000000000000..350145da7669 --- /dev/null +++ b/scripts/coccinelle/api/stream_open.cocci @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: GPL-2.0 +// Author: Kirill Smelkov (kirr@nexedi.com) +// +// Search for stream-like files that are using nonseekable_open and convert +// them to stream_open. A stream-like file is a file that does not use ppos in +// its read and write. Rationale for the conversion is to avoid deadlock in +// between read and write. + +virtual report +virtual patch +virtual explain // explain decisions in the patch (SPFLAGS="-D explain") + +// stream-like reader & writer - ones that do not depend on f_pos. +@ stream_reader @ +identifier readstream, ppos; +identifier f, buf, len; +type loff_t; +@@ + ssize_t readstream(struct file *f, char *buf, size_t len, loff_t *ppos) + { + ... when != ppos + } + +@ stream_writer @ +identifier writestream, ppos; +identifier f, buf, len; +type loff_t; +@@ + ssize_t writestream(struct file *f, const char *buf, size_t len, loff_t *ppos) + { + ... when != ppos + } + + +// a function that blocks +@ blocks @ +identifier block_f; +identifier wait_event =~ "^wait_event_.*"; +@@ + block_f(...) { + ... when exists + wait_event(...) + ... when exists + } + +// stream_reader that can block inside. +// +// XXX wait_* can be called not directly from current function (e.g. func -> f -> g -> wait()) +// XXX currently reader_blocks supports only direct and 1-level indirect cases. +@ reader_blocks_direct @ +identifier stream_reader.readstream; +identifier wait_event =~ "^wait_event_.*"; +@@ + readstream(...) + { + ... when exists + wait_event(...) + ... when exists + } + +@ reader_blocks_1 @ +identifier stream_reader.readstream; +identifier blocks.block_f; +@@ + readstream(...) + { + ... when exists + block_f(...) + ... when exists + } + +@ reader_blocks depends on reader_blocks_direct || reader_blocks_1 @ +identifier stream_reader.readstream; +@@ + readstream(...) { + ... + } + + +// file_operations + whether they have _any_ .read, .write, .llseek ... at all. +// +// XXX add support for file_operations xxx[N] = ... (sound/core/pcm_native.c) +@ fops0 @ +identifier fops; +@@ + struct file_operations fops = { + ... + }; + +@ has_read @ +identifier fops0.fops; +identifier read_f; +@@ + struct file_operations fops = { + .read = read_f, + }; + +@ has_read_iter @ +identifier fops0.fops; +identifier read_iter_f; +@@ + struct file_operations fops = { + .read_iter = read_iter_f, + }; + +@ has_write @ +identifier fops0.fops; +identifier write_f; +@@ + struct file_operations fops = { + .write = write_f, + }; + +@ has_write_iter @ +identifier fops0.fops; +identifier write_iter_f; +@@ + struct file_operations fops = { + .write_iter = write_iter_f, + }; + +@ has_llseek @ +identifier fops0.fops; +identifier llseek_f; +@@ + struct file_operations fops = { + .llseek = llseek_f, + }; + +@ has_no_llseek @ +identifier fops0.fops; +@@ + struct file_operations fops = { + .llseek = no_llseek, + }; + +@ has_mmap @ +identifier fops0.fops; +identifier mmap_f; +@@ + struct file_operations fops = { + .mmap = mmap_f, + }; + +@ has_copy_file_range @ +identifier fops0.fops; +identifier copy_file_range_f; +@@ + struct file_operations fops = { + .copy_file_range = copy_file_range_f, + }; + +@ has_remap_file_range @ +identifier fops0.fops; +identifier remap_file_range_f; +@@ + struct file_operations fops = { + .remap_file_range = remap_file_range_f, + }; + +@ has_splice_read @ +identifier fops0.fops; +identifier splice_read_f; +@@ + struct file_operations fops = { + .splice_read = splice_read_f, + }; + +@ has_splice_write @ +identifier fops0.fops; +identifier splice_write_f; +@@ + struct file_operations fops = { + .splice_write = splice_write_f, + }; + + +// file_operations that is candidate for stream_open conversion - it does not +// use mmap and other methods that assume @offset access to file. +// +// XXX for simplicity require no .{read/write}_iter and no .splice_{read/write} for now. +// XXX maybe_steam.fops cannot be used in other rules - it gives "bad rule maybe_stream or bad variable fops". +@ maybe_stream depends on (!has_llseek || has_no_llseek) && !has_mmap && !has_copy_file_range && !has_remap_file_range && !has_read_iter && !has_write_iter && !has_splice_read && !has_splice_write @ +identifier fops0.fops; +@@ + struct file_operations fops = { + }; + + +// ---- conversions ---- + +// XXX .open = nonseekable_open -> .open = stream_open +// XXX .open = func -> openfunc -> nonseekable_open + +// read & write +// +// if both are used in the same file_operations together with an opener - +// under that conditions we can use stream_open instead of nonseekable_open. +@ fops_rw depends on maybe_stream @ +identifier fops0.fops, openfunc; +identifier stream_reader.readstream; +identifier stream_writer.writestream; +@@ + struct file_operations fops = { + .open = openfunc, + .read = readstream, + .write = writestream, + }; + +@ report_rw depends on report @ +identifier fops_rw.openfunc; +position p1; +@@ + openfunc(...) { + <... + nonseekable_open@p1 + ...> + } + +@ script:python depends on report && reader_blocks @ +fops << fops0.fops; +p << report_rw.p1; +@@ +coccilib.report.print_report(p[0], + "ERROR: %s: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix." % (fops,)) + +@ script:python depends on report && !reader_blocks @ +fops << fops0.fops; +p << report_rw.p1; +@@ +coccilib.report.print_report(p[0], + "WARNING: %s: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open." % (fops,)) + + +@ explain_rw_deadlocked depends on explain && reader_blocks @ +identifier fops_rw.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ nonseekable_open /* read & write (was deadlock) */ + ...> + } + + +@ explain_rw_nodeadlock depends on explain && !reader_blocks @ +identifier fops_rw.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ nonseekable_open /* read & write (no direct deadlock) */ + ...> + } + +@ patch_rw depends on patch @ +identifier fops_rw.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ stream_open + ...> + } + + +// read, but not write +@ fops_r depends on maybe_stream && !has_write @ +identifier fops0.fops, openfunc; +identifier stream_reader.readstream; +@@ + struct file_operations fops = { + .open = openfunc, + .read = readstream, + }; + +@ report_r depends on report @ +identifier fops_r.openfunc; +position p1; +@@ + openfunc(...) { + <... + nonseekable_open@p1 + ...> + } + +@ script:python depends on report @ +fops << fops0.fops; +p << report_r.p1; +@@ +coccilib.report.print_report(p[0], + "WARNING: %s: .read() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,)) + +@ explain_r depends on explain @ +identifier fops_r.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ nonseekable_open /* read only */ + ...> + } + +@ patch_r depends on patch @ +identifier fops_r.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ stream_open + ...> + } + + +// write, but not read +@ fops_w depends on maybe_stream && !has_read @ +identifier fops0.fops, openfunc; +identifier stream_writer.writestream; +@@ + struct file_operations fops = { + .open = openfunc, + .write = writestream, + }; + +@ report_w depends on report @ +identifier fops_w.openfunc; +position p1; +@@ + openfunc(...) { + <... + nonseekable_open@p1 + ...> + } + +@ script:python depends on report @ +fops << fops0.fops; +p << report_w.p1; +@@ +coccilib.report.print_report(p[0], + "WARNING: %s: .write() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,)) + +@ explain_w depends on explain @ +identifier fops_w.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ nonseekable_open /* write only */ + ...> + } + +@ patch_w depends on patch @ +identifier fops_w.openfunc; +@@ + openfunc(...) { + <... +- nonseekable_open ++ stream_open + ...> + } + + +// no read, no write - don't change anything diff --git a/scripts/conmakehash.c b/scripts/conmakehash.c index 61bbda54cf13..cddd789fe46e 100644 --- a/scripts/conmakehash.c +++ b/scripts/conmakehash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * conmakehash.c * @@ -8,10 +9,6 @@ * just for this seems like massive overkill. * * Copyright (C) 1995-1997 H. Peter Anvin - * - * This program is a part of the Linux kernel, and may be freely - * copied under the terms of the GNU General Public License (GPL), - * version 2, or at your option any later version. */ #include <stdio.h> diff --git a/scripts/documentation-file-ref-check b/scripts/documentation-file-ref-check index ad9db6821824..63e9542656f1 100755 --- a/scripts/documentation-file-ref-check +++ b/scripts/documentation-file-ref-check @@ -30,6 +30,34 @@ print "Finding broken references. This may take a while... " if ($fix); my %broken_ref; +my $doc_fix = 0; + +open IN, "git grep ':doc:\`' Documentation/|" + or die "Failed to run git grep"; +while (<IN>) { + next if (!m,^([^:]+):.*\:doc\:\`([^\`]+)\`,); + + my $d = $1; + my $doc_ref = $2; + + my $f = $doc_ref; + + $d =~ s,(.*/).*,$1,; + $f =~ s,.*\<([^\>]+)\>,$1,; + + $f ="$d$f.rst"; + + next if (grep -e, glob("$f")); + + if ($fix && !$doc_fix) { + print STDERR "\nWARNING: Currently, can't fix broken :doc:`` fields\n"; + } + $doc_fix++; + + print STDERR "$f: :doc:`$doc_ref`\n"; +} +close IN; + open IN, "git grep 'Documentation/'|" or die "Failed to run git grep"; while (<IN>) { @@ -38,6 +66,9 @@ while (<IN>) { my $f = $1; my $ln = $2; + # On linux-next, discard the Next/ directory + next if ($f =~ m,^Next/,); + # Makefiles and scripts contain nasty expressions to parse docs next if ($f =~ m/Makefile/ || $f =~ m/\.sh$/); @@ -100,6 +131,7 @@ while (<IN>) { } } } +close IN; exit 0 if (!$fix); diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 5f227d8d39d8..82160808765c 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -9,7 +9,7 @@ dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o # Source files need to get at the userspace version of libfdt_env.h to compile -HOST_EXTRACFLAGS := -I$(src)/libfdt +HOST_EXTRACFLAGS := -I $(srctree)/$(src)/libfdt ifeq ($(wildcard /usr/include/yaml.h),) ifneq ($(CHECK_DTBS),) @@ -23,8 +23,8 @@ HOSTLDLIBS_dtc := -lyaml endif # Generated files need one more search path to include headers in source tree -HOSTCFLAGS_dtc-lexer.lex.o := -I$(src) -HOSTCFLAGS_dtc-parser.tab.o := -I$(src) +HOSTCFLAGS_dtc-lexer.lex.o := -I $(srctree)/$(src) +HOSTCFLAGS_dtc-parser.tab.o := -I $(srctree)/$(src) # dependencies on generated files need to be listed explicitly $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h diff --git a/scripts/dtc/Makefile.dtc b/scripts/dtc/Makefile.dtc index d4375630a7f7..6ce8b4a35a23 100644 --- a/scripts/dtc/Makefile.dtc +++ b/scripts/dtc/Makefile.dtc @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # Makefile.dtc # # This is not a complete Makefile of itself. Instead, it is designed to diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt index 3af3656df801..1649c2c48046 100644 --- a/scripts/dtc/libfdt/Makefile.libfdt +++ b/scripts/dtc/libfdt/Makefile.libfdt @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # Makefile.libfdt # # This is not a complete Makefile of itself. Instead, it is designed to diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index 74271dba4f94..e9c677a53c74 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only preferred-plugin-hostcc := $(if-success,[ $(gcc-version) -ge 40800 ],$(HOSTCXX),$(HOSTCC)) config PLUGIN_HOSTCC @@ -13,17 +14,19 @@ config HAVE_GCC_PLUGINS An arch should select this symbol if it supports building with GCC plugins. -menuconfig GCC_PLUGINS - bool "GCC plugins" +config GCC_PLUGINS + bool depends on HAVE_GCC_PLUGINS depends on PLUGIN_HOSTCC != "" + default y help GCC plugins are loadable modules that provide extra features to the compiler. They are useful for runtime instrumentation and static analysis. See Documentation/gcc-plugins.txt for details. -if GCC_PLUGINS +menu "GCC plugins" + depends on GCC_PLUGINS config GCC_PLUGIN_CYC_COMPLEXITY bool "Compute the cyclomatic complexity of a function" if EXPERT @@ -66,71 +69,6 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ -config GCC_PLUGIN_STRUCTLEAK - bool "Zero initialize stack variables" - help - While the kernel is built with warnings enabled for any missed - stack variable initializations, this warning is silenced for - anything passed by reference to another function, under the - occasionally misguided assumption that the function will do - the initialization. As this regularly leads to exploitable - flaws, this plugin is available to identify and zero-initialize - such variables, depending on the chosen level of coverage. - - This plugin was originally ported from grsecurity/PaX. More - information at: - * https://grsecurity.net/ - * https://pax.grsecurity.net/ - -choice - prompt "Coverage" - depends on GCC_PLUGIN_STRUCTLEAK - default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL - help - This chooses the level of coverage over classes of potentially - uninitialized variables. The selected class will be - zero-initialized before use. - - config GCC_PLUGIN_STRUCTLEAK_USER - bool "structs marked for userspace" - help - Zero-initialize any structures on the stack containing - a __user attribute. This can prevent some classes of - uninitialized stack variable exploits and information - exposures, like CVE-2013-2141: - https://git.kernel.org/linus/b9e146d8eb3b9eca - - config GCC_PLUGIN_STRUCTLEAK_BYREF - bool "structs passed by reference" - help - Zero-initialize any structures on the stack that may - be passed by reference and had not already been - explicitly initialized. This can prevent most classes - of uninitialized stack variable exploits and information - exposures, like CVE-2017-1000410: - https://git.kernel.org/linus/06e7e776ca4d3654 - - config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL - bool "anything passed by reference" - help - Zero-initialize any stack variables that may be passed - by reference and had not already been explicitly - initialized. This is intended to eliminate all classes - of uninitialized stack variable exploits and information - exposures. - -endchoice - -config GCC_PLUGIN_STRUCTLEAK_VERBOSE - bool "Report forcefully initialized variables" - depends on GCC_PLUGIN_STRUCTLEAK - depends on !COMPILE_TEST # too noisy - help - This option will cause a warning to be printed each time the - structleak plugin finds a variable it thinks needs to be - initialized. Since not all existing initializers are detected - by the plugin, this can produce false positive warnings. - config GCC_PLUGIN_RANDSTRUCT bool "Randomize layout of sensitive kernel structures" select MODVERSIONS if MODULES @@ -171,59 +109,8 @@ config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE in structures. This reduces the performance hit of RANDSTRUCT at the cost of weakened randomization. -config GCC_PLUGIN_STACKLEAK - bool "Erase the kernel stack before returning from syscalls" - depends on GCC_PLUGINS - depends on HAVE_ARCH_STACKLEAK - help - This option makes the kernel erase the kernel stack before - returning from system calls. That reduces the information which - kernel stack leak bugs can reveal and blocks some uninitialized - stack variable attacks. - - The tradeoff is the performance impact: on a single CPU system kernel - compilation sees a 1% slowdown, other systems and workloads may vary - and you are advised to test this feature on your expected workload - before deploying it. - - This plugin was ported from grsecurity/PaX. More information at: - * https://grsecurity.net/ - * https://pax.grsecurity.net/ - -config STACKLEAK_TRACK_MIN_SIZE - int "Minimum stack frame size of functions tracked by STACKLEAK" - default 100 - range 0 4096 - depends on GCC_PLUGIN_STACKLEAK - help - The STACKLEAK gcc plugin instruments the kernel code for tracking - the lowest border of the kernel stack (and for some other purposes). - It inserts the stackleak_track_stack() call for the functions with - a stack frame size greater than or equal to this parameter. - If unsure, leave the default value 100. - -config STACKLEAK_METRICS - bool "Show STACKLEAK metrics in the /proc file system" - depends on GCC_PLUGIN_STACKLEAK - depends on PROC_FS - help - If this is set, STACKLEAK metrics for every task are available in - the /proc file system. In particular, /proc/<pid>/stack_depth - shows the maximum kernel stack consumption for the current and - previous syscalls. Although this information is not precise, it - can be useful for estimating the STACKLEAK performance impact for - your workloads. - -config STACKLEAK_RUNTIME_DISABLE - bool "Allow runtime disabling of kernel stack erasing" - depends on GCC_PLUGIN_STACKLEAK - help - This option provides 'stack_erasing' sysctl, which can be used in - runtime to control kernel stack erasing for kernels built with - CONFIG_GCC_PLUGIN_STACKLEAK. - config GCC_PLUGIN_ARM_SSP_PER_TASK bool depends on GCC_PLUGINS && ARM -endif +endmenu diff --git a/scripts/gcc-plugins/arm_ssp_per_task_plugin.c b/scripts/gcc-plugins/arm_ssp_per_task_plugin.c index 89c47f57d1ce..8c1af9bdcb1b 100644 --- a/scripts/gcc-plugins/arm_ssp_per_task_plugin.c +++ b/scripts/gcc-plugins/arm_ssp_per_task_plugin.c @@ -36,7 +36,7 @@ static unsigned int arm_pertask_ssp_rtl_execute(void) mask = GEN_INT(sext_hwi(sp_mask, GET_MODE_PRECISION(Pmode))); masked_sp = gen_reg_rtx(Pmode); - emit_insn_before(gen_rtx_SET(masked_sp, + emit_insn_before(gen_rtx_set(masked_sp, gen_rtx_AND(Pmode, stack_pointer_rtx, mask)), diff --git a/scripts/gdb/Makefile b/scripts/gdb/Makefile index 62f5f65becfd..3fca1937d956 100644 --- a/scripts/gdb/Makefile +++ b/scripts/gdb/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only subdir-y := linux diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile index 3df395a9c2ce..9fd3d8ed731a 100644 --- a/scripts/gdb/linux/Makefile +++ b/scripts/gdb/linux/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -ifneq ($(KBUILD_SRC),) +ifneq ($(srctree),.) symlinks := $(patsubst $(srctree)/$(src)/%,%,$(wildcard $(srctree)/$(src)/*.py)) diff --git a/scripts/gdb/linux/clk.py b/scripts/gdb/linux/clk.py new file mode 100644 index 000000000000..061aecfa294e --- /dev/null +++ b/scripts/gdb/linux/clk.py @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) NXP 2019 + +import gdb +import sys + +from linux import utils, lists, constants + +clk_core_type = utils.CachedType("struct clk_core") + + +def clk_core_for_each_child(hlist_head): + return lists.hlist_for_each_entry(hlist_head, + clk_core_type.get_type().pointer(), "child_node") + + +class LxClkSummary(gdb.Command): + """Print clk tree summary + +Output is a subset of /sys/kernel/debug/clk/clk_summary + +No calls are made during printing, instead a (c) if printed after values which +are cached and potentially out of date""" + + def __init__(self): + super(LxClkSummary, self).__init__("lx-clk-summary", gdb.COMMAND_DATA) + + def show_subtree(self, clk, level): + gdb.write("%*s%-*s %7d %8d %8d %11lu%s\n" % ( + level * 3 + 1, "", + 30 - level * 3, + clk['name'].string(), + clk['enable_count'], + clk['prepare_count'], + clk['protect_count'], + clk['rate'], + '(c)' if clk['flags'] & constants.LX_CLK_GET_RATE_NOCACHE else ' ')) + + for child in clk_core_for_each_child(clk['children']): + self.show_subtree(child, level + 1) + + def invoke(self, arg, from_tty): + gdb.write(" enable prepare protect \n") + gdb.write(" clock count count count rate \n") + gdb.write("------------------------------------------------------------------------\n") + for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_root_list")): + self.show_subtree(clk, 0) + for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_orphan_list")): + self.show_subtree(clk, 0) + + +LxClkSummary() + + +class LxClkCoreLookup(gdb.Function): + """Find struct clk_core by name""" + + def __init__(self): + super(LxClkCoreLookup, self).__init__("lx_clk_core_lookup") + + def lookup_hlist(self, hlist_head, name): + for child in clk_core_for_each_child(hlist_head): + if child['name'].string() == name: + return child + result = self.lookup_hlist(child['children'], name) + if result: + return result + + def invoke(self, name): + name = name.string() + return (self.lookup_hlist(gdb.parse_and_eval("clk_root_list"), name) or + self.lookup_hlist(gdb.parse_and_eval("clk_orphan_list"), name)) + + +LxClkCoreLookup() diff --git a/scripts/gdb/linux/config.py b/scripts/gdb/linux/config.py new file mode 100644 index 000000000000..90e1565b1967 --- /dev/null +++ b/scripts/gdb/linux/config.py @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2019 Google LLC. + +import gdb +import zlib + +from linux import utils + + +class LxConfigDump(gdb.Command): + """Output kernel config to the filename specified as the command + argument. Equivalent to 'zcat /proc/config.gz > config.txt' on + a running target""" + + def __init__(self): + super(LxConfigDump, self).__init__("lx-configdump", gdb.COMMAND_DATA, + gdb.COMPLETE_FILENAME) + + def invoke(self, arg, from_tty): + if len(arg) == 0: + filename = "config.txt" + else: + filename = arg + + try: + py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8") + py_config_size = gdb.parse_and_eval( + "sizeof(kernel_config_data) - 1 - 8 * 2") + except gdb.error as e: + raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?") + + inf = gdb.inferiors()[0] + zconfig_buf = utils.read_memoryview(inf, py_config_ptr, + py_config_size).tobytes() + + config_buf = zlib.decompress(zconfig_buf, 16) + with open(filename, 'wb') as f: + f.write(config_buf) + + gdb.write("Dumped config to " + filename + "\n") + + +LxConfigDump() diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index d3319a80788a..1d73083da6cb 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -12,9 +12,12 @@ * */ +#include <linux/clk-provider.h> #include <linux/fs.h> +#include <linux/hrtimer.h> #include <linux/mount.h> #include <linux/of_fdt.h> +#include <linux/threads.h> /* We need to stringify expanded macros so that they can be parsed */ @@ -36,6 +39,9 @@ import gdb +/* linux/clk-provider.h */ +LX_GDBPARSED(CLK_GET_RATE_NOCACHE) + /* linux/fs.h */ LX_VALUE(SB_RDONLY) LX_VALUE(SB_SYNCHRONOUS) @@ -44,6 +50,9 @@ LX_VALUE(SB_DIRSYNC) LX_VALUE(SB_NOATIME) LX_VALUE(SB_NODIRATIME) +/* linux/htimer.h */ +LX_GDBPARSED(hrtimer_resolution) + /* linux/mount.h */ LX_VALUE(MNT_NOSUID) LX_VALUE(MNT_NODEV) @@ -52,8 +61,16 @@ LX_VALUE(MNT_NOATIME) LX_VALUE(MNT_NODIRATIME) LX_VALUE(MNT_RELATIME) +/* linux/threads.h */ +LX_VALUE(NR_CPUS) + /* linux/of_fdt.h> */ LX_VALUE(OF_DT_HEADER) /* Kernel Configs */ +LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS) +LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) +LX_CONFIG(CONFIG_HIGH_RES_TIMERS) +LX_CONFIG(CONFIG_NR_CPUS) LX_CONFIG(CONFIG_OF) +LX_CONFIG(CONFIG_TICK_ONESHOT) diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index ca11e8df31b6..008e62f3190d 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -135,6 +135,7 @@ and can help identify the state of hotplugged CPUs""" gdb.write("Online CPUs : {}\n".format(list(each_online_cpu()))) gdb.write("Active CPUs : {}\n".format(list(each_active_cpu()))) + LxCpus() diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py index 2f335fbd86fd..c487ddf09d38 100644 --- a/scripts/gdb/linux/lists.py +++ b/scripts/gdb/linux/lists.py @@ -16,13 +16,15 @@ import gdb from linux import utils list_head = utils.CachedType("struct list_head") +hlist_head = utils.CachedType("struct hlist_head") +hlist_node = utils.CachedType("struct hlist_node") def list_for_each(head): if head.type == list_head.get_type().pointer(): head = head.dereference() elif head.type != list_head.get_type(): - raise gdb.GdbError("Must be struct list_head not {}" + raise TypeError("Must be struct list_head not {}" .format(head.type)) node = head['next'].dereference() @@ -33,9 +35,24 @@ def list_for_each(head): def list_for_each_entry(head, gdbtype, member): for node in list_for_each(head): - if node.type != list_head.get_type().pointer(): - raise TypeError("Type {} found. Expected struct list_head *." - .format(node.type)) + yield utils.container_of(node, gdbtype, member) + + +def hlist_for_each(head): + if head.type == hlist_head.get_type().pointer(): + head = head.dereference() + elif head.type != hlist_head.get_type(): + raise TypeError("Must be struct hlist_head not {}" + .format(head.type)) + + node = head['first'].dereference() + while node.address: + yield node.address + node = node['next'].dereference() + + +def hlist_for_each_entry(head, gdbtype, member): + for node in hlist_for_each(head): yield utils.container_of(node, gdbtype, member) @@ -110,4 +127,5 @@ class LxListChk(gdb.Command): raise gdb.GdbError("lx-list-check takes one argument") list_check(gdb.parse_and_eval(argv[0])) + LxListChk() diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 2f01a958eb22..6a56bba233a9 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -29,6 +29,7 @@ class LxCmdLine(gdb.Command): def invoke(self, arg, from_tty): gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n") + LxCmdLine() @@ -43,6 +44,7 @@ class LxVersion(gdb.Command): # linux_banner should contain a newline gdb.write(gdb.parse_and_eval("(char *)linux_banner").string()) + LxVersion() @@ -86,6 +88,7 @@ Equivalent to cat /proc/iomem on a running target""" def invoke(self, arg, from_tty): return show_lx_resources("iomem_resource") + LxIOMem() @@ -100,6 +103,7 @@ Equivalent to cat /proc/ioports on a running target""" def invoke(self, arg, from_tty): return show_lx_resources("ioport_resource") + LxIOPorts() @@ -149,7 +153,7 @@ values of that process namespace""" if len(argv) >= 1: try: pid = int(argv[0]) - except: + except gdb.error: raise gdb.GdbError("Provide a PID as integer value") else: pid = 1 @@ -195,6 +199,7 @@ values of that process namespace""" info_opts(FS_INFO, s_flags), info_opts(MNT_INFO, m_flags))) + LxMounts() @@ -259,7 +264,7 @@ class LxFdtDump(gdb.Command): try: f = open(filename, 'wb') - except: + except gdb.error: raise gdb.GdbError("Could not open file to dump fdt") f.write(fdt_buf) @@ -267,4 +272,5 @@ class LxFdtDump(gdb.Command): gdb.write("Dumped fdt blob to " + filename + "\n") + LxFdtDump() diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py new file mode 100644 index 000000000000..39db889b874c --- /dev/null +++ b/scripts/gdb/linux/rbtree.py @@ -0,0 +1,177 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2019 Google LLC. + +import gdb + +from linux import utils + +rb_root_type = utils.CachedType("struct rb_root") +rb_node_type = utils.CachedType("struct rb_node") + + +def rb_first(root): + if root.type == rb_root_type.get_type(): + node = node.address.cast(rb_root_type.get_type().pointer()) + elif root.type != rb_root_type.get_type().pointer(): + raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) + + node = root['rb_node'] + if node is 0: + return None + + while node['rb_left']: + node = node['rb_left'] + + return node + + +def rb_last(root): + if root.type == rb_root_type.get_type(): + node = node.address.cast(rb_root_type.get_type().pointer()) + elif root.type != rb_root_type.get_type().pointer(): + raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) + + node = root['rb_node'] + if node is 0: + return None + + while node['rb_right']: + node = node['rb_right'] + + return node + + +def rb_parent(node): + parent = gdb.Value(node['__rb_parent_color'] & ~3) + return parent.cast(rb_node_type.get_type().pointer()) + + +def rb_empty_node(node): + return node['__rb_parent_color'] == node.address + + +def rb_next(node): + if node.type == rb_node_type.get_type(): + node = node.address.cast(rb_node_type.get_type().pointer()) + elif node.type != rb_node_type.get_type().pointer(): + raise gdb.GdbError("Must be struct rb_node not {}".format(node.type)) + + if rb_empty_node(node): + return None + + if node['rb_right']: + node = node['rb_right'] + while node['rb_left']: + node = node['rb_left'] + return node + + parent = rb_parent(node) + while parent and node == parent['rb_right']: + node = parent + parent = rb_parent(node) + + return parent + + +def rb_prev(node): + if node.type == rb_node_type.get_type(): + node = node.address.cast(rb_node_type.get_type().pointer()) + elif node.type != rb_node_type.get_type().pointer(): + raise gdb.GdbError("Must be struct rb_node not {}".format(node.type)) + + if rb_empty_node(node): + return None + + if node['rb_left']: + node = node['rb_left'] + while node['rb_right']: + node = node['rb_right'] + return node.dereference() + + parent = rb_parent(node) + while parent and node == parent['rb_left'].dereference(): + node = parent + parent = rb_parent(node) + + return parent + + +class LxRbFirst(gdb.Function): + """Lookup and return a node from an RBTree + +$lx_rb_first(root): Return the node at the given index. +If index is omitted, the root node is dereferenced and returned.""" + + def __init__(self): + super(LxRbFirst, self).__init__("lx_rb_first") + + def invoke(self, root): + result = rb_first(root) + if result is None: + raise gdb.GdbError("No entry in tree") + + return result + + +LxRbFirst() + + +class LxRbLast(gdb.Function): + """Lookup and return a node from an RBTree. + +$lx_rb_last(root): Return the node at the given index. +If index is omitted, the root node is dereferenced and returned.""" + + def __init__(self): + super(LxRbLast, self).__init__("lx_rb_last") + + def invoke(self, root): + result = rb_last(root) + if result is None: + raise gdb.GdbError("No entry in tree") + + return result + + +LxRbLast() + + +class LxRbNext(gdb.Function): + """Lookup and return a node from an RBTree. + +$lx_rb_next(node): Return the node at the given index. +If index is omitted, the root node is dereferenced and returned.""" + + def __init__(self): + super(LxRbNext, self).__init__("lx_rb_next") + + def invoke(self, node): + result = rb_next(node) + if result is None: + raise gdb.GdbError("No entry in tree") + + return result + + +LxRbNext() + + +class LxRbPrev(gdb.Function): + """Lookup and return a node from an RBTree. + +$lx_rb_prev(node): Return the node at the given index. +If index is omitted, the root node is dereferenced and returned.""" + + def __init__(self): + super(LxRbPrev, self).__init__("lx_rb_prev") + + def invoke(self, node): + result = rb_prev(node) + if result is None: + raise gdb.GdbError("No entry in tree") + + return result + + +LxRbPrev() diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 004b0ac7fa72..2f5b95f09fa0 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -139,8 +139,12 @@ lx-symbols command.""" saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) # drop all current symbols and reload vmlinux + orig_vmlinux = 'vmlinux' + for obj in gdb.objfiles(): + if obj.filename.endswith('vmlinux'): + orig_vmlinux = obj.filename gdb.execute("symbol-file", to_string=True) - gdb.execute("symbol-file vmlinux") + gdb.execute("symbol-file {0}".format(orig_vmlinux)) self.loaded_modules = [] module_list = modules.module_list() diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index f6ab3ccf698f..0301dc1e0138 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -79,6 +79,7 @@ class LxPs(gdb.Command): pid=task["pid"], comm=task["comm"].string())) + LxPs() @@ -134,4 +135,5 @@ variable.""" else: raise gdb.GdbError("No task of PID " + str(pid)) + LxThreadInfoByPidFunc() diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py new file mode 100644 index 000000000000..071d0dd5a634 --- /dev/null +++ b/scripts/gdb/linux/timerlist.py @@ -0,0 +1,219 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2019 Google LLC. + +import binascii +import gdb + +from linux import constants +from linux import cpus +from linux import rbtree +from linux import utils + +timerqueue_node_type = utils.CachedType("struct timerqueue_node").get_type() +hrtimer_type = utils.CachedType("struct hrtimer").get_type() + + +def ktime_get(): + """Returns the current time, but not very accurately + + We can't read the hardware timer itself to add any nanoseconds + that need to be added since we last stored the time in the + timekeeper. But this is probably good enough for debug purposes.""" + tk_core = gdb.parse_and_eval("&tk_core") + + return tk_core['timekeeper']['tkr_mono']['base'] + + +def print_timer(rb_node, idx): + timerqueue = utils.container_of(rb_node, timerqueue_node_type.pointer(), + "node") + timer = utils.container_of(timerqueue, hrtimer_type.pointer(), "node") + + function = str(timer['function']).split(" ")[1].strip("<>") + softexpires = timer['_softexpires'] + expires = timer['node']['expires'] + now = ktime_get() + + text = " #{}: <{}>, {}, ".format(idx, timer, function) + text += "S:{:02x}\n".format(int(timer['state'])) + text += " # expires at {}-{} nsecs [in {} to {} nsecs]\n".format( + softexpires, expires, softexpires - now, expires - now) + return text + + +def print_active_timers(base): + curr = base['active']['next']['node'] + curr = curr.address.cast(rbtree.rb_node_type.get_type().pointer()) + idx = 0 + while curr: + yield print_timer(curr, idx) + curr = rbtree.rb_next(curr) + idx += 1 + + +def print_base(base): + text = " .base: {}\n".format(base.address) + text += " .index: {}\n".format(base['index']) + + text += " .resolution: {} nsecs\n".format(constants.LX_hrtimer_resolution) + + text += " .get_time: {}\n".format(base['get_time']) + if constants.LX_CONFIG_HIGH_RES_TIMERS: + text += " .offset: {} nsecs\n".format(base['offset']) + text += "active timers:\n" + text += "".join([x for x in print_active_timers(base)]) + return text + + +def print_cpu(hrtimer_bases, cpu, max_clock_bases): + cpu_base = cpus.per_cpu(hrtimer_bases, cpu) + jiffies = gdb.parse_and_eval("jiffies_64") + tick_sched_ptr = gdb.parse_and_eval("&tick_cpu_sched") + ts = cpus.per_cpu(tick_sched_ptr, cpu) + + text = "cpu: {}\n".format(cpu) + for i in xrange(max_clock_bases): + text += " clock {}:\n".format(i) + text += print_base(cpu_base['clock_base'][i]) + + if constants.LX_CONFIG_HIGH_RES_TIMERS: + fmts = [(" .{} : {} nsecs", 'expires_next'), + (" .{} : {}", 'hres_active'), + (" .{} : {}", 'nr_events'), + (" .{} : {}", 'nr_retries'), + (" .{} : {}", 'nr_hangs'), + (" .{} : {}", 'max_hang_time')] + text += "\n".join([s.format(f, cpu_base[f]) for s, f in fmts]) + text += "\n" + + if constants.LX_CONFIG_TICK_ONESHOT: + fmts = [(" .{} : {}", 'nohz_mode'), + (" .{} : {} nsecs", 'last_tick'), + (" .{} : {}", 'tick_stopped'), + (" .{} : {}", 'idle_jiffies'), + (" .{} : {}", 'idle_calls'), + (" .{} : {}", 'idle_sleeps'), + (" .{} : {} nsecs", 'idle_entrytime'), + (" .{} : {} nsecs", 'idle_waketime'), + (" .{} : {} nsecs", 'idle_exittime'), + (" .{} : {} nsecs", 'idle_sleeptime'), + (" .{}: {} nsecs", 'iowait_sleeptime'), + (" .{} : {}", 'last_jiffies'), + (" .{} : {}", 'next_timer'), + (" .{} : {} nsecs", 'idle_expires')] + text += "\n".join([s.format(f, ts[f]) for s, f in fmts]) + text += "\njiffies: {}\n".format(jiffies) + + text += "\n" + + return text + + +def print_tickdevice(td, cpu): + dev = td['evtdev'] + text = "Tick Device: mode: {}\n".format(td['mode']) + if cpu < 0: + text += "Broadcast device\n" + else: + text += "Per CPU device: {}\n".format(cpu) + + text += "Clock Event Device: " + if dev == 0: + text += "<NULL>\n" + return text + + text += "{}\n".format(dev['name']) + text += " max_delta_ns: {}\n".format(dev['max_delta_ns']) + text += " min_delta_ns: {}\n".format(dev['min_delta_ns']) + text += " mult: {}\n".format(dev['mult']) + text += " shift: {}\n".format(dev['shift']) + text += " mode: {}\n".format(dev['state_use_accessors']) + text += " next_event: {} nsecs\n".format(dev['next_event']) + + text += " set_next_event: {}\n".format(dev['set_next_event']) + + members = [('set_state_shutdown', " shutdown: {}\n"), + ('set_state_periodic', " periodic: {}\n"), + ('set_state_oneshot', " oneshot: {}\n"), + ('set_state_oneshot_stopped', " oneshot stopped: {}\n"), + ('tick_resume', " resume: {}\n")] + for member, fmt in members: + if dev[member]: + text += fmt.format(dev[member]) + + text += " event_handler: {}\n".format(dev['event_handler']) + text += " retries: {}\n".format(dev['retries']) + + return text + + +def pr_cpumask(mask): + nr_cpu_ids = 1 + if constants.LX_NR_CPUS > 1: + nr_cpu_ids = gdb.parse_and_eval("nr_cpu_ids") + + inf = gdb.inferiors()[0] + bits = mask['bits'] + num_bytes = (nr_cpu_ids + 7) / 8 + buf = utils.read_memoryview(inf, bits, num_bytes).tobytes() + buf = binascii.b2a_hex(buf) + + chunks = [] + i = num_bytes + while i > 0: + i -= 1 + start = i * 2 + end = start + 2 + chunks.append(buf[start:end]) + if i != 0 and i % 4 == 0: + chunks.append(',') + + extra = nr_cpu_ids % 8 + if 0 < extra <= 4: + chunks[0] = chunks[0][0] # Cut off the first 0 + + return "".join(chunks) + + +class LxTimerList(gdb.Command): + """Print /proc/timer_list""" + + def __init__(self): + super(LxTimerList, self).__init__("lx-timerlist", gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + hrtimer_bases = gdb.parse_and_eval("&hrtimer_bases") + max_clock_bases = gdb.parse_and_eval("HRTIMER_MAX_CLOCK_BASES") + + text = "Timer List Version: gdb scripts\n" + text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format(max_clock_bases) + text += "now at {} nsecs\n".format(ktime_get()) + + for cpu in cpus.each_online_cpu(): + text += print_cpu(hrtimer_bases, cpu, max_clock_bases) + + if constants.LX_CONFIG_GENERIC_CLOCKEVENTS: + if constants.LX_CONFIG_GENERIC_CLOCKEVENTS_BROADCAST: + bc_dev = gdb.parse_and_eval("&tick_broadcast_device") + text += print_tickdevice(bc_dev, -1) + text += "\n" + mask = gdb.parse_and_eval("tick_broadcast_mask") + mask = pr_cpumask(mask) + text += "tick_broadcast_mask: {}\n".format(mask) + if constants.LX_CONFIG_TICK_ONESHOT: + mask = gdb.parse_and_eval("tick_broadcast_oneshot_mask") + mask = pr_cpumask(mask) + text += "tick_broadcast_oneshot_mask: {}\n".format(mask) + text += "\n" + + tick_cpu_devices = gdb.parse_and_eval("&tick_cpu_device") + for cpu in cpus.each_online_cpu(): + tick_dev = cpus.per_cpu(tick_cpu_devices, cpu) + text += print_tickdevice(tick_dev, cpu) + text += "\n" + + gdb.write(text) + + +LxTimerList() diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 50805874cfc3..bc67126118c4 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -66,6 +66,7 @@ Note that TYPE and ELEMENT have to be quoted as strings.""" return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), elementname.string()) + ContainerOf() @@ -148,14 +149,14 @@ def get_gdbserver_type(): def probe_qemu(): try: return gdb.execute("monitor info version", to_string=True) != "" - except: + except gdb.error: return False def probe_kgdb(): try: thread_info = gdb.execute("info thread 2", to_string=True) return "shadowCPU0" in thread_info - except: + except gdb.error: return False global gdbserver_type @@ -172,7 +173,7 @@ def get_gdbserver_type(): def gdb_eval_or_none(expresssion): try: return gdb.parse_and_eval(expresssion) - except: + except gdb.error: return None diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 6e0b0afd888a..eff5a48ac026 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -27,7 +27,11 @@ else: import linux.modules import linux.dmesg import linux.tasks + import linux.config import linux.cpus import linux.lists + import linux.rbtree import linux.proc import linux.constants + import linux.timerlist + import linux.clk diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index 03b7ce97de14..66c314bc5933 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -31,8 +31,8 @@ $(obj)/parse.tab.h: $(src)/parse.y FORCE endif # -I needed for generated C source (shipped source) -HOSTCFLAGS_parse.tab.o := -I$(src) -HOSTCFLAGS_lex.lex.o := -I$(src) +HOSTCFLAGS_parse.tab.o := -I $(srctree)/$(src) +HOSTCFLAGS_lex.lex.o := -I $(srctree)/$(src) # dependencies on generated files need to be listed explicitly $(obj)/lex.lex.o: $(obj)/parse.tab.h diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c index 9f40bcd17d07..e93336baaaed 100644 --- a/scripts/genksyms/keywords.c +++ b/scripts/genksyms/keywords.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only static struct resword { const char *name; int token; diff --git a/scripts/get_dvb_firmware b/scripts/get_dvb_firmware index f3f230225aba..1a90802410bc 100755 --- a/scripts/get_dvb_firmware +++ b/scripts/get_dvb_firmware @@ -1,22 +1,9 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0-or-later # DVB firmware extractor # # (c) 2004 Andrew de Quincey # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. use File::Temp qw/ tempdir /; use IO::Handle; diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 7c5dc31c1d95..3f327e21f60e 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -76,15 +76,13 @@ savedefconfig: $(obj)/conf defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) $< $(silent) --defconfig $(Kconfig) -else -ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) +else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) else @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) endif -endif %_defconfig: $(obj)/conf $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) @@ -147,8 +145,8 @@ common-objs := confdata.o expr.o lexer.lex.o parser.tab.o preprocess.o \ symbol.o $(obj)/lexer.lex.o: $(obj)/parser.tab.h -HOSTCFLAGS_lexer.lex.o := -I$(src) -HOSTCFLAGS_parser.tab.o := -I$(src) +HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src) +HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src) # conf: Used for defconfig, oldconfig and related targets hostprogs-y += conf diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 08ba146a83c5..6006154d36bd 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -3,6 +3,7 @@ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> */ +#include <sys/mman.h> #include <sys/stat.h> #include <ctype.h> #include <errno.h> @@ -36,6 +37,52 @@ static bool is_dir(const char *path) return S_ISDIR(st.st_mode); } +/* return true if the given two files are the same, false otherwise */ +static bool is_same(const char *file1, const char *file2) +{ + int fd1, fd2; + struct stat st1, st2; + void *map1, *map2; + bool ret = false; + + fd1 = open(file1, O_RDONLY); + if (fd1 < 0) + return ret; + + fd2 = open(file2, O_RDONLY); + if (fd2 < 0) + goto close1; + + ret = fstat(fd1, &st1); + if (ret) + goto close2; + ret = fstat(fd2, &st2); + if (ret) + goto close2; + + if (st1.st_size != st2.st_size) + goto close2; + + map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); + if (map1 == MAP_FAILED) + goto close2; + + map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); + if (map2 == MAP_FAILED) + goto close2; + + if (bcmp(map1, map2, st1.st_size)) + goto close2; + + ret = true; +close2: + close(fd2); +close1: + close(fd1); + + return ret; +} + /* * Create the parent directory of the given path. * @@ -179,7 +226,7 @@ const char *conf_get_configname(void) return name ? name : ".config"; } -const char *conf_get_autoconfig_name(void) +static const char *conf_get_autoconfig_name(void) { char *name = getenv("KCONFIG_AUTOCONFIG"); @@ -194,7 +241,7 @@ char *conf_get_default_confname(void) name = expand_string(conf_defname); env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), "%s/%s", env, name); if (is_present(fullname)) return fullname; } @@ -817,40 +864,35 @@ int conf_write(const char *name) FILE *out; struct symbol *sym; struct menu *menu; - const char *basename; const char *str; - char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; + char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; char *env; + bool need_newline = false; + + if (!name) + name = conf_get_configname(); + + if (!*name) { + fprintf(stderr, "config name is empty\n"); + return -1; + } + + if (is_dir(name)) { + fprintf(stderr, "%s: Is a directory\n", name); + return -1; + } + + if (make_parent_dir(name)) + return -1; - dirname[0] = 0; - if (name && name[0]) { - char *slash; - - if (is_dir(name)) { - strcpy(dirname, name); - strcat(dirname, "/"); - basename = conf_get_configname(); - } else if ((slash = strrchr(name, '/'))) { - int size = slash - name + 1; - memcpy(dirname, name, size); - dirname[size] = 0; - if (slash[1]) - basename = slash + 1; - else - basename = conf_get_configname(); - } else - basename = name; - } else - basename = conf_get_configname(); - - sprintf(newname, "%s%s", dirname, basename); env = getenv("KCONFIG_OVERWRITECONFIG"); - if (!env || !*env) { - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(tmpname, "w"); - } else { + if (env && *env) { *tmpname = 0; - out = fopen(newname, "w"); + out = fopen(name, "w"); + } else { + snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", + name, (int)getpid()); + out = fopen(tmpname, "w"); } if (!out) return 1; @@ -871,12 +913,16 @@ int conf_write(const char *name) "#\n" "# %s\n" "#\n", str); + need_newline = false; } else if (!(sym->flags & SYMBOL_CHOICE)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) goto next; + if (need_newline) { + fprintf(out, "\n"); + need_newline = false; + } sym->flags &= ~SYMBOL_WRITE; - conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); } @@ -888,6 +934,12 @@ next: if (menu->next) menu = menu->next; else while ((menu = menu->parent)) { + if (!menu->sym && menu_is_visible(menu) && + menu != &rootmenu) { + str = menu_get_prompt(menu); + fprintf(out, "# end of %s\n", str); + need_newline = true; + } if (menu->next) { menu = menu->next; break; @@ -897,14 +949,20 @@ next: fclose(out); if (*tmpname) { - strcat(dirname, basename); - strcat(dirname, ".old"); - rename(newname, dirname); - if (rename(tmpname, newname)) + if (is_same(name, tmpname)) { + conf_message("No change to %s", name); + unlink(tmpname); + sym_set_change_count(0); + return 0; + } + + snprintf(oldname, sizeof(oldname), "%s.old", name); + rename(name, oldname); + if (rename(tmpname, name)) return 1; } - conf_message("configuration written to %s", newname); + conf_message("configuration written to %s", name); sym_set_change_count(0); @@ -917,8 +975,6 @@ static int conf_write_dep(const char *name) struct file *file; FILE *out; - if (!name) - name = ".kconfig.d"; out = fopen("..config.tmp", "w"); if (!out) return 1; diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 5d4ecf309ee4..e36b342f1065 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -638,7 +638,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; - const gchar *intro_text = + const gchar *intro_text = "Welcome to gkc, the GTK+ graphical configuration tool\n" "For each option, a blank box indicates the feature is disabled, a\n" "check indicates it is enabled, and a dot indicates that it is to\n" diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index c9df1c8b9824..6354c905b006 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -378,7 +378,8 @@ FILE *zconf_fopen(const char *name) if (!f && name != NULL && name[0] != '/') { env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), + "%s/%s", env, name); f = fopen(fullname, "r"); } } diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index d871539e4b45..cbc7658ee27d 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -49,7 +49,6 @@ const char *zconf_curname(void); /* confdata.c */ const char *conf_get_configname(void); -const char *conf_get_autoconfig_name(void); char *conf_get_default_confname(void); void sym_set_change_count(int count); void sym_add_change_count(int count); diff --git a/scripts/kconfig/lxdialog/BIG.FAT.WARNING b/scripts/kconfig/lxdialog/BIG.FAT.WARNING index a8999d82bdb3..7cb5a7ec93d2 100644 --- a/scripts/kconfig/lxdialog/BIG.FAT.WARNING +++ b/scripts/kconfig/lxdialog/BIG.FAT.WARNING @@ -1,4 +1,4 @@ This is NOT the official version of dialog. This version has been significantly modified from the original. It is for use by the Linux -kernel configuration script. Please do not bother Savio Lam with +kernel configuration script. Please do not bother Savio Lam with questions about this program. diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 5f8c82a4cb08..694091f3ef9d 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -936,7 +936,7 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); + show_textbox(NULL, "Can't create file!", 5, 60); break; case 1: show_helptext("Save Alternate Configuration", save_config_help); diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh index 001559ef0a60..001559ef0a60 100644..100755 --- a/scripts/kconfig/nconf-cfg.sh +++ b/scripts/kconfig/nconf-cfg.sh diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index ac92c0ded6c5..cbafe3bf082e 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1438,8 +1438,7 @@ static void conf_save(void) set_config_filename(dialog_input_result); return; } - btn_dialog(main_window, "Can't create file! " - "Probably a nonexistent directory.", + btn_dialog(main_window, "Can't create file!", 1, "<OK>"); break; case 1: diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig index 0e4c8750ab65..c6f4adec76d1 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only source "Kconfig.inc1" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 index 00e408d653fc..01cbf0d69cce 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 index 349ea2db15dc..82351075ab1b 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only source "Kconfig.inc3" diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 index 0e4c8750ab65..c6f4adec76d1 100644 --- a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only source "Kconfig.inc1" diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index dc0e8c5a1402..a7124f895b24 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -35,7 +35,7 @@ set -e info() { if [ "${quiet}" != "silent_" ]; then - printf " %-7s %s\n" ${1} ${2} + printf " %-7s %s\n" "${1}" "${2}" fi } @@ -91,6 +91,25 @@ vmlinux_link() fi } +# generate .BTF typeinfo from DWARF debuginfo +gen_btf() +{ + local pahole_ver; + + if ! [ -x "$(command -v ${PAHOLE})" ]; then + info "BTF" "${1}: pahole (${PAHOLE}) is not available" + return 0 + fi + + pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/') + if [ "${pahole_ver}" -lt "113" ]; then + info "BTF" "${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13" + return 0 + fi + + info "BTF" ${1} + LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} +} # Create ${2} .o file with all symbols from the ${1} object file kallsyms() @@ -193,6 +212,9 @@ modpost_link vmlinux.o # modpost vmlinux.o to check for section mismatches ${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o +info MODINFO modules.builtin.modinfo +${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo + kallsymso="" kallsyms_vmlinux="" if [ -n "${CONFIG_KALLSYMS}" ]; then @@ -248,6 +270,10 @@ fi info LD vmlinux vmlinux_link "${kallsymso}" vmlinux +if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then + gen_btf vmlinux +fi + if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then info SORTEX vmlinux sortextable vmlinux diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 412f13fdff52..4d0faebb1719 100755 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -7,33 +7,11 @@ # Usage # $1 - Kernel src directory -# Only overwrite automatically generated Makefiles -# (so we do not overwrite kernel Makefile) -if test -e Makefile && ! grep -q Automatically Makefile -then - exit 0 -fi if [ "${quiet}" != "silent_" ]; then echo " GEN Makefile" fi cat << EOF > Makefile -# Automatically generated by $0: don't edit - -ifeq ("\$(origin V)", "command line") -VERBOSE := \$(V) -endif -ifneq (\$(VERBOSE),1) -Q := @ -endif - -MAKEFLAGS += --no-print-directory - -.PHONY: __sub-make \$(MAKECMDGOALS) - -__sub-make: - \$(Q)\$(MAKE) -C $1 O=\$(CURDIR) \$(MAKECMDGOALS) - -\$(filter-out __sub-make, \$(MAKECMDGOALS)): __sub-make - @: +# Automatically generated by $(realpath $0): don't edit +include $(realpath $1/Makefile) EOF diff --git a/scripts/modules-check.sh b/scripts/modules-check.sh new file mode 100755 index 000000000000..39e8cb36ba19 --- /dev/null +++ b/scripts/modules-check.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +set -e + +# Check uniqueness of module names +check_same_name_modules() +{ + for m in $(sed 's:.*/::' modules.order | sort | uniq -d) + do + echo "warning: same module names found:" >&2 + sed -n "/\/$m/s:^kernel/: :p" modules.order >&2 + done +} + +check_same_name_modules diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 2c6de21e5152..27b42d5b6c4f 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # Makefile for the different targets used to generate full packages of a kernel # It uses the generic clean infrastructure of kbuild diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 68841d01162c..d24759214efd 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -397,6 +397,9 @@ if ($arch eq "x86_64") { } elsif ($arch eq "nds32") { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$"; $alignment = 2; +} elsif ($arch eq "csky") { + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_CKCORE_PCREL_JSR_IMM26BY2\\s+_mcount\$"; + $alignment = 2; } else { die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; } @@ -493,7 +496,7 @@ sub update_funcs # # Step 2: find the sections and mcount call sites # -open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump"; +open(IN, "LANG=C $objdump -hdr $inputfile|") || die "error running $objdump"; my $text; diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile index b3048b894a39..59494e14989b 100644 --- a/scripts/selinux/Makefile +++ b/scripts/selinux/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only subdir-y := mdp genheaders diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index 1ceedea847dd..544ca126a8a8 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c @@ -9,7 +9,6 @@ #include <string.h> #include <errno.h> #include <ctype.h> -#include <sys/socket.h> struct security_class_mapping { const char *name; diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh index 0b86c47baf7d..2dccf141241d 100755 --- a/scripts/selinux/install_policy.sh +++ b/scripts/selinux/install_policy.sh @@ -1,30 +1,61 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 +set -e if [ `id -u` -ne 0 ]; then echo "$0: must be root to install the selinux policy" exit 1 fi + SF=`which setfiles` if [ $? -eq 1 ]; then - if [ -f /sbin/setfiles ]; then - SF="/usr/setfiles" - else - echo "no selinux tools installed: setfiles" - exit 1 - fi + echo "Could not find setfiles" + echo "Do you have policycoreutils installed?" + exit 1 fi -cd mdp - CP=`which checkpolicy` +if [ $? -eq 1 ]; then + echo "Could not find checkpolicy" + echo "Do you have checkpolicy installed?" + exit 1 +fi VERS=`$CP -V | awk '{print $1}'` -./mdp policy.conf file_contexts -$CP -o policy.$VERS policy.conf +ENABLED=`which selinuxenabled` +if [ $? -eq 1 ]; then + echo "Could not find selinuxenabled" + echo "Do you have libselinux-utils installed?" + exit 1 +fi + +if selinuxenabled; then + echo "SELinux is already enabled" + echo "This prevents safely relabeling all files." + echo "Boot with selinux=0 on the kernel command-line or" + echo "SELINUX=disabled in /etc/selinux/config." + exit 1 +fi + +cd mdp +./mdp -m policy.conf file_contexts +$CP -U allow -M -o policy.$VERS policy.conf mkdir -p /etc/selinux/dummy/policy mkdir -p /etc/selinux/dummy/contexts/files +echo "__default__:user_u:s0" > /etc/selinux/dummy/seusers +echo "base_r:base_t:s0" > /etc/selinux/dummy/contexts/failsafe_context +echo "base_r:base_t:s0 base_r:base_t:s0" > /etc/selinux/dummy/default_contexts +cat > /etc/selinux/dummy/contexts/x_contexts <<EOF +client * user_u:base_r:base_t:s0 +property * user_u:object_r:base_t:s0 +extension * user_u:object_r:base_t:s0 +selection * user_u:object_r:base_t:s0 +event * user_u:object_r:base_t:s0 +EOF +touch /etc/selinux/dummy/contexts/virtual_domain_context +touch /etc/selinux/dummy/contexts/virtual_image_context + cp file_contexts /etc/selinux/dummy/contexts/files cp dbus_contexts /etc/selinux/dummy/contexts cp policy.$VERS /etc/selinux/dummy/policy @@ -33,37 +64,22 @@ FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts if [ ! -d /etc/selinux ]; then mkdir -p /etc/selinux fi -if [ ! -f /etc/selinux/config ]; then - cat > /etc/selinux/config << EOF -SELINUX=enforcing +if [ -f /etc/selinux/config ]; then + echo "/etc/selinux/config exists, moving to /etc/selinux/config.bak." + mv /etc/selinux/config /etc/selinux/config.bak +fi +echo "Creating new /etc/selinux/config for dummy policy." +cat > /etc/selinux/config << EOF +SELINUX=permissive SELINUXTYPE=dummy EOF -else - TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}` - if [ "eq$TYPE" != "eqdummy" ]; then - selinuxenabled - if [ $? -eq 0 ]; then - echo "SELinux already enabled with a non-dummy policy." - echo "Exiting. Please install policy by hand if that" - echo "is what you REALLY want." - exit 1 - fi - mv /etc/selinux/config /etc/selinux/config.mdpbak - grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config - echo "SELINUXTYPE=dummy" >> /etc/selinux/config - fi -fi cd /etc/selinux/dummy/contexts/files -$SF file_contexts / +$SF -F file_contexts / -mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}` -$SF file_contexts $mounts +mounts=`cat /proc/$$/mounts | \ + egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ + awk '{ print $2 '}` +$SF -F file_contexts $mounts - -dodev=`cat /proc/$$/mounts | grep "/dev "` -if [ "eq$dodev" != "eq" ]; then - mount --move /dev /mnt - $SF file_contexts /dev - mount --move /mnt /dev -fi +echo "-F" > /.autorelabel diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile index e9c92db7e2a3..8a1269a9d0ba 100644 --- a/scripts/selinux/mdp/Makefile +++ b/scripts/selinux/mdp/Makefile @@ -2,7 +2,7 @@ hostprogs-y := mdp HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ - -I$(srctree)/security/selinux/include + -I$(srctree)/security/selinux/include -I$(objtree)/include always := $(hostprogs-y) clean-files := policy.* file_contexts diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c index 073fe7537f6c..18fd6143888b 100644 --- a/scripts/selinux/mdp/mdp.c +++ b/scripts/selinux/mdp/mdp.c @@ -32,7 +32,7 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> -#include <sys/socket.h> +#include <linux/kconfig.h> static void usage(char *name) { @@ -95,10 +95,31 @@ int main(int argc, char *argv[]) } fprintf(fout, "\n"); - /* NOW PRINT OUT MLS STUFF */ + /* print out mls declarations and constraints */ if (mls) { - printf("MLS not yet implemented\n"); - exit(1); + fprintf(fout, "sensitivity s0;\n"); + fprintf(fout, "sensitivity s1;\n"); + fprintf(fout, "dominance { s0 s1 }\n"); + fprintf(fout, "category c0;\n"); + fprintf(fout, "category c1;\n"); + fprintf(fout, "level s0:c0.c1;\n"); + fprintf(fout, "level s1:c0.c1;\n"); +#define SYSTEMLOW "s0" +#define SYSTEMHIGH "s1:c0.c1" + for (i = 0; secclass_map[i].name; i++) { + struct security_class_mapping *map = &secclass_map[i]; + + fprintf(fout, "mlsconstrain %s {\n", map->name); + for (j = 0; map->perms[j]; j++) + fprintf(fout, "\t%s\n", map->perms[j]); + /* + * This requires all subjects and objects to be + * single-level (l2 eq h2), and that the subject + * level dominate the object level (h1 dom h2) + * in order to have any permissions to it. + */ + fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n"); + } } /* types, roles, and allows */ @@ -108,34 +129,127 @@ int main(int argc, char *argv[]) for (i = 0; secclass_map[i].name; i++) fprintf(fout, "allow base_t base_t:%s *;\n", secclass_map[i].name); - fprintf(fout, "user user_u roles { base_r };\n"); - fprintf(fout, "\n"); + fprintf(fout, "user user_u roles { base_r }"); + if (mls) + fprintf(fout, " level %s range %s - %s", SYSTEMLOW, + SYSTEMLOW, SYSTEMHIGH); + fprintf(fout, ";\n"); + +#define SUBJUSERROLETYPE "user_u:base_r:base_t" +#define OBJUSERROLETYPE "user_u:object_r:base_t" /* default sids */ for (i = 1; i < initial_sid_to_string_len; i++) - fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); + fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", + initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); fprintf(fout, "\n"); - fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); +#define FS_USE(behavior, fstype) \ + fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \ + behavior, fstype, mls ? ":" SYSTEMLOW : "") + + /* + * Filesystems whose inode labels can be fetched via getxattr. + */ +#ifdef CONFIG_EXT2_FS_SECURITY + FS_USE("xattr", "ext2"); +#endif +#ifdef CONFIG_EXT4_FS_SECURITY +#ifdef CONFIG_EXT4_USE_FOR_EXT2 + FS_USE("xattr", "ext2"); +#endif + FS_USE("xattr", "ext3"); + FS_USE("xattr", "ext4"); +#endif +#ifdef CONFIG_JFS_SECURITY + FS_USE("xattr", "jfs"); +#endif +#ifdef CONFIG_REISERFS_FS_SECURITY + FS_USE("xattr", "reiserfs"); +#endif +#ifdef CONFIG_JFFS2_FS_SECURITY + FS_USE("xattr", "jffs2"); +#endif +#ifdef CONFIG_XFS_FS + FS_USE("xattr", "xfs"); +#endif +#ifdef CONFIG_GFS2_FS + FS_USE("xattr", "gfs2"); +#endif +#ifdef CONFIG_BTRFS_FS + FS_USE("xattr", "btrfs"); +#endif +#ifdef CONFIG_F2FS_FS_SECURITY + FS_USE("xattr", "f2fs"); +#endif +#ifdef CONFIG_OCFS2_FS + FS_USE("xattr", "ocsfs2"); +#endif +#ifdef CONFIG_OVERLAY_FS + FS_USE("xattr", "overlay"); +#endif +#ifdef CONFIG_SQUASHFS_XATTR + FS_USE("xattr", "squashfs"); +#endif + + /* + * Filesystems whose inodes are labeled from allocating task. + */ + FS_USE("task", "pipefs"); + FS_USE("task", "sockfs"); - fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); + /* + * Filesystems whose inode labels are computed from both + * the allocating task and the superblock label. + */ +#ifdef CONFIG_UNIX98_PTYS + FS_USE("trans", "devpts"); +#endif +#ifdef CONFIG_HUGETLBFS + FS_USE("trans", "hugetlbfs"); +#endif +#ifdef CONFIG_TMPFS + FS_USE("trans", "tmpfs"); +#endif +#ifdef CONFIG_DEVTMPFS + FS_USE("trans", "devtmpfs"); +#endif +#ifdef CONFIG_POSIX_MQUEUE + FS_USE("trans", "mqueue"); +#endif - fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); - fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); +#define GENFSCON(fstype, prefix) \ + fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \ + fstype, prefix, mls ? ":" SYSTEMLOW : "") - fprintf(fout, "genfscon proc / user_u:base_r:base_t\n"); + /* + * Filesystems whose inodes are labeled from path prefix match + * relative to the filesystem root. Depending on the filesystem, + * only a single label for all inodes may be supported. Here + * we list the filesystem types for which per-file labeling is + * supported using genfscon; any other filesystem type can also + * be added by only with a single entry for all of its inodes. + */ +#ifdef CONFIG_PROC_FS + GENFSCON("proc", "/"); +#endif +#ifdef CONFIG_SECURITY_SELINUX + GENFSCON("selinuxfs", "/"); +#endif +#ifdef CONFIG_SYSFS + GENFSCON("sysfs", "/"); +#endif +#ifdef CONFIG_DEBUG_FS + GENFSCON("debugfs", "/"); +#endif +#ifdef CONFIG_TRACING + GENFSCON("tracefs", "/"); +#endif +#ifdef CONFIG_PSTORE + GENFSCON("pstore", "/"); +#endif + GENFSCON("cgroup", "/"); + GENFSCON("cgroup2", "/"); fclose(fout); @@ -144,8 +258,8 @@ int main(int argc, char *argv[]) printf("Wrote policy, but cannot open %s for writing\n", ctxout); usage(argv[0]); } - fprintf(fout, "/ user_u:base_r:base_t\n"); - fprintf(fout, "/.* user_u:base_r:base_t\n"); + fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); + fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); fclose(fout); return 0; diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py index 4fe392e507fb..33df646618e2 100755 --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py @@ -32,7 +32,7 @@ class SPDXdata(object): def read_spdxdata(repo): # The subdirectories of LICENSES in the kernel source - license_dirs = [ "preferred", "other", "exceptions" ] + license_dirs = [ "preferred", "deprecated", "exceptions", "dual" ] lictree = repo.head.commit.tree['LICENSES'] spdx = SPDXdata() diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index 067459760a7b..f6a5c0bae31e 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -532,6 +532,7 @@ sub check_needs() check_program("dot", 1); check_program("convert", 1); check_program("rsvg-convert", 1) if ($pdf); + check_program("latexmk", 1) if ($pdf); check_distros(); diff --git a/scripts/tags.sh b/scripts/tags.sh index f470d9919ed7..d46be47633af 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only # Generate tags or cscope files # Usage tags.sh <mode> # @@ -19,7 +20,7 @@ ignore="$ignore ( -name *.mod.c ) -prune -o" # Do not use full path if we do not use O=.. builds # Use make O=. {tags|cscope} # to force full paths for a non-O= build -if [ "${KBUILD_SRC}" = "" ]; then +if [ "${srctree}" = "." -o -z "${srctree}" ]; then tree= else tree=${srctree}/ |