aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.build12
-rw-r--r--scripts/Makefile.host2
-rw-r--r--scripts/Makefile.lib2
-rw-r--r--scripts/Makefile.modbuiltin2
-rw-r--r--scripts/Makefile.modpost2
-rw-r--r--scripts/Makefile.ubsan1
-rw-r--r--scripts/atomic/gen-atomics.sh2
-rwxr-xr-xscripts/bpf_helpers_doc.py8
-rwxr-xr-xscripts/checkpatch.pl20
-rw-r--r--scripts/coccinelle/api/stream_open.cocci363
-rw-r--r--scripts/coccinelle/free/put_device.cocci1
-rw-r--r--scripts/coccinelle/misc/badty.cocci2
-rwxr-xr-xscripts/documentation-file-ref-check32
-rw-r--r--scripts/gcc-plugins/Kconfig126
-rw-r--r--scripts/gcc-plugins/arm_ssp_per_task_plugin.c2
-rw-r--r--scripts/gdb/linux/Makefile2
-rw-r--r--scripts/gdb/linux/clk.py76
-rw-r--r--scripts/gdb/linux/config.py44
-rw-r--r--scripts/gdb/linux/constants.py.in17
-rw-r--r--scripts/gdb/linux/cpus.py1
-rw-r--r--scripts/gdb/linux/lists.py26
-rw-r--r--scripts/gdb/linux/proc.py10
-rw-r--r--scripts/gdb/linux/rbtree.py177
-rw-r--r--scripts/gdb/linux/symbols.py6
-rw-r--r--scripts/gdb/linux/tasks.py2
-rw-r--r--scripts/gdb/linux/timerlist.py219
-rw-r--r--scripts/gdb/linux/utils.py7
-rw-r--r--scripts/gdb/vmlinux-gdb.py4
-rw-r--r--scripts/kconfig/confdata.c121
-rw-r--r--scripts/kconfig/gconf.c2
-rw-r--r--scripts/kconfig/lexer.l3
-rw-r--r--scripts/kconfig/lkc.h1
-rw-r--r--scripts/kconfig/lxdialog/BIG.FAT.WARNING2
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c3
-rw-r--r--scripts/kconfig/mconf.c2
-rwxr-xr-x[-rw-r--r--]scripts/kconfig/nconf-cfg.sh0
-rw-r--r--scripts/kconfig/nconf.c5
-rw-r--r--scripts/kconfig/nconf.gui.c3
-rwxr-xr-xscripts/link-vmlinux.sh28
-rwxr-xr-xscripts/mkmakefile26
-rw-r--r--scripts/mod/modpost.c2
-rwxr-xr-xscripts/recordmcount.pl5
-rw-r--r--scripts/selinux/genheaders/genheaders.c1
-rwxr-xr-xscripts/selinux/install_policy.sh92
-rw-r--r--scripts/selinux/mdp/Makefile2
-rw-r--r--scripts/selinux/mdp/mdp.c166
-rwxr-xr-xscripts/sphinx-pre-install1
-rwxr-xr-xscripts/tags.sh2
48 files changed, 1343 insertions, 292 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 2554a15ecf2b..ae9cf740633e 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -199,11 +199,8 @@ sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
199 "$(if $(part-of-module),1,0)" "$(@)"; 199 "$(if $(part-of-module),1,0)" "$(@)";
200recordmcount_source := $(srctree)/scripts/recordmcount.pl 200recordmcount_source := $(srctree)/scripts/recordmcount.pl
201endif # BUILD_C_RECORDMCOUNT 201endif # BUILD_C_RECORDMCOUNT
202cmd_record_mcount = \ 202cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \
203 if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \ 203 $(sub_cmd_record_mcount))
204 "$(CC_FLAGS_FTRACE)" ]; then \
205 $(sub_cmd_record_mcount) \
206 fi
207endif # CC_USING_RECORD_MCOUNT 204endif # CC_USING_RECORD_MCOUNT
208endif # CONFIG_FTRACE_MCOUNT_RECORD 205endif # CONFIG_FTRACE_MCOUNT_RECORD
209 206
@@ -225,6 +222,9 @@ endif
225ifdef CONFIG_RETPOLINE 222ifdef CONFIG_RETPOLINE
226 objtool_args += --retpoline 223 objtool_args += --retpoline
227endif 224endif
225ifdef CONFIG_X86_SMAP
226 objtool_args += --uaccess
227endif
228 228
229# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory 229# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
230# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file 230# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
@@ -504,7 +504,7 @@ existing-targets := $(wildcard $(sort $(targets)))
504 504
505-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) 505-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
506 506
507ifneq ($(KBUILD_SRC),) 507ifneq ($(srctree),.)
508# Create directories for object files if they do not exist 508# Create directories for object files if they do not exist
509obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets)))) 509obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets))))
510# If targets exist, their directories apparently exist. Skip mkdir. 510# If targets exist, their directories apparently exist. Skip mkdir.
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index a115259b57e7..73b804197fca 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -71,7 +71,7 @@ __hostc_flags = $(_hostc_flags)
71__hostcxx_flags = $(_hostcxx_flags) 71__hostcxx_flags = $(_hostcxx_flags)
72 72
73ifeq ($(KBUILD_EXTMOD),) 73ifeq ($(KBUILD_EXTMOD),)
74ifneq ($(KBUILD_SRC),) 74ifneq ($(srctree),.)
75__hostc_flags = -I$(obj) $(call flags,_hostc_flags) 75__hostc_flags = -I$(obj) $(call flags,_hostc_flags)
76__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags) 76__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags)
77endif 77endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 8a1f64f17740..41e98fa66b91 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -144,7 +144,7 @@ __cpp_flags = $(_cpp_flags)
144# If building the kernel in a separate objtree expand all occurrences 144# If building the kernel in a separate objtree expand all occurrences
145# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). 145# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
146ifeq ($(KBUILD_EXTMOD),) 146ifeq ($(KBUILD_EXTMOD),)
147ifneq ($(KBUILD_SRC),) 147ifneq ($(srctree),.)
148 148
149# -I$(obj) locates generated .h files 149# -I$(obj) locates generated .h files
150# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files 150# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
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
15 15
16include scripts/Kbuild.include 16include scripts/Kbuild.include
17 17
18ifneq ($(KBUILD_SRC),) 18ifneq ($(srctree),.)
19# Create output directory if not already present 19# Create output directory if not already present
20_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) 20_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
21endif 21endif
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 \
78 $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \ 78 $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \
79 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ 79 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
80 $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ 80 $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
81 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) 81 $(if $(KBUILD_MODPOST_WARN),-w)
82 82
83MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS))) 83MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS)))
84 84
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
3 CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift) 3 CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift)
4 CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero) 4 CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero)
5 CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable) 5 CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable)
6 CFLAGS_UBSAN += $(call cc-option, -fsanitize=vla-bound)
7 CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow) 6 CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow)
8 CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds) 7 CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds)
9 CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size) 8 CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size)
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
13gen-atomic-fallback.sh linux/atomic-fallback.h 13gen-atomic-fallback.sh linux/atomic-fallback.h
14EOF 14EOF
15while read script header; do 15while read script header; do
16 ${ATOMICDIR}/${script} ${ATOMICTBL} > ${LINUXDIR}/include/${header} 16 /bin/sh ${ATOMICDIR}/${script} ${ATOMICTBL} > ${LINUXDIR}/include/${header}
17 HASH="$(sha1sum ${LINUXDIR}/include/${header})" 17 HASH="$(sha1sum ${LINUXDIR}/include/${header})"
18 HASH="${HASH%% *}" 18 HASH="${HASH%% *}"
19 printf "// %s\n" "${HASH}" >> ${LINUXDIR}/include/${header} 19 printf "// %s\n" "${HASH}" >> ${LINUXDIR}/include/${header}
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 @@
1#!/usr/bin/python3 1#!/usr/bin/python3
2# SPDX-License-Identifier: GPL-2.0-only 2# SPDX-License-Identifier: GPL-2.0-only
3# 3#
4# Copyright (C) 2018 Netronome Systems, Inc. 4# Copyright (C) 2018-2019 Netronome Systems, Inc.
5 5
6# In case user attempts to run with Python 2. 6# In case user attempts to run with Python 2.
7from __future__ import print_function 7from __future__ import print_function
@@ -39,7 +39,7 @@ class Helper(object):
39 Break down helper function protocol into smaller chunks: return type, 39 Break down helper function protocol into smaller chunks: return type,
40 name, distincts arguments. 40 name, distincts arguments.
41 """ 41 """
42 arg_re = re.compile('((const )?(struct )?(\w+|...))( (\**)(\w+))?$') 42 arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$')
43 res = {} 43 res = {}
44 proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') 44 proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$')
45 45
@@ -54,8 +54,8 @@ class Helper(object):
54 capture = arg_re.match(a) 54 capture = arg_re.match(a)
55 res['args'].append({ 55 res['args'].append({
56 'type' : capture.group(1), 56 'type' : capture.group(1),
57 'star' : capture.group(6), 57 'star' : capture.group(5),
58 'name' : capture.group(7) 58 'name' : capture.group(6)
59 }) 59 })
60 60
61 return res 61 return res
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 5b756278df13..bb28b178d929 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2687,6 +2687,24 @@ sub process {
2687 } else { 2687 } else {
2688 $signatures{$sig_nospace} = 1; 2688 $signatures{$sig_nospace} = 1;
2689 } 2689 }
2690
2691# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
2692 if ($sign_off =~ /^co-developed-by:$/i) {
2693 if ($email eq $author) {
2694 WARN("BAD_SIGN_OFF",
2695 "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
2696 }
2697 if (!defined $lines[$linenr]) {
2698 WARN("BAD_SIGN_OFF",
2699 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
2700 } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
2701 WARN("BAD_SIGN_OFF",
2702 "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2703 } elsif ($1 ne $email) {
2704 WARN("BAD_SIGN_OFF",
2705 "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2706 }
2707 }
2690 } 2708 }
2691 2709
2692# Check email subject for common tools that don't need to be mentioned 2710# Check email subject for common tools that don't need to be mentioned
@@ -5977,7 +5995,7 @@ sub process {
5977 while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { 5995 while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
5978 $specifier = $1; 5996 $specifier = $1;
5979 $extension = $2; 5997 $extension = $2;
5980 if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) { 5998 if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) {
5981 $bad_specifier = $specifier; 5999 $bad_specifier = $specifier;
5982 last; 6000 last;
5983 } 6001 }
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 @@
1// SPDX-License-Identifier: GPL-2.0
2// Author: Kirill Smelkov (kirr@nexedi.com)
3//
4// Search for stream-like files that are using nonseekable_open and convert
5// them to stream_open. A stream-like file is a file that does not use ppos in
6// its read and write. Rationale for the conversion is to avoid deadlock in
7// between read and write.
8
9virtual report
10virtual patch
11virtual explain // explain decisions in the patch (SPFLAGS="-D explain")
12
13// stream-like reader & writer - ones that do not depend on f_pos.
14@ stream_reader @
15identifier readstream, ppos;
16identifier f, buf, len;
17type loff_t;
18@@
19 ssize_t readstream(struct file *f, char *buf, size_t len, loff_t *ppos)
20 {
21 ... when != ppos
22 }
23
24@ stream_writer @
25identifier writestream, ppos;
26identifier f, buf, len;
27type loff_t;
28@@
29 ssize_t writestream(struct file *f, const char *buf, size_t len, loff_t *ppos)
30 {
31 ... when != ppos
32 }
33
34
35// a function that blocks
36@ blocks @
37identifier block_f;
38identifier wait_event =~ "^wait_event_.*";
39@@
40 block_f(...) {
41 ... when exists
42 wait_event(...)
43 ... when exists
44 }
45
46// stream_reader that can block inside.
47//
48// XXX wait_* can be called not directly from current function (e.g. func -> f -> g -> wait())
49// XXX currently reader_blocks supports only direct and 1-level indirect cases.
50@ reader_blocks_direct @
51identifier stream_reader.readstream;
52identifier wait_event =~ "^wait_event_.*";
53@@
54 readstream(...)
55 {
56 ... when exists
57 wait_event(...)
58 ... when exists
59 }
60
61@ reader_blocks_1 @
62identifier stream_reader.readstream;
63identifier blocks.block_f;
64@@
65 readstream(...)
66 {
67 ... when exists
68 block_f(...)
69 ... when exists
70 }
71
72@ reader_blocks depends on reader_blocks_direct || reader_blocks_1 @
73identifier stream_reader.readstream;
74@@
75 readstream(...) {
76 ...
77 }
78
79
80// file_operations + whether they have _any_ .read, .write, .llseek ... at all.
81//
82// XXX add support for file_operations xxx[N] = ... (sound/core/pcm_native.c)
83@ fops0 @
84identifier fops;
85@@
86 struct file_operations fops = {
87 ...
88 };
89
90@ has_read @
91identifier fops0.fops;
92identifier read_f;
93@@
94 struct file_operations fops = {
95 .read = read_f,
96 };
97
98@ has_read_iter @
99identifier fops0.fops;
100identifier read_iter_f;
101@@
102 struct file_operations fops = {
103 .read_iter = read_iter_f,
104 };
105
106@ has_write @
107identifier fops0.fops;
108identifier write_f;
109@@
110 struct file_operations fops = {
111 .write = write_f,
112 };
113
114@ has_write_iter @
115identifier fops0.fops;
116identifier write_iter_f;
117@@
118 struct file_operations fops = {
119 .write_iter = write_iter_f,
120 };
121
122@ has_llseek @
123identifier fops0.fops;
124identifier llseek_f;
125@@
126 struct file_operations fops = {
127 .llseek = llseek_f,
128 };
129
130@ has_no_llseek @
131identifier fops0.fops;
132@@
133 struct file_operations fops = {
134 .llseek = no_llseek,
135 };
136
137@ has_mmap @
138identifier fops0.fops;
139identifier mmap_f;
140@@
141 struct file_operations fops = {
142 .mmap = mmap_f,
143 };
144
145@ has_copy_file_range @
146identifier fops0.fops;
147identifier copy_file_range_f;
148@@
149 struct file_operations fops = {
150 .copy_file_range = copy_file_range_f,
151 };
152
153@ has_remap_file_range @
154identifier fops0.fops;
155identifier remap_file_range_f;
156@@
157 struct file_operations fops = {
158 .remap_file_range = remap_file_range_f,
159 };
160
161@ has_splice_read @
162identifier fops0.fops;
163identifier splice_read_f;
164@@
165 struct file_operations fops = {
166 .splice_read = splice_read_f,
167 };
168
169@ has_splice_write @
170identifier fops0.fops;
171identifier splice_write_f;
172@@
173 struct file_operations fops = {
174 .splice_write = splice_write_f,
175 };
176
177
178// file_operations that is candidate for stream_open conversion - it does not
179// use mmap and other methods that assume @offset access to file.
180//
181// XXX for simplicity require no .{read/write}_iter and no .splice_{read/write} for now.
182// XXX maybe_steam.fops cannot be used in other rules - it gives "bad rule maybe_stream or bad variable fops".
183@ 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 @
184identifier fops0.fops;
185@@
186 struct file_operations fops = {
187 };
188
189
190// ---- conversions ----
191
192// XXX .open = nonseekable_open -> .open = stream_open
193// XXX .open = func -> openfunc -> nonseekable_open
194
195// read & write
196//
197// if both are used in the same file_operations together with an opener -
198// under that conditions we can use stream_open instead of nonseekable_open.
199@ fops_rw depends on maybe_stream @
200identifier fops0.fops, openfunc;
201identifier stream_reader.readstream;
202identifier stream_writer.writestream;
203@@
204 struct file_operations fops = {
205 .open = openfunc,
206 .read = readstream,
207 .write = writestream,
208 };
209
210@ report_rw depends on report @
211identifier fops_rw.openfunc;
212position p1;
213@@
214 openfunc(...) {
215 <...
216 nonseekable_open@p1
217 ...>
218 }
219
220@ script:python depends on report && reader_blocks @
221fops << fops0.fops;
222p << report_rw.p1;
223@@
224coccilib.report.print_report(p[0],
225 "ERROR: %s: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix." % (fops,))
226
227@ script:python depends on report && !reader_blocks @
228fops << fops0.fops;
229p << report_rw.p1;
230@@
231coccilib.report.print_report(p[0],
232 "WARNING: %s: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
233
234
235@ explain_rw_deadlocked depends on explain && reader_blocks @
236identifier fops_rw.openfunc;
237@@
238 openfunc(...) {
239 <...
240- nonseekable_open
241+ nonseekable_open /* read & write (was deadlock) */
242 ...>
243 }
244
245
246@ explain_rw_nodeadlock depends on explain && !reader_blocks @
247identifier fops_rw.openfunc;
248@@
249 openfunc(...) {
250 <...
251- nonseekable_open
252+ nonseekable_open /* read & write (no direct deadlock) */
253 ...>
254 }
255
256@ patch_rw depends on patch @
257identifier fops_rw.openfunc;
258@@
259 openfunc(...) {
260 <...
261- nonseekable_open
262+ stream_open
263 ...>
264 }
265
266
267// read, but not write
268@ fops_r depends on maybe_stream && !has_write @
269identifier fops0.fops, openfunc;
270identifier stream_reader.readstream;
271@@
272 struct file_operations fops = {
273 .open = openfunc,
274 .read = readstream,
275 };
276
277@ report_r depends on report @
278identifier fops_r.openfunc;
279position p1;
280@@
281 openfunc(...) {
282 <...
283 nonseekable_open@p1
284 ...>
285 }
286
287@ script:python depends on report @
288fops << fops0.fops;
289p << report_r.p1;
290@@
291coccilib.report.print_report(p[0],
292 "WARNING: %s: .read() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
293
294@ explain_r depends on explain @
295identifier fops_r.openfunc;
296@@
297 openfunc(...) {
298 <...
299- nonseekable_open
300+ nonseekable_open /* read only */
301 ...>
302 }
303
304@ patch_r depends on patch @
305identifier fops_r.openfunc;
306@@
307 openfunc(...) {
308 <...
309- nonseekable_open
310+ stream_open
311 ...>
312 }
313
314
315// write, but not read
316@ fops_w depends on maybe_stream && !has_read @
317identifier fops0.fops, openfunc;
318identifier stream_writer.writestream;
319@@
320 struct file_operations fops = {
321 .open = openfunc,
322 .write = writestream,
323 };
324
325@ report_w depends on report @
326identifier fops_w.openfunc;
327position p1;
328@@
329 openfunc(...) {
330 <...
331 nonseekable_open@p1
332 ...>
333 }
334
335@ script:python depends on report @
336fops << fops0.fops;
337p << report_w.p1;
338@@
339coccilib.report.print_report(p[0],
340 "WARNING: %s: .write() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
341
342@ explain_w depends on explain @
343identifier fops_w.openfunc;
344@@
345 openfunc(...) {
346 <...
347- nonseekable_open
348+ nonseekable_open /* write only */
349 ...>
350 }
351
352@ patch_w depends on patch @
353identifier fops_w.openfunc;
354@@
355 openfunc(...) {
356 <...
357- nonseekable_open
358+ stream_open
359 ...>
360 }
361
362
363// no read, no write - don't change anything
diff --git a/scripts/coccinelle/free/put_device.cocci b/scripts/coccinelle/free/put_device.cocci
index 7395697e7f19..c9f071b0a0ab 100644
--- a/scripts/coccinelle/free/put_device.cocci
+++ b/scripts/coccinelle/free/put_device.cocci
@@ -32,6 +32,7 @@ if (id == NULL || ...) { ... return ...; }
32( id 32( id
33| (T2)dev_get_drvdata(&id->dev) 33| (T2)dev_get_drvdata(&id->dev)
34| (T3)platform_get_drvdata(id) 34| (T3)platform_get_drvdata(id)
35| &id->dev
35); 36);
36| return@p2 ...; 37| return@p2 ...;
37) 38)
diff --git a/scripts/coccinelle/misc/badty.cocci b/scripts/coccinelle/misc/badty.cocci
index 481cf301ccfc..08470362199c 100644
--- a/scripts/coccinelle/misc/badty.cocci
+++ b/scripts/coccinelle/misc/badty.cocci
@@ -1,4 +1,4 @@
1/// Use ARRAY_SIZE instead of dividing sizeof array with sizeof an element 1/// Correct the size argument to alloc functions
2/// 2///
3//# This makes an effort to find cases where the argument to sizeof is wrong 3//# This makes an effort to find cases where the argument to sizeof is wrong
4//# in memory allocation functions by checking the type of the allocated memory 4//# in memory allocation functions by checking the type of the allocated memory
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);
30 30
31my %broken_ref; 31my %broken_ref;
32 32
33my $doc_fix = 0;
34
35open IN, "git grep ':doc:\`' Documentation/|"
36 or die "Failed to run git grep";
37while (<IN>) {
38 next if (!m,^([^:]+):.*\:doc\:\`([^\`]+)\`,);
39
40 my $d = $1;
41 my $doc_ref = $2;
42
43 my $f = $doc_ref;
44
45 $d =~ s,(.*/).*,$1,;
46 $f =~ s,.*\<([^\>]+)\>,$1,;
47
48 $f ="$d$f.rst";
49
50 next if (grep -e, glob("$f"));
51
52 if ($fix && !$doc_fix) {
53 print STDERR "\nWARNING: Currently, can't fix broken :doc:`` fields\n";
54 }
55 $doc_fix++;
56
57 print STDERR "$f: :doc:`$doc_ref`\n";
58}
59close IN;
60
33open IN, "git grep 'Documentation/'|" 61open IN, "git grep 'Documentation/'|"
34 or die "Failed to run git grep"; 62 or die "Failed to run git grep";
35while (<IN>) { 63while (<IN>) {
@@ -38,6 +66,9 @@ while (<IN>) {
38 my $f = $1; 66 my $f = $1;
39 my $ln = $2; 67 my $ln = $2;
40 68
69 # On linux-next, discard the Next/ directory
70 next if ($f =~ m,^Next/,);
71
41 # Makefiles and scripts contain nasty expressions to parse docs 72 # Makefiles and scripts contain nasty expressions to parse docs
42 next if ($f =~ m/Makefile/ || $f =~ m/\.sh$/); 73 next if ($f =~ m/Makefile/ || $f =~ m/\.sh$/);
43 74
@@ -100,6 +131,7 @@ while (<IN>) {
100 } 131 }
101 } 132 }
102} 133}
134close IN;
103 135
104exit 0 if (!$fix); 136exit 0 if (!$fix);
105 137
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
index 74271dba4f94..80220ed26a35 100644
--- a/scripts/gcc-plugins/Kconfig
+++ b/scripts/gcc-plugins/Kconfig
@@ -13,17 +13,19 @@ config HAVE_GCC_PLUGINS
13 An arch should select this symbol if it supports building with 13 An arch should select this symbol if it supports building with
14 GCC plugins. 14 GCC plugins.
15 15
16menuconfig GCC_PLUGINS 16config GCC_PLUGINS
17 bool "GCC plugins" 17 bool
18 depends on HAVE_GCC_PLUGINS 18 depends on HAVE_GCC_PLUGINS
19 depends on PLUGIN_HOSTCC != "" 19 depends on PLUGIN_HOSTCC != ""
20 default y
20 help 21 help
21 GCC plugins are loadable modules that provide extra features to the 22 GCC plugins are loadable modules that provide extra features to the
22 compiler. They are useful for runtime instrumentation and static analysis. 23 compiler. They are useful for runtime instrumentation and static analysis.
23 24
24 See Documentation/gcc-plugins.txt for details. 25 See Documentation/gcc-plugins.txt for details.
25 26
26if GCC_PLUGINS 27menu "GCC plugins"
28 depends on GCC_PLUGINS
27 29
28config GCC_PLUGIN_CYC_COMPLEXITY 30config GCC_PLUGIN_CYC_COMPLEXITY
29 bool "Compute the cyclomatic complexity of a function" if EXPERT 31 bool "Compute the cyclomatic complexity of a function" if EXPERT
@@ -66,71 +68,6 @@ config GCC_PLUGIN_LATENT_ENTROPY
66 * https://grsecurity.net/ 68 * https://grsecurity.net/
67 * https://pax.grsecurity.net/ 69 * https://pax.grsecurity.net/
68 70
69config GCC_PLUGIN_STRUCTLEAK
70 bool "Zero initialize stack variables"
71 help
72 While the kernel is built with warnings enabled for any missed
73 stack variable initializations, this warning is silenced for
74 anything passed by reference to another function, under the
75 occasionally misguided assumption that the function will do
76 the initialization. As this regularly leads to exploitable
77 flaws, this plugin is available to identify and zero-initialize
78 such variables, depending on the chosen level of coverage.
79
80 This plugin was originally ported from grsecurity/PaX. More
81 information at:
82 * https://grsecurity.net/
83 * https://pax.grsecurity.net/
84
85choice
86 prompt "Coverage"
87 depends on GCC_PLUGIN_STRUCTLEAK
88 default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
89 help
90 This chooses the level of coverage over classes of potentially
91 uninitialized variables. The selected class will be
92 zero-initialized before use.
93
94 config GCC_PLUGIN_STRUCTLEAK_USER
95 bool "structs marked for userspace"
96 help
97 Zero-initialize any structures on the stack containing
98 a __user attribute. This can prevent some classes of
99 uninitialized stack variable exploits and information
100 exposures, like CVE-2013-2141:
101 https://git.kernel.org/linus/b9e146d8eb3b9eca
102
103 config GCC_PLUGIN_STRUCTLEAK_BYREF
104 bool "structs passed by reference"
105 help
106 Zero-initialize any structures on the stack that may
107 be passed by reference and had not already been
108 explicitly initialized. This can prevent most classes
109 of uninitialized stack variable exploits and information
110 exposures, like CVE-2017-1000410:
111 https://git.kernel.org/linus/06e7e776ca4d3654
112
113 config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
114 bool "anything passed by reference"
115 help
116 Zero-initialize any stack variables that may be passed
117 by reference and had not already been explicitly
118 initialized. This is intended to eliminate all classes
119 of uninitialized stack variable exploits and information
120 exposures.
121
122endchoice
123
124config GCC_PLUGIN_STRUCTLEAK_VERBOSE
125 bool "Report forcefully initialized variables"
126 depends on GCC_PLUGIN_STRUCTLEAK
127 depends on !COMPILE_TEST # too noisy
128 help
129 This option will cause a warning to be printed each time the
130 structleak plugin finds a variable it thinks needs to be
131 initialized. Since not all existing initializers are detected
132 by the plugin, this can produce false positive warnings.
133
134config GCC_PLUGIN_RANDSTRUCT 71config GCC_PLUGIN_RANDSTRUCT
135 bool "Randomize layout of sensitive kernel structures" 72 bool "Randomize layout of sensitive kernel structures"
136 select MODVERSIONS if MODULES 73 select MODVERSIONS if MODULES
@@ -171,59 +108,8 @@ config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
171 in structures. This reduces the performance hit of RANDSTRUCT 108 in structures. This reduces the performance hit of RANDSTRUCT
172 at the cost of weakened randomization. 109 at the cost of weakened randomization.
173 110
174config GCC_PLUGIN_STACKLEAK
175 bool "Erase the kernel stack before returning from syscalls"
176 depends on GCC_PLUGINS
177 depends on HAVE_ARCH_STACKLEAK
178 help
179 This option makes the kernel erase the kernel stack before
180 returning from system calls. That reduces the information which
181 kernel stack leak bugs can reveal and blocks some uninitialized
182 stack variable attacks.
183
184 The tradeoff is the performance impact: on a single CPU system kernel
185 compilation sees a 1% slowdown, other systems and workloads may vary
186 and you are advised to test this feature on your expected workload
187 before deploying it.
188
189 This plugin was ported from grsecurity/PaX. More information at:
190 * https://grsecurity.net/
191 * https://pax.grsecurity.net/
192
193config STACKLEAK_TRACK_MIN_SIZE
194 int "Minimum stack frame size of functions tracked by STACKLEAK"
195 default 100
196 range 0 4096
197 depends on GCC_PLUGIN_STACKLEAK
198 help
199 The STACKLEAK gcc plugin instruments the kernel code for tracking
200 the lowest border of the kernel stack (and for some other purposes).
201 It inserts the stackleak_track_stack() call for the functions with
202 a stack frame size greater than or equal to this parameter.
203 If unsure, leave the default value 100.
204
205config STACKLEAK_METRICS
206 bool "Show STACKLEAK metrics in the /proc file system"
207 depends on GCC_PLUGIN_STACKLEAK
208 depends on PROC_FS
209 help
210 If this is set, STACKLEAK metrics for every task are available in
211 the /proc file system. In particular, /proc/<pid>/stack_depth
212 shows the maximum kernel stack consumption for the current and
213 previous syscalls. Although this information is not precise, it
214 can be useful for estimating the STACKLEAK performance impact for
215 your workloads.
216
217config STACKLEAK_RUNTIME_DISABLE
218 bool "Allow runtime disabling of kernel stack erasing"
219 depends on GCC_PLUGIN_STACKLEAK
220 help
221 This option provides 'stack_erasing' sysctl, which can be used in
222 runtime to control kernel stack erasing for kernels built with
223 CONFIG_GCC_PLUGIN_STACKLEAK.
224
225config GCC_PLUGIN_ARM_SSP_PER_TASK 111config GCC_PLUGIN_ARM_SSP_PER_TASK
226 bool 112 bool
227 depends on GCC_PLUGINS && ARM 113 depends on GCC_PLUGINS && ARM
228 114
229endif 115endmenu
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)
36 mask = GEN_INT(sext_hwi(sp_mask, GET_MODE_PRECISION(Pmode))); 36 mask = GEN_INT(sext_hwi(sp_mask, GET_MODE_PRECISION(Pmode)));
37 masked_sp = gen_reg_rtx(Pmode); 37 masked_sp = gen_reg_rtx(Pmode);
38 38
39 emit_insn_before(gen_rtx_SET(masked_sp, 39 emit_insn_before(gen_rtx_set(masked_sp,
40 gen_rtx_AND(Pmode, 40 gen_rtx_AND(Pmode,
41 stack_pointer_rtx, 41 stack_pointer_rtx,
42 mask)), 42 mask)),
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 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2 2
3ifneq ($(KBUILD_SRC),) 3ifneq ($(srctree),.)
4 4
5symlinks := $(patsubst $(srctree)/$(src)/%,%,$(wildcard $(srctree)/$(src)/*.py)) 5symlinks := $(patsubst $(srctree)/$(src)/%,%,$(wildcard $(srctree)/$(src)/*.py))
6 6
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 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Copyright (c) NXP 2019
4
5import gdb
6import sys
7
8from linux import utils, lists, constants
9
10clk_core_type = utils.CachedType("struct clk_core")
11
12
13def clk_core_for_each_child(hlist_head):
14 return lists.hlist_for_each_entry(hlist_head,
15 clk_core_type.get_type().pointer(), "child_node")
16
17
18class LxClkSummary(gdb.Command):
19 """Print clk tree summary
20
21Output is a subset of /sys/kernel/debug/clk/clk_summary
22
23No calls are made during printing, instead a (c) if printed after values which
24are cached and potentially out of date"""
25
26 def __init__(self):
27 super(LxClkSummary, self).__init__("lx-clk-summary", gdb.COMMAND_DATA)
28
29 def show_subtree(self, clk, level):
30 gdb.write("%*s%-*s %7d %8d %8d %11lu%s\n" % (
31 level * 3 + 1, "",
32 30 - level * 3,
33 clk['name'].string(),
34 clk['enable_count'],
35 clk['prepare_count'],
36 clk['protect_count'],
37 clk['rate'],
38 '(c)' if clk['flags'] & constants.LX_CLK_GET_RATE_NOCACHE else ' '))
39
40 for child in clk_core_for_each_child(clk['children']):
41 self.show_subtree(child, level + 1)
42
43 def invoke(self, arg, from_tty):
44 gdb.write(" enable prepare protect \n")
45 gdb.write(" clock count count count rate \n")
46 gdb.write("------------------------------------------------------------------------\n")
47 for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_root_list")):
48 self.show_subtree(clk, 0)
49 for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_orphan_list")):
50 self.show_subtree(clk, 0)
51
52
53LxClkSummary()
54
55
56class LxClkCoreLookup(gdb.Function):
57 """Find struct clk_core by name"""
58
59 def __init__(self):
60 super(LxClkCoreLookup, self).__init__("lx_clk_core_lookup")
61
62 def lookup_hlist(self, hlist_head, name):
63 for child in clk_core_for_each_child(hlist_head):
64 if child['name'].string() == name:
65 return child
66 result = self.lookup_hlist(child['children'], name)
67 if result:
68 return result
69
70 def invoke(self, name):
71 name = name.string()
72 return (self.lookup_hlist(gdb.parse_and_eval("clk_root_list"), name) or
73 self.lookup_hlist(gdb.parse_and_eval("clk_orphan_list"), name))
74
75
76LxClkCoreLookup()
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 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Copyright 2019 Google LLC.
4
5import gdb
6import zlib
7
8from linux import utils
9
10
11class LxConfigDump(gdb.Command):
12 """Output kernel config to the filename specified as the command
13 argument. Equivalent to 'zcat /proc/config.gz > config.txt' on
14 a running target"""
15
16 def __init__(self):
17 super(LxConfigDump, self).__init__("lx-configdump", gdb.COMMAND_DATA,
18 gdb.COMPLETE_FILENAME)
19
20 def invoke(self, arg, from_tty):
21 if len(arg) == 0:
22 filename = "config.txt"
23 else:
24 filename = arg
25
26 try:
27 py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8")
28 py_config_size = gdb.parse_and_eval(
29 "sizeof(kernel_config_data) - 1 - 8 * 2")
30 except gdb.error as e:
31 raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?")
32
33 inf = gdb.inferiors()[0]
34 zconfig_buf = utils.read_memoryview(inf, py_config_ptr,
35 py_config_size).tobytes()
36
37 config_buf = zlib.decompress(zconfig_buf, 16)
38 with open(filename, 'wb') as f:
39 f.write(config_buf)
40
41 gdb.write("Dumped config to " + filename + "\n")
42
43
44LxConfigDump()
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 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/clk-provider.h>
15#include <linux/fs.h> 16#include <linux/fs.h>
17#include <linux/hrtimer.h>
16#include <linux/mount.h> 18#include <linux/mount.h>
17#include <linux/of_fdt.h> 19#include <linux/of_fdt.h>
20#include <linux/threads.h>
18 21
19/* We need to stringify expanded macros so that they can be parsed */ 22/* We need to stringify expanded macros so that they can be parsed */
20 23
@@ -36,6 +39,9 @@
36 39
37import gdb 40import gdb
38 41
42/* linux/clk-provider.h */
43LX_GDBPARSED(CLK_GET_RATE_NOCACHE)
44
39/* linux/fs.h */ 45/* linux/fs.h */
40LX_VALUE(SB_RDONLY) 46LX_VALUE(SB_RDONLY)
41LX_VALUE(SB_SYNCHRONOUS) 47LX_VALUE(SB_SYNCHRONOUS)
@@ -44,6 +50,9 @@ LX_VALUE(SB_DIRSYNC)
44LX_VALUE(SB_NOATIME) 50LX_VALUE(SB_NOATIME)
45LX_VALUE(SB_NODIRATIME) 51LX_VALUE(SB_NODIRATIME)
46 52
53/* linux/htimer.h */
54LX_GDBPARSED(hrtimer_resolution)
55
47/* linux/mount.h */ 56/* linux/mount.h */
48LX_VALUE(MNT_NOSUID) 57LX_VALUE(MNT_NOSUID)
49LX_VALUE(MNT_NODEV) 58LX_VALUE(MNT_NODEV)
@@ -52,8 +61,16 @@ LX_VALUE(MNT_NOATIME)
52LX_VALUE(MNT_NODIRATIME) 61LX_VALUE(MNT_NODIRATIME)
53LX_VALUE(MNT_RELATIME) 62LX_VALUE(MNT_RELATIME)
54 63
64/* linux/threads.h */
65LX_VALUE(NR_CPUS)
66
55/* linux/of_fdt.h> */ 67/* linux/of_fdt.h> */
56LX_VALUE(OF_DT_HEADER) 68LX_VALUE(OF_DT_HEADER)
57 69
58/* Kernel Configs */ 70/* Kernel Configs */
71LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS)
72LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
73LX_CONFIG(CONFIG_HIGH_RES_TIMERS)
74LX_CONFIG(CONFIG_NR_CPUS)
59LX_CONFIG(CONFIG_OF) 75LX_CONFIG(CONFIG_OF)
76LX_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"""
135 gdb.write("Online CPUs : {}\n".format(list(each_online_cpu()))) 135 gdb.write("Online CPUs : {}\n".format(list(each_online_cpu())))
136 gdb.write("Active CPUs : {}\n".format(list(each_active_cpu()))) 136 gdb.write("Active CPUs : {}\n".format(list(each_active_cpu())))
137 137
138
138LxCpus() 139LxCpus()
139 140
140 141
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
16from linux import utils 16from linux import utils
17 17
18list_head = utils.CachedType("struct list_head") 18list_head = utils.CachedType("struct list_head")
19hlist_head = utils.CachedType("struct hlist_head")
20hlist_node = utils.CachedType("struct hlist_node")
19 21
20 22
21def list_for_each(head): 23def list_for_each(head):
22 if head.type == list_head.get_type().pointer(): 24 if head.type == list_head.get_type().pointer():
23 head = head.dereference() 25 head = head.dereference()
24 elif head.type != list_head.get_type(): 26 elif head.type != list_head.get_type():
25 raise gdb.GdbError("Must be struct list_head not {}" 27 raise TypeError("Must be struct list_head not {}"
26 .format(head.type)) 28 .format(head.type))
27 29
28 node = head['next'].dereference() 30 node = head['next'].dereference()
@@ -33,9 +35,24 @@ def list_for_each(head):
33 35
34def list_for_each_entry(head, gdbtype, member): 36def list_for_each_entry(head, gdbtype, member):
35 for node in list_for_each(head): 37 for node in list_for_each(head):
36 if node.type != list_head.get_type().pointer(): 38 yield utils.container_of(node, gdbtype, member)
37 raise TypeError("Type {} found. Expected struct list_head *." 39
38 .format(node.type)) 40
41def hlist_for_each(head):
42 if head.type == hlist_head.get_type().pointer():
43 head = head.dereference()
44 elif head.type != hlist_head.get_type():
45 raise TypeError("Must be struct hlist_head not {}"
46 .format(head.type))
47
48 node = head['first'].dereference()
49 while node.address:
50 yield node.address
51 node = node['next'].dereference()
52
53
54def hlist_for_each_entry(head, gdbtype, member):
55 for node in hlist_for_each(head):
39 yield utils.container_of(node, gdbtype, member) 56 yield utils.container_of(node, gdbtype, member)
40 57
41 58
@@ -110,4 +127,5 @@ class LxListChk(gdb.Command):
110 raise gdb.GdbError("lx-list-check takes one argument") 127 raise gdb.GdbError("lx-list-check takes one argument")
111 list_check(gdb.parse_and_eval(argv[0])) 128 list_check(gdb.parse_and_eval(argv[0]))
112 129
130
113LxListChk() 131LxListChk()
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):
29 def invoke(self, arg, from_tty): 29 def invoke(self, arg, from_tty):
30 gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n") 30 gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n")
31 31
32
32LxCmdLine() 33LxCmdLine()
33 34
34 35
@@ -43,6 +44,7 @@ class LxVersion(gdb.Command):
43 # linux_banner should contain a newline 44 # linux_banner should contain a newline
44 gdb.write(gdb.parse_and_eval("(char *)linux_banner").string()) 45 gdb.write(gdb.parse_and_eval("(char *)linux_banner").string())
45 46
47
46LxVersion() 48LxVersion()
47 49
48 50
@@ -86,6 +88,7 @@ Equivalent to cat /proc/iomem on a running target"""
86 def invoke(self, arg, from_tty): 88 def invoke(self, arg, from_tty):
87 return show_lx_resources("iomem_resource") 89 return show_lx_resources("iomem_resource")
88 90
91
89LxIOMem() 92LxIOMem()
90 93
91 94
@@ -100,6 +103,7 @@ Equivalent to cat /proc/ioports on a running target"""
100 def invoke(self, arg, from_tty): 103 def invoke(self, arg, from_tty):
101 return show_lx_resources("ioport_resource") 104 return show_lx_resources("ioport_resource")
102 105
106
103LxIOPorts() 107LxIOPorts()
104 108
105 109
@@ -149,7 +153,7 @@ values of that process namespace"""
149 if len(argv) >= 1: 153 if len(argv) >= 1:
150 try: 154 try:
151 pid = int(argv[0]) 155 pid = int(argv[0])
152 except: 156 except gdb.error:
153 raise gdb.GdbError("Provide a PID as integer value") 157 raise gdb.GdbError("Provide a PID as integer value")
154 else: 158 else:
155 pid = 1 159 pid = 1
@@ -195,6 +199,7 @@ values of that process namespace"""
195 info_opts(FS_INFO, s_flags), 199 info_opts(FS_INFO, s_flags),
196 info_opts(MNT_INFO, m_flags))) 200 info_opts(MNT_INFO, m_flags)))
197 201
202
198LxMounts() 203LxMounts()
199 204
200 205
@@ -259,7 +264,7 @@ class LxFdtDump(gdb.Command):
259 264
260 try: 265 try:
261 f = open(filename, 'wb') 266 f = open(filename, 'wb')
262 except: 267 except gdb.error:
263 raise gdb.GdbError("Could not open file to dump fdt") 268 raise gdb.GdbError("Could not open file to dump fdt")
264 269
265 f.write(fdt_buf) 270 f.write(fdt_buf)
@@ -267,4 +272,5 @@ class LxFdtDump(gdb.Command):
267 272
268 gdb.write("Dumped fdt blob to " + filename + "\n") 273 gdb.write("Dumped fdt blob to " + filename + "\n")
269 274
275
270LxFdtDump() 276LxFdtDump()
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 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Copyright 2019 Google LLC.
4
5import gdb
6
7from linux import utils
8
9rb_root_type = utils.CachedType("struct rb_root")
10rb_node_type = utils.CachedType("struct rb_node")
11
12
13def rb_first(root):
14 if root.type == rb_root_type.get_type():
15 node = node.address.cast(rb_root_type.get_type().pointer())
16 elif root.type != rb_root_type.get_type().pointer():
17 raise gdb.GdbError("Must be struct rb_root not {}".format(root.type))
18
19 node = root['rb_node']
20 if node is 0:
21 return None
22
23 while node['rb_left']:
24 node = node['rb_left']
25
26 return node
27
28
29def rb_last(root):
30 if root.type == rb_root_type.get_type():
31 node = node.address.cast(rb_root_type.get_type().pointer())
32 elif root.type != rb_root_type.get_type().pointer():
33 raise gdb.GdbError("Must be struct rb_root not {}".format(root.type))
34
35 node = root['rb_node']
36 if node is 0:
37 return None
38
39 while node['rb_right']:
40 node = node['rb_right']
41
42 return node
43
44
45def rb_parent(node):
46 parent = gdb.Value(node['__rb_parent_color'] & ~3)
47 return parent.cast(rb_node_type.get_type().pointer())
48
49
50def rb_empty_node(node):
51 return node['__rb_parent_color'] == node.address
52
53
54def rb_next(node):
55 if node.type == rb_node_type.get_type():
56 node = node.address.cast(rb_node_type.get_type().pointer())
57 elif node.type != rb_node_type.get_type().pointer():
58 raise gdb.GdbError("Must be struct rb_node not {}".format(node.type))
59
60 if rb_empty_node(node):
61 return None
62
63 if node['rb_right']:
64 node = node['rb_right']
65 while node['rb_left']:
66 node = node['rb_left']
67 return node
68
69 parent = rb_parent(node)
70 while parent and node == parent['rb_right']:
71 node = parent
72 parent = rb_parent(node)
73
74 return parent
75
76
77def rb_prev(node):
78 if node.type == rb_node_type.get_type():
79 node = node.address.cast(rb_node_type.get_type().pointer())
80 elif node.type != rb_node_type.get_type().pointer():
81 raise gdb.GdbError("Must be struct rb_node not {}".format(node.type))
82
83 if rb_empty_node(node):
84 return None
85
86 if node['rb_left']:
87 node = node['rb_left']
88 while node['rb_right']:
89 node = node['rb_right']
90 return node.dereference()
91
92 parent = rb_parent(node)
93 while parent and node == parent['rb_left'].dereference():
94 node = parent
95 parent = rb_parent(node)
96
97 return parent
98
99
100class LxRbFirst(gdb.Function):
101 """Lookup and return a node from an RBTree
102
103$lx_rb_first(root): Return the node at the given index.
104If index is omitted, the root node is dereferenced and returned."""
105
106 def __init__(self):
107 super(LxRbFirst, self).__init__("lx_rb_first")
108
109 def invoke(self, root):
110 result = rb_first(root)
111 if result is None:
112 raise gdb.GdbError("No entry in tree")
113
114 return result
115
116
117LxRbFirst()
118
119
120class LxRbLast(gdb.Function):
121 """Lookup and return a node from an RBTree.
122
123$lx_rb_last(root): Return the node at the given index.
124If index is omitted, the root node is dereferenced and returned."""
125
126 def __init__(self):
127 super(LxRbLast, self).__init__("lx_rb_last")
128
129 def invoke(self, root):
130 result = rb_last(root)
131 if result is None:
132 raise gdb.GdbError("No entry in tree")
133
134 return result
135
136
137LxRbLast()
138
139
140class LxRbNext(gdb.Function):
141 """Lookup and return a node from an RBTree.
142
143$lx_rb_next(node): Return the node at the given index.
144If index is omitted, the root node is dereferenced and returned."""
145
146 def __init__(self):
147 super(LxRbNext, self).__init__("lx_rb_next")
148
149 def invoke(self, node):
150 result = rb_next(node)
151 if result is None:
152 raise gdb.GdbError("No entry in tree")
153
154 return result
155
156
157LxRbNext()
158
159
160class LxRbPrev(gdb.Function):
161 """Lookup and return a node from an RBTree.
162
163$lx_rb_prev(node): Return the node at the given index.
164If index is omitted, the root node is dereferenced and returned."""
165
166 def __init__(self):
167 super(LxRbPrev, self).__init__("lx_rb_prev")
168
169 def invoke(self, node):
170 result = rb_prev(node)
171 if result is None:
172 raise gdb.GdbError("No entry in tree")
173
174 return result
175
176
177LxRbPrev()
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."""
139 saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) 139 saved_states.append({'breakpoint': bp, 'enabled': bp.enabled})
140 140
141 # drop all current symbols and reload vmlinux 141 # drop all current symbols and reload vmlinux
142 orig_vmlinux = 'vmlinux'
143 for obj in gdb.objfiles():
144 if obj.filename.endswith('vmlinux'):
145 orig_vmlinux = obj.filename
142 gdb.execute("symbol-file", to_string=True) 146 gdb.execute("symbol-file", to_string=True)
143 gdb.execute("symbol-file vmlinux") 147 gdb.execute("symbol-file {0}".format(orig_vmlinux))
144 148
145 self.loaded_modules = [] 149 self.loaded_modules = []
146 module_list = modules.module_list() 150 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):
79 pid=task["pid"], 79 pid=task["pid"],
80 comm=task["comm"].string())) 80 comm=task["comm"].string()))
81 81
82
82LxPs() 83LxPs()
83 84
84 85
@@ -134,4 +135,5 @@ variable."""
134 else: 135 else:
135 raise gdb.GdbError("No task of PID " + str(pid)) 136 raise gdb.GdbError("No task of PID " + str(pid))
136 137
138
137LxThreadInfoByPidFunc() 139LxThreadInfoByPidFunc()
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 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Copyright 2019 Google LLC.
4
5import binascii
6import gdb
7
8from linux import constants
9from linux import cpus
10from linux import rbtree
11from linux import utils
12
13timerqueue_node_type = utils.CachedType("struct timerqueue_node").get_type()
14hrtimer_type = utils.CachedType("struct hrtimer").get_type()
15
16
17def ktime_get():
18 """Returns the current time, but not very accurately
19
20 We can't read the hardware timer itself to add any nanoseconds
21 that need to be added since we last stored the time in the
22 timekeeper. But this is probably good enough for debug purposes."""
23 tk_core = gdb.parse_and_eval("&tk_core")
24
25 return tk_core['timekeeper']['tkr_mono']['base']
26
27
28def print_timer(rb_node, idx):
29 timerqueue = utils.container_of(rb_node, timerqueue_node_type.pointer(),
30 "node")
31 timer = utils.container_of(timerqueue, hrtimer_type.pointer(), "node")
32
33 function = str(timer['function']).split(" ")[1].strip("<>")
34 softexpires = timer['_softexpires']
35 expires = timer['node']['expires']
36 now = ktime_get()
37
38 text = " #{}: <{}>, {}, ".format(idx, timer, function)
39 text += "S:{:02x}\n".format(int(timer['state']))
40 text += " # expires at {}-{} nsecs [in {} to {} nsecs]\n".format(
41 softexpires, expires, softexpires - now, expires - now)
42 return text
43
44
45def print_active_timers(base):
46 curr = base['active']['next']['node']
47 curr = curr.address.cast(rbtree.rb_node_type.get_type().pointer())
48 idx = 0
49 while curr:
50 yield print_timer(curr, idx)
51 curr = rbtree.rb_next(curr)
52 idx += 1
53
54
55def print_base(base):
56 text = " .base: {}\n".format(base.address)
57 text += " .index: {}\n".format(base['index'])
58
59 text += " .resolution: {} nsecs\n".format(constants.LX_hrtimer_resolution)
60
61 text += " .get_time: {}\n".format(base['get_time'])
62 if constants.LX_CONFIG_HIGH_RES_TIMERS:
63 text += " .offset: {} nsecs\n".format(base['offset'])
64 text += "active timers:\n"
65 text += "".join([x for x in print_active_timers(base)])
66 return text
67
68
69def print_cpu(hrtimer_bases, cpu, max_clock_bases):
70 cpu_base = cpus.per_cpu(hrtimer_bases, cpu)
71 jiffies = gdb.parse_and_eval("jiffies_64")
72 tick_sched_ptr = gdb.parse_and_eval("&tick_cpu_sched")
73 ts = cpus.per_cpu(tick_sched_ptr, cpu)
74
75 text = "cpu: {}\n".format(cpu)
76 for i in xrange(max_clock_bases):
77 text += " clock {}:\n".format(i)
78 text += print_base(cpu_base['clock_base'][i])
79
80 if constants.LX_CONFIG_HIGH_RES_TIMERS:
81 fmts = [(" .{} : {} nsecs", 'expires_next'),
82 (" .{} : {}", 'hres_active'),
83 (" .{} : {}", 'nr_events'),
84 (" .{} : {}", 'nr_retries'),
85 (" .{} : {}", 'nr_hangs'),
86 (" .{} : {}", 'max_hang_time')]
87 text += "\n".join([s.format(f, cpu_base[f]) for s, f in fmts])
88 text += "\n"
89
90 if constants.LX_CONFIG_TICK_ONESHOT:
91 fmts = [(" .{} : {}", 'nohz_mode'),
92 (" .{} : {} nsecs", 'last_tick'),
93 (" .{} : {}", 'tick_stopped'),
94 (" .{} : {}", 'idle_jiffies'),
95 (" .{} : {}", 'idle_calls'),
96 (" .{} : {}", 'idle_sleeps'),
97 (" .{} : {} nsecs", 'idle_entrytime'),
98 (" .{} : {} nsecs", 'idle_waketime'),
99 (" .{} : {} nsecs", 'idle_exittime'),
100 (" .{} : {} nsecs", 'idle_sleeptime'),
101 (" .{}: {} nsecs", 'iowait_sleeptime'),
102 (" .{} : {}", 'last_jiffies'),
103 (" .{} : {}", 'next_timer'),
104 (" .{} : {} nsecs", 'idle_expires')]
105 text += "\n".join([s.format(f, ts[f]) for s, f in fmts])
106 text += "\njiffies: {}\n".format(jiffies)
107
108 text += "\n"
109
110 return text
111
112
113def print_tickdevice(td, cpu):
114 dev = td['evtdev']
115 text = "Tick Device: mode: {}\n".format(td['mode'])
116 if cpu < 0:
117 text += "Broadcast device\n"
118 else:
119 text += "Per CPU device: {}\n".format(cpu)
120
121 text += "Clock Event Device: "
122 if dev == 0:
123 text += "<NULL>\n"
124 return text
125
126 text += "{}\n".format(dev['name'])
127 text += " max_delta_ns: {}\n".format(dev['max_delta_ns'])
128 text += " min_delta_ns: {}\n".format(dev['min_delta_ns'])
129 text += " mult: {}\n".format(dev['mult'])
130 text += " shift: {}\n".format(dev['shift'])
131 text += " mode: {}\n".format(dev['state_use_accessors'])
132 text += " next_event: {} nsecs\n".format(dev['next_event'])
133
134 text += " set_next_event: {}\n".format(dev['set_next_event'])
135
136 members = [('set_state_shutdown', " shutdown: {}\n"),
137 ('set_state_periodic', " periodic: {}\n"),
138 ('set_state_oneshot', " oneshot: {}\n"),
139 ('set_state_oneshot_stopped', " oneshot stopped: {}\n"),
140 ('tick_resume', " resume: {}\n")]
141 for member, fmt in members:
142 if dev[member]:
143 text += fmt.format(dev[member])
144
145 text += " event_handler: {}\n".format(dev['event_handler'])
146 text += " retries: {}\n".format(dev['retries'])
147
148 return text
149
150
151def pr_cpumask(mask):
152 nr_cpu_ids = 1
153 if constants.LX_NR_CPUS > 1:
154 nr_cpu_ids = gdb.parse_and_eval("nr_cpu_ids")
155
156 inf = gdb.inferiors()[0]
157 bits = mask['bits']
158 num_bytes = (nr_cpu_ids + 7) / 8
159 buf = utils.read_memoryview(inf, bits, num_bytes).tobytes()
160 buf = binascii.b2a_hex(buf)
161
162 chunks = []
163 i = num_bytes
164 while i > 0:
165 i -= 1
166 start = i * 2
167 end = start + 2
168 chunks.append(buf[start:end])
169 if i != 0 and i % 4 == 0:
170 chunks.append(',')
171
172 extra = nr_cpu_ids % 8
173 if 0 < extra <= 4:
174 chunks[0] = chunks[0][0] # Cut off the first 0
175
176 return "".join(chunks)
177
178
179class LxTimerList(gdb.Command):
180 """Print /proc/timer_list"""
181
182 def __init__(self):
183 super(LxTimerList, self).__init__("lx-timerlist", gdb.COMMAND_DATA)
184
185 def invoke(self, arg, from_tty):
186 hrtimer_bases = gdb.parse_and_eval("&hrtimer_bases")
187 max_clock_bases = gdb.parse_and_eval("HRTIMER_MAX_CLOCK_BASES")
188
189 text = "Timer List Version: gdb scripts\n"
190 text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format(max_clock_bases)
191 text += "now at {} nsecs\n".format(ktime_get())
192
193 for cpu in cpus.each_online_cpu():
194 text += print_cpu(hrtimer_bases, cpu, max_clock_bases)
195
196 if constants.LX_CONFIG_GENERIC_CLOCKEVENTS:
197 if constants.LX_CONFIG_GENERIC_CLOCKEVENTS_BROADCAST:
198 bc_dev = gdb.parse_and_eval("&tick_broadcast_device")
199 text += print_tickdevice(bc_dev, -1)
200 text += "\n"
201 mask = gdb.parse_and_eval("tick_broadcast_mask")
202 mask = pr_cpumask(mask)
203 text += "tick_broadcast_mask: {}\n".format(mask)
204 if constants.LX_CONFIG_TICK_ONESHOT:
205 mask = gdb.parse_and_eval("tick_broadcast_oneshot_mask")
206 mask = pr_cpumask(mask)
207 text += "tick_broadcast_oneshot_mask: {}\n".format(mask)
208 text += "\n"
209
210 tick_cpu_devices = gdb.parse_and_eval("&tick_cpu_device")
211 for cpu in cpus.each_online_cpu():
212 tick_dev = cpus.per_cpu(tick_cpu_devices, cpu)
213 text += print_tickdevice(tick_dev, cpu)
214 text += "\n"
215
216 gdb.write(text)
217
218
219LxTimerList()
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."""
66 return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), 66 return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
67 elementname.string()) 67 elementname.string())
68 68
69
69ContainerOf() 70ContainerOf()
70 71
71 72
@@ -148,14 +149,14 @@ def get_gdbserver_type():
148 def probe_qemu(): 149 def probe_qemu():
149 try: 150 try:
150 return gdb.execute("monitor info version", to_string=True) != "" 151 return gdb.execute("monitor info version", to_string=True) != ""
151 except: 152 except gdb.error:
152 return False 153 return False
153 154
154 def probe_kgdb(): 155 def probe_kgdb():
155 try: 156 try:
156 thread_info = gdb.execute("info thread 2", to_string=True) 157 thread_info = gdb.execute("info thread 2", to_string=True)
157 return "shadowCPU0" in thread_info 158 return "shadowCPU0" in thread_info
158 except: 159 except gdb.error:
159 return False 160 return False
160 161
161 global gdbserver_type 162 global gdbserver_type
@@ -172,7 +173,7 @@ def get_gdbserver_type():
172def gdb_eval_or_none(expresssion): 173def gdb_eval_or_none(expresssion):
173 try: 174 try:
174 return gdb.parse_and_eval(expresssion) 175 return gdb.parse_and_eval(expresssion)
175 except: 176 except gdb.error:
176 return None 177 return None
177 178
178 179
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:
27 import linux.modules 27 import linux.modules
28 import linux.dmesg 28 import linux.dmesg
29 import linux.tasks 29 import linux.tasks
30 import linux.config
30 import linux.cpus 31 import linux.cpus
31 import linux.lists 32 import linux.lists
33 import linux.rbtree
32 import linux.proc 34 import linux.proc
33 import linux.constants 35 import linux.constants
36 import linux.timerlist
37 import linux.clk
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 08ba146a83c5..492ac3410147 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -3,6 +3,7 @@
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 */ 4 */
5 5
6#include <sys/mman.h>
6#include <sys/stat.h> 7#include <sys/stat.h>
7#include <ctype.h> 8#include <ctype.h>
8#include <errno.h> 9#include <errno.h>
@@ -36,6 +37,52 @@ static bool is_dir(const char *path)
36 return S_ISDIR(st.st_mode); 37 return S_ISDIR(st.st_mode);
37} 38}
38 39
40/* return true if the given two files are the same, false otherwise */
41static bool is_same(const char *file1, const char *file2)
42{
43 int fd1, fd2;
44 struct stat st1, st2;
45 void *map1, *map2;
46 bool ret = false;
47
48 fd1 = open(file1, O_RDONLY);
49 if (fd1 < 0)
50 return ret;
51
52 fd2 = open(file2, O_RDONLY);
53 if (fd2 < 0)
54 goto close1;
55
56 ret = fstat(fd1, &st1);
57 if (ret)
58 goto close2;
59 ret = fstat(fd2, &st2);
60 if (ret)
61 goto close2;
62
63 if (st1.st_size != st2.st_size)
64 goto close2;
65
66 map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
67 if (map1 == MAP_FAILED)
68 goto close2;
69
70 map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
71 if (map2 == MAP_FAILED)
72 goto close2;
73
74 if (bcmp(map1, map2, st1.st_size))
75 goto close2;
76
77 ret = true;
78close2:
79 close(fd2);
80close1:
81 close(fd1);
82
83 return ret;
84}
85
39/* 86/*
40 * Create the parent directory of the given path. 87 * Create the parent directory of the given path.
41 * 88 *
@@ -179,7 +226,7 @@ const char *conf_get_configname(void)
179 return name ? name : ".config"; 226 return name ? name : ".config";
180} 227}
181 228
182const char *conf_get_autoconfig_name(void) 229static const char *conf_get_autoconfig_name(void)
183{ 230{
184 char *name = getenv("KCONFIG_AUTOCONFIG"); 231 char *name = getenv("KCONFIG_AUTOCONFIG");
185 232
@@ -194,7 +241,7 @@ char *conf_get_default_confname(void)
194 name = expand_string(conf_defname); 241 name = expand_string(conf_defname);
195 env = getenv(SRCTREE); 242 env = getenv(SRCTREE);
196 if (env) { 243 if (env) {
197 sprintf(fullname, "%s/%s", env, name); 244 snprintf(fullname, sizeof(fullname), "%s/%s", env, name);
198 if (is_present(fullname)) 245 if (is_present(fullname))
199 return fullname; 246 return fullname;
200 } 247 }
@@ -817,40 +864,34 @@ int conf_write(const char *name)
817 FILE *out; 864 FILE *out;
818 struct symbol *sym; 865 struct symbol *sym;
819 struct menu *menu; 866 struct menu *menu;
820 const char *basename;
821 const char *str; 867 const char *str;
822 char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; 868 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
823 char *env; 869 char *env;
824 870
825 dirname[0] = 0; 871 if (!name)
826 if (name && name[0]) { 872 name = conf_get_configname();
827 char *slash; 873
828 874 if (!*name) {
829 if (is_dir(name)) { 875 fprintf(stderr, "config name is empty\n");
830 strcpy(dirname, name); 876 return -1;
831 strcat(dirname, "/"); 877 }
832 basename = conf_get_configname(); 878
833 } else if ((slash = strrchr(name, '/'))) { 879 if (is_dir(name)) {
834 int size = slash - name + 1; 880 fprintf(stderr, "%s: Is a directory\n", name);
835 memcpy(dirname, name, size); 881 return -1;
836 dirname[size] = 0; 882 }
837 if (slash[1]) 883
838 basename = slash + 1; 884 if (make_parent_dir(name))
839 else 885 return -1;
840 basename = conf_get_configname(); 886
841 } else
842 basename = name;
843 } else
844 basename = conf_get_configname();
845
846 sprintf(newname, "%s%s", dirname, basename);
847 env = getenv("KCONFIG_OVERWRITECONFIG"); 887 env = getenv("KCONFIG_OVERWRITECONFIG");
848 if (!env || !*env) { 888 if (env && *env) {
849 sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
850 out = fopen(tmpname, "w");
851 } else {
852 *tmpname = 0; 889 *tmpname = 0;
853 out = fopen(newname, "w"); 890 out = fopen(name, "w");
891 } else {
892 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
893 name, (int)getpid());
894 out = fopen(tmpname, "w");
854 } 895 }
855 if (!out) 896 if (!out)
856 return 1; 897 return 1;
@@ -897,14 +938,20 @@ next:
897 fclose(out); 938 fclose(out);
898 939
899 if (*tmpname) { 940 if (*tmpname) {
900 strcat(dirname, basename); 941 if (is_same(name, tmpname)) {
901 strcat(dirname, ".old"); 942 conf_message("No change to %s", name);
902 rename(newname, dirname); 943 unlink(tmpname);
903 if (rename(tmpname, newname)) 944 sym_set_change_count(0);
945 return 0;
946 }
947
948 snprintf(oldname, sizeof(oldname), "%s.old", name);
949 rename(name, oldname);
950 if (rename(tmpname, name))
904 return 1; 951 return 1;
905 } 952 }
906 953
907 conf_message("configuration written to %s", newname); 954 conf_message("configuration written to %s", name);
908 955
909 sym_set_change_count(0); 956 sym_set_change_count(0);
910 957
@@ -917,8 +964,6 @@ static int conf_write_dep(const char *name)
917 struct file *file; 964 struct file *file;
918 FILE *out; 965 FILE *out;
919 966
920 if (!name)
921 name = ".kconfig.d";
922 out = fopen("..config.tmp", "w"); 967 out = fopen("..config.tmp", "w");
923 if (!out) 968 if (!out)
924 return 1; 969 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)
638void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) 638void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
639{ 639{
640 GtkWidget *dialog; 640 GtkWidget *dialog;
641 const gchar *intro_text = 641 const gchar *intro_text =
642 "Welcome to gkc, the GTK+ graphical configuration tool\n" 642 "Welcome to gkc, the GTK+ graphical configuration tool\n"
643 "For each option, a blank box indicates the feature is disabled, a\n" 643 "For each option, a blank box indicates the feature is disabled, a\n"
644 "check indicates it is enabled, and a dot indicates that it is to\n" 644 "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)
378 if (!f && name != NULL && name[0] != '/') { 378 if (!f && name != NULL && name[0] != '/') {
379 env = getenv(SRCTREE); 379 env = getenv(SRCTREE);
380 if (env) { 380 if (env) {
381 sprintf(fullname, "%s/%s", env, name); 381 snprintf(fullname, sizeof(fullname),
382 "%s/%s", env, name);
382 f = fopen(fullname, "r"); 383 f = fopen(fullname, "r");
383 } 384 }
384 } 385 }
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);
49 49
50/* confdata.c */ 50/* confdata.c */
51const char *conf_get_configname(void); 51const char *conf_get_configname(void);
52const char *conf_get_autoconfig_name(void);
53char *conf_get_default_confname(void); 52char *conf_get_default_confname(void);
54void sym_set_change_count(int count); 53void sym_set_change_count(int count);
55void sym_add_change_count(int count); 54void 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 @@
1This is NOT the official version of dialog. This version has been 1This is NOT the official version of dialog. This version has been
2significantly modified from the original. It is for use by the Linux 2significantly modified from the original. It is for use by the Linux
3kernel configuration script. Please do not bother Savio Lam with 3kernel configuration script. Please do not bother Savio Lam with
4questions about this program. 4questions about this program.
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 611945611bf8..1dcfb288ee63 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -113,7 +113,8 @@ do_resize:
113 case KEY_DOWN: 113 case KEY_DOWN:
114 break; 114 break;
115 case KEY_BACKSPACE: 115 case KEY_BACKSPACE:
116 case 127: 116 case 8: /* ^H */
117 case 127: /* ^? */
117 if (pos) { 118 if (pos) {
118 wattrset(dialog, dlg.inputbox.atr); 119 wattrset(dialog, dlg.inputbox.atr);
119 if (input_x == 0) { 120 if (input_x == 0) {
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)
936 set_config_filename(dialog_input_result); 936 set_config_filename(dialog_input_result);
937 return; 937 return;
938 } 938 }
939 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); 939 show_textbox(NULL, "Can't create file!", 5, 60);
940 break; 940 break;
941 case 1: 941 case 1:
942 show_helptext("Save Alternate Configuration", save_config_help); 942 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 a4670f4e825a..cbafe3bf082e 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -1048,7 +1048,7 @@ static int do_match(int key, struct match_state *state, int *ans)
1048 state->match_direction = FIND_NEXT_MATCH_UP; 1048 state->match_direction = FIND_NEXT_MATCH_UP;
1049 *ans = get_mext_match(state->pattern, 1049 *ans = get_mext_match(state->pattern,
1050 state->match_direction); 1050 state->match_direction);
1051 } else if (key == KEY_BACKSPACE || key == 127) { 1051 } else if (key == KEY_BACKSPACE || key == 8 || key == 127) {
1052 state->pattern[strlen(state->pattern)-1] = '\0'; 1052 state->pattern[strlen(state->pattern)-1] = '\0';
1053 adj_match_dir(&state->match_direction); 1053 adj_match_dir(&state->match_direction);
1054 } else 1054 } else
@@ -1438,8 +1438,7 @@ static void conf_save(void)
1438 set_config_filename(dialog_input_result); 1438 set_config_filename(dialog_input_result);
1439 return; 1439 return;
1440 } 1440 }
1441 btn_dialog(main_window, "Can't create file! " 1441 btn_dialog(main_window, "Can't create file!",
1442 "Probably a nonexistent directory.",
1443 1, "<OK>"); 1442 1, "<OK>");
1444 break; 1443 break;
1445 case 1: 1444 case 1:
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 7be620a1fcdb..77f525a8617c 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -439,7 +439,8 @@ int dialog_inputbox(WINDOW *main_window,
439 case KEY_F(F_EXIT): 439 case KEY_F(F_EXIT):
440 case KEY_F(F_BACK): 440 case KEY_F(F_BACK):
441 break; 441 break;
442 case 127: 442 case 8: /* ^H */
443 case 127: /* ^? */
443 case KEY_BACKSPACE: 444 case KEY_BACKSPACE:
444 if (cursor_position > 0) { 445 if (cursor_position > 0) {
445 memmove(&result[cursor_position-1], 446 memmove(&result[cursor_position-1],
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
35info() 35info()
36{ 36{
37 if [ "${quiet}" != "silent_" ]; then 37 if [ "${quiet}" != "silent_" ]; then
38 printf " %-7s %s\n" ${1} ${2} 38 printf " %-7s %s\n" "${1}" "${2}"
39 fi 39 fi
40} 40}
41 41
@@ -91,6 +91,25 @@ vmlinux_link()
91 fi 91 fi
92} 92}
93 93
94# generate .BTF typeinfo from DWARF debuginfo
95gen_btf()
96{
97 local pahole_ver;
98
99 if ! [ -x "$(command -v ${PAHOLE})" ]; then
100 info "BTF" "${1}: pahole (${PAHOLE}) is not available"
101 return 0
102 fi
103
104 pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
105 if [ "${pahole_ver}" -lt "113" ]; then
106 info "BTF" "${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13"
107 return 0
108 fi
109
110 info "BTF" ${1}
111 LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1}
112}
94 113
95# Create ${2} .o file with all symbols from the ${1} object file 114# Create ${2} .o file with all symbols from the ${1} object file
96kallsyms() 115kallsyms()
@@ -193,6 +212,9 @@ modpost_link vmlinux.o
193# modpost vmlinux.o to check for section mismatches 212# modpost vmlinux.o to check for section mismatches
194${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o 213${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
195 214
215info MODINFO modules.builtin.modinfo
216${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
217
196kallsymso="" 218kallsymso=""
197kallsyms_vmlinux="" 219kallsyms_vmlinux=""
198if [ -n "${CONFIG_KALLSYMS}" ]; then 220if [ -n "${CONFIG_KALLSYMS}" ]; then
@@ -248,6 +270,10 @@ fi
248info LD vmlinux 270info LD vmlinux
249vmlinux_link "${kallsymso}" vmlinux 271vmlinux_link "${kallsymso}" vmlinux
250 272
273if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
274 gen_btf vmlinux
275fi
276
251if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then 277if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then
252 info SORTEX vmlinux 278 info SORTEX vmlinux
253 sortextable vmlinux 279 sortextable vmlinux
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index 412f13fdff52..4d0faebb1719 100755
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -7,33 +7,11 @@
7# Usage 7# Usage
8# $1 - Kernel src directory 8# $1 - Kernel src directory
9 9
10# Only overwrite automatically generated Makefiles
11# (so we do not overwrite kernel Makefile)
12if test -e Makefile && ! grep -q Automatically Makefile
13then
14 exit 0
15fi
16if [ "${quiet}" != "silent_" ]; then 10if [ "${quiet}" != "silent_" ]; then
17 echo " GEN Makefile" 11 echo " GEN Makefile"
18fi 12fi
19 13
20cat << EOF > Makefile 14cat << EOF > Makefile
21# Automatically generated by $0: don't edit 15# Automatically generated by $(realpath $0): don't edit
22 16include $(realpath $1/Makefile)
23ifeq ("\$(origin V)", "command line")
24VERBOSE := \$(V)
25endif
26ifneq (\$(VERBOSE),1)
27Q := @
28endif
29
30MAKEFLAGS += --no-print-directory
31
32.PHONY: __sub-make \$(MAKECMDGOALS)
33
34__sub-make:
35 \$(Q)\$(MAKE) -C $1 O=\$(CURDIR) \$(MAKECMDGOALS)
36
37\$(filter-out __sub-make, \$(MAKECMDGOALS)): __sub-make
38 @:
39EOF 17EOF
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 0b0d1080b1c5..f277e116e0eb 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -639,7 +639,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
639 info->sechdrs[sym->st_shndx].sh_offset - 639 info->sechdrs[sym->st_shndx].sh_offset -
640 (info->hdr->e_type != ET_REL ? 640 (info->hdr->e_type != ET_REL ?
641 info->sechdrs[sym->st_shndx].sh_addr : 0); 641 info->sechdrs[sym->st_shndx].sh_addr : 0);
642 crc = *crcp; 642 crc = TO_NATIVE(*crcp);
643 } 643 }
644 sym_update_crc(symname + strlen("__crc_"), mod, crc, 644 sym_update_crc(symname + strlen("__crc_"), mod, crc,
645 export); 645 export);
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") {
397} elsif ($arch eq "nds32") { 397} elsif ($arch eq "nds32") {
398 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$"; 398 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$";
399 $alignment = 2; 399 $alignment = 2;
400} elsif ($arch eq "csky") {
401 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_CKCORE_PCREL_JSR_IMM26BY2\\s+_mcount\$";
402 $alignment = 2;
400} else { 403} else {
401 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 404 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
402} 405}
@@ -493,7 +496,7 @@ sub update_funcs
493# 496#
494# Step 2: find the sections and mcount call sites 497# Step 2: find the sections and mcount call sites
495# 498#
496open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump"; 499open(IN, "LANG=C $objdump -hdr $inputfile|") || die "error running $objdump";
497 500
498my $text; 501my $text;
499 502
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 @@
9#include <string.h> 9#include <string.h>
10#include <errno.h> 10#include <errno.h>
11#include <ctype.h> 11#include <ctype.h>
12#include <sys/socket.h>
13 12
14struct security_class_mapping { 13struct security_class_mapping {
15 const char *name; 14 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 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3set -e
3if [ `id -u` -ne 0 ]; then 4if [ `id -u` -ne 0 ]; then
4 echo "$0: must be root to install the selinux policy" 5 echo "$0: must be root to install the selinux policy"
5 exit 1 6 exit 1
6fi 7fi
8
7SF=`which setfiles` 9SF=`which setfiles`
8if [ $? -eq 1 ]; then 10if [ $? -eq 1 ]; then
9 if [ -f /sbin/setfiles ]; then 11 echo "Could not find setfiles"
10 SF="/usr/setfiles" 12 echo "Do you have policycoreutils installed?"
11 else 13 exit 1
12 echo "no selinux tools installed: setfiles"
13 exit 1
14 fi
15fi 14fi
16 15
17cd mdp
18
19CP=`which checkpolicy` 16CP=`which checkpolicy`
17if [ $? -eq 1 ]; then
18 echo "Could not find checkpolicy"
19 echo "Do you have checkpolicy installed?"
20 exit 1
21fi
20VERS=`$CP -V | awk '{print $1}'` 22VERS=`$CP -V | awk '{print $1}'`
21 23
22./mdp policy.conf file_contexts 24ENABLED=`which selinuxenabled`
23$CP -o policy.$VERS policy.conf 25if [ $? -eq 1 ]; then
26 echo "Could not find selinuxenabled"
27 echo "Do you have libselinux-utils installed?"
28 exit 1
29fi
30
31if selinuxenabled; then
32 echo "SELinux is already enabled"
33 echo "This prevents safely relabeling all files."
34 echo "Boot with selinux=0 on the kernel command-line or"
35 echo "SELINUX=disabled in /etc/selinux/config."
36 exit 1
37fi
38
39cd mdp
40./mdp -m policy.conf file_contexts
41$CP -U allow -M -o policy.$VERS policy.conf
24 42
25mkdir -p /etc/selinux/dummy/policy 43mkdir -p /etc/selinux/dummy/policy
26mkdir -p /etc/selinux/dummy/contexts/files 44mkdir -p /etc/selinux/dummy/contexts/files
27 45
46echo "__default__:user_u:s0" > /etc/selinux/dummy/seusers
47echo "base_r:base_t:s0" > /etc/selinux/dummy/contexts/failsafe_context
48echo "base_r:base_t:s0 base_r:base_t:s0" > /etc/selinux/dummy/default_contexts
49cat > /etc/selinux/dummy/contexts/x_contexts <<EOF
50client * user_u:base_r:base_t:s0
51property * user_u:object_r:base_t:s0
52extension * user_u:object_r:base_t:s0
53selection * user_u:object_r:base_t:s0
54event * user_u:object_r:base_t:s0
55EOF
56touch /etc/selinux/dummy/contexts/virtual_domain_context
57touch /etc/selinux/dummy/contexts/virtual_image_context
58
28cp file_contexts /etc/selinux/dummy/contexts/files 59cp file_contexts /etc/selinux/dummy/contexts/files
29cp dbus_contexts /etc/selinux/dummy/contexts 60cp dbus_contexts /etc/selinux/dummy/contexts
30cp policy.$VERS /etc/selinux/dummy/policy 61cp policy.$VERS /etc/selinux/dummy/policy
@@ -33,37 +64,22 @@ FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts
33if [ ! -d /etc/selinux ]; then 64if [ ! -d /etc/selinux ]; then
34 mkdir -p /etc/selinux 65 mkdir -p /etc/selinux
35fi 66fi
36if [ ! -f /etc/selinux/config ]; then 67if [ -f /etc/selinux/config ]; then
37 cat > /etc/selinux/config << EOF 68 echo "/etc/selinux/config exists, moving to /etc/selinux/config.bak."
38SELINUX=enforcing 69 mv /etc/selinux/config /etc/selinux/config.bak
70fi
71echo "Creating new /etc/selinux/config for dummy policy."
72cat > /etc/selinux/config << EOF
73SELINUX=permissive
39SELINUXTYPE=dummy 74SELINUXTYPE=dummy
40EOF 75EOF
41else
42 TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}`
43 if [ "eq$TYPE" != "eqdummy" ]; then
44 selinuxenabled
45 if [ $? -eq 0 ]; then
46 echo "SELinux already enabled with a non-dummy policy."
47 echo "Exiting. Please install policy by hand if that"
48 echo "is what you REALLY want."
49 exit 1
50 fi
51 mv /etc/selinux/config /etc/selinux/config.mdpbak
52 grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config
53 echo "SELINUXTYPE=dummy" >> /etc/selinux/config
54 fi
55fi
56 76
57cd /etc/selinux/dummy/contexts/files 77cd /etc/selinux/dummy/contexts/files
58$SF file_contexts / 78$SF -F file_contexts /
59 79
60mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}` 80mounts=`cat /proc/$$/mounts | \
61$SF file_contexts $mounts 81 egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
82 awk '{ print $2 '}`
83$SF -F file_contexts $mounts
62 84
63 85echo "-F" > /.autorelabel
64dodev=`cat /proc/$$/mounts | grep "/dev "`
65if [ "eq$dodev" != "eq" ]; then
66 mount --move /dev /mnt
67 $SF file_contexts /dev
68 mount --move /mnt /dev
69fi
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 @@
2hostprogs-y := mdp 2hostprogs-y := mdp
3HOST_EXTRACFLAGS += \ 3HOST_EXTRACFLAGS += \
4 -I$(srctree)/include/uapi -I$(srctree)/include \ 4 -I$(srctree)/include/uapi -I$(srctree)/include \
5 -I$(srctree)/security/selinux/include 5 -I$(srctree)/security/selinux/include -I$(objtree)/include
6 6
7always := $(hostprogs-y) 7always := $(hostprogs-y)
8clean-files := policy.* file_contexts 8clean-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 @@
32#include <stdlib.h> 32#include <stdlib.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <string.h> 34#include <string.h>
35#include <sys/socket.h> 35#include <linux/kconfig.h>
36 36
37static void usage(char *name) 37static void usage(char *name)
38{ 38{
@@ -95,10 +95,31 @@ int main(int argc, char *argv[])
95 } 95 }
96 fprintf(fout, "\n"); 96 fprintf(fout, "\n");
97 97
98 /* NOW PRINT OUT MLS STUFF */ 98 /* print out mls declarations and constraints */
99 if (mls) { 99 if (mls) {
100 printf("MLS not yet implemented\n"); 100 fprintf(fout, "sensitivity s0;\n");
101 exit(1); 101 fprintf(fout, "sensitivity s1;\n");
102 fprintf(fout, "dominance { s0 s1 }\n");
103 fprintf(fout, "category c0;\n");
104 fprintf(fout, "category c1;\n");
105 fprintf(fout, "level s0:c0.c1;\n");
106 fprintf(fout, "level s1:c0.c1;\n");
107#define SYSTEMLOW "s0"
108#define SYSTEMHIGH "s1:c0.c1"
109 for (i = 0; secclass_map[i].name; i++) {
110 struct security_class_mapping *map = &secclass_map[i];
111
112 fprintf(fout, "mlsconstrain %s {\n", map->name);
113 for (j = 0; map->perms[j]; j++)
114 fprintf(fout, "\t%s\n", map->perms[j]);
115 /*
116 * This requires all subjects and objects to be
117 * single-level (l2 eq h2), and that the subject
118 * level dominate the object level (h1 dom h2)
119 * in order to have any permissions to it.
120 */
121 fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n");
122 }
102 } 123 }
103 124
104 /* types, roles, and allows */ 125 /* types, roles, and allows */
@@ -108,34 +129,127 @@ int main(int argc, char *argv[])
108 for (i = 0; secclass_map[i].name; i++) 129 for (i = 0; secclass_map[i].name; i++)
109 fprintf(fout, "allow base_t base_t:%s *;\n", 130 fprintf(fout, "allow base_t base_t:%s *;\n",
110 secclass_map[i].name); 131 secclass_map[i].name);
111 fprintf(fout, "user user_u roles { base_r };\n"); 132 fprintf(fout, "user user_u roles { base_r }");
112 fprintf(fout, "\n"); 133 if (mls)
134 fprintf(fout, " level %s range %s - %s", SYSTEMLOW,
135 SYSTEMLOW, SYSTEMHIGH);
136 fprintf(fout, ";\n");
137
138#define SUBJUSERROLETYPE "user_u:base_r:base_t"
139#define OBJUSERROLETYPE "user_u:object_r:base_t"
113 140
114 /* default sids */ 141 /* default sids */
115 for (i = 1; i < initial_sid_to_string_len; i++) 142 for (i = 1; i < initial_sid_to_string_len; i++)
116 fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); 143 fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n",
144 initial_sid_to_string[i], mls ? ":" SYSTEMLOW : "");
117 fprintf(fout, "\n"); 145 fprintf(fout, "\n");
118 146
119 fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); 147#define FS_USE(behavior, fstype) \
120 fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); 148 fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \
121 fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n"); 149 behavior, fstype, mls ? ":" SYSTEMLOW : "")
122 fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); 150
123 fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); 151 /*
124 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); 152 * Filesystems whose inode labels can be fetched via getxattr.
125 fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); 153 */
126 fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); 154#ifdef CONFIG_EXT2_FS_SECURITY
155 FS_USE("xattr", "ext2");
156#endif
157#ifdef CONFIG_EXT4_FS_SECURITY
158#ifdef CONFIG_EXT4_USE_FOR_EXT2
159 FS_USE("xattr", "ext2");
160#endif
161 FS_USE("xattr", "ext3");
162 FS_USE("xattr", "ext4");
163#endif
164#ifdef CONFIG_JFS_SECURITY
165 FS_USE("xattr", "jfs");
166#endif
167#ifdef CONFIG_REISERFS_FS_SECURITY
168 FS_USE("xattr", "reiserfs");
169#endif
170#ifdef CONFIG_JFFS2_FS_SECURITY
171 FS_USE("xattr", "jffs2");
172#endif
173#ifdef CONFIG_XFS_FS
174 FS_USE("xattr", "xfs");
175#endif
176#ifdef CONFIG_GFS2_FS
177 FS_USE("xattr", "gfs2");
178#endif
179#ifdef CONFIG_BTRFS_FS
180 FS_USE("xattr", "btrfs");
181#endif
182#ifdef CONFIG_F2FS_FS_SECURITY
183 FS_USE("xattr", "f2fs");
184#endif
185#ifdef CONFIG_OCFS2_FS
186 FS_USE("xattr", "ocsfs2");
187#endif
188#ifdef CONFIG_OVERLAY_FS
189 FS_USE("xattr", "overlay");
190#endif
191#ifdef CONFIG_SQUASHFS_XATTR
192 FS_USE("xattr", "squashfs");
193#endif
194
195 /*
196 * Filesystems whose inodes are labeled from allocating task.
197 */
198 FS_USE("task", "pipefs");
199 FS_USE("task", "sockfs");
127 200
128 fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); 201 /*
129 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); 202 * Filesystems whose inode labels are computed from both
130 fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); 203 * the allocating task and the superblock label.
204 */
205#ifdef CONFIG_UNIX98_PTYS
206 FS_USE("trans", "devpts");
207#endif
208#ifdef CONFIG_HUGETLBFS
209 FS_USE("trans", "hugetlbfs");
210#endif
211#ifdef CONFIG_TMPFS
212 FS_USE("trans", "tmpfs");
213#endif
214#ifdef CONFIG_DEVTMPFS
215 FS_USE("trans", "devtmpfs");
216#endif
217#ifdef CONFIG_POSIX_MQUEUE
218 FS_USE("trans", "mqueue");
219#endif
131 220
132 fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n"); 221#define GENFSCON(fstype, prefix) \
133 fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); 222 fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \
134 fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n"); 223 fstype, prefix, mls ? ":" SYSTEMLOW : "")
135 fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
136 fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
137 224
138 fprintf(fout, "genfscon proc / user_u:base_r:base_t\n"); 225 /*
226 * Filesystems whose inodes are labeled from path prefix match
227 * relative to the filesystem root. Depending on the filesystem,
228 * only a single label for all inodes may be supported. Here
229 * we list the filesystem types for which per-file labeling is
230 * supported using genfscon; any other filesystem type can also
231 * be added by only with a single entry for all of its inodes.
232 */
233#ifdef CONFIG_PROC_FS
234 GENFSCON("proc", "/");
235#endif
236#ifdef CONFIG_SECURITY_SELINUX
237 GENFSCON("selinuxfs", "/");
238#endif
239#ifdef CONFIG_SYSFS
240 GENFSCON("sysfs", "/");
241#endif
242#ifdef CONFIG_DEBUG_FS
243 GENFSCON("debugfs", "/");
244#endif
245#ifdef CONFIG_TRACING
246 GENFSCON("tracefs", "/");
247#endif
248#ifdef CONFIG_PSTORE
249 GENFSCON("pstore", "/");
250#endif
251 GENFSCON("cgroup", "/");
252 GENFSCON("cgroup2", "/");
139 253
140 fclose(fout); 254 fclose(fout);
141 255
@@ -144,8 +258,8 @@ int main(int argc, char *argv[])
144 printf("Wrote policy, but cannot open %s for writing\n", ctxout); 258 printf("Wrote policy, but cannot open %s for writing\n", ctxout);
145 usage(argv[0]); 259 usage(argv[0]);
146 } 260 }
147 fprintf(fout, "/ user_u:base_r:base_t\n"); 261 fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : "");
148 fprintf(fout, "/.* user_u:base_r:base_t\n"); 262 fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : "");
149 fclose(fout); 263 fclose(fout);
150 264
151 return 0; 265 return 0;
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()
532 check_program("dot", 1); 532 check_program("dot", 1);
533 check_program("convert", 1); 533 check_program("convert", 1);
534 check_program("rsvg-convert", 1) if ($pdf); 534 check_program("rsvg-convert", 1) if ($pdf);
535 check_program("latexmk", 1) if ($pdf);
535 536
536 check_distros(); 537 check_distros();
537 538
diff --git a/scripts/tags.sh b/scripts/tags.sh
index f470d9919ed7..70e14c67bde7 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -19,7 +19,7 @@ ignore="$ignore ( -name *.mod.c ) -prune -o"
19# Do not use full path if we do not use O=.. builds 19# Do not use full path if we do not use O=.. builds
20# Use make O=. {tags|cscope} 20# Use make O=. {tags|cscope}
21# to force full paths for a non-O= build 21# to force full paths for a non-O= build
22if [ "${KBUILD_SRC}" = "" ]; then 22if [ "${srctree}" = "." -o -z "${srctree}" ]; then
23 tree= 23 tree=
24else 24else
25 tree=${srctree}/ 25 tree=${srctree}/