1 |
commit: 91c3b96e63792590118e17193061908a07017497 |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon May 30 08:00:17 2016 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon May 30 08:00:17 2016 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=91c3b96e |
7 |
|
8 |
grsecurity-3.1-4.5.5-201605291201 |
9 |
|
10 |
4.5.5/0000_README | 2 +- |
11 |
...> 4420_grsecurity-3.1-4.5.5-201605291201.patch} | 18852 ++++++++++--------- |
12 |
2 files changed, 9793 insertions(+), 9061 deletions(-) |
13 |
|
14 |
diff --git a/4.5.5/0000_README b/4.5.5/0000_README |
15 |
index febdb77..71dba33 100644 |
16 |
--- a/4.5.5/0000_README |
17 |
+++ b/4.5.5/0000_README |
18 |
@@ -2,7 +2,7 @@ README |
19 |
----------------------------------------------------------------------------- |
20 |
Individual Patch Descriptions: |
21 |
----------------------------------------------------------------------------- |
22 |
-Patch: 4420_grsecurity-3.1-4.5.5-201605211442.patch |
23 |
+Patch: 4420_grsecurity-3.1-4.5.5-201605291201.patch |
24 |
From: http://www.grsecurity.net |
25 |
Desc: hardened-sources base patch from upstream grsecurity |
26 |
|
27 |
|
28 |
diff --git a/4.5.5/4420_grsecurity-3.1-4.5.5-201605211442.patch b/4.5.5/4420_grsecurity-3.1-4.5.5-201605291201.patch |
29 |
similarity index 99% |
30 |
rename from 4.5.5/4420_grsecurity-3.1-4.5.5-201605211442.patch |
31 |
rename to 4.5.5/4420_grsecurity-3.1-4.5.5-201605291201.patch |
32 |
index 7202c18..1fb08ce 100644 |
33 |
--- a/4.5.5/4420_grsecurity-3.1-4.5.5-201605211442.patch |
34 |
+++ b/4.5.5/4420_grsecurity-3.1-4.5.5-201605291201.patch |
35 |
@@ -408,7 +408,7 @@ index a93b414..f50a50b 100644 |
36 |
|
37 |
A toggle value indicating if modules are allowed to be loaded |
38 |
diff --git a/Makefile b/Makefile |
39 |
-index a23df41..314f8da 100644 |
40 |
+index a23df41..db4f30b 100644 |
41 |
--- a/Makefile |
42 |
+++ b/Makefile |
43 |
@@ -298,7 +298,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ |
44 |
@@ -422,27 +422,41 @@ index a23df41..314f8da 100644 |
45 |
|
46 |
ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1) |
47 |
HOSTCFLAGS += -Wno-unused-value -Wno-unused-parameter \ |
48 |
-@@ -434,8 +436,8 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \ |
49 |
- # Rules shared between *config targets and build targets |
50 |
- |
51 |
- # Basic helpers built in scripts/ |
52 |
--PHONY += scripts_basic |
53 |
--scripts_basic: |
54 |
-+PHONY += scripts_basic gcc-plugins |
55 |
-+scripts_basic: gcc-plugins |
56 |
- $(Q)$(MAKE) $(build)=scripts/basic |
57 |
- $(Q)rm -f .tmp_quiet_recordmcount |
58 |
- |
59 |
-@@ -622,6 +624,8 @@ endif |
60 |
+@@ -417,6 +419,8 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE |
61 |
+ export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL |
62 |
+ export KBUILD_ARFLAGS |
63 |
+ |
64 |
++export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS |
65 |
++ |
66 |
+ # When compiling out-of-tree modules, put MODVERDIR in the module |
67 |
+ # tree rather than in the kernel tree. The kernel tree might |
68 |
+ # even be read-only. |
69 |
+@@ -547,7 +551,7 @@ ifeq ($(KBUILD_EXTMOD),) |
70 |
+ # in parallel |
71 |
+ PHONY += scripts |
72 |
+ scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ |
73 |
+- asm-generic |
74 |
++ asm-generic gcc-plugins |
75 |
+ $(Q)$(MAKE) $(build)=$(@) |
76 |
+ |
77 |
+ # Objects we will link into vmlinux / subdirs we need to visit |
78 |
+@@ -622,6 +626,15 @@ endif |
79 |
# Tell gcc to never replace conditional load with a non-conditional one |
80 |
KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) |
81 |
|
82 |
++PHONY += gcc-plugins |
83 |
++gcc-plugins: scripts_basic |
84 |
++ifdef CONFIG_GCC_PLUGINS |
85 |
++ $(Q)$(MAKE) $(build)=scripts/gcc-plugins |
86 |
++endif |
87 |
++ @: |
88 |
++ |
89 |
+include scripts/Makefile.gcc-plugins |
90 |
+ |
91 |
ifdef CONFIG_READABLE_ASM |
92 |
# Disable optimizations that make assembler listings hard to read. |
93 |
# reorder blocks reorders the control in the function |
94 |
-@@ -714,7 +718,7 @@ KBUILD_CFLAGS += $(call cc-option, -gsplit-dwarf, -g) |
95 |
+@@ -714,7 +727,7 @@ KBUILD_CFLAGS += $(call cc-option, -gsplit-dwarf, -g) |
96 |
else |
97 |
KBUILD_CFLAGS += -g |
98 |
endif |
99 |
@@ -451,7 +465,7 @@ index a23df41..314f8da 100644 |
100 |
endif |
101 |
ifdef CONFIG_DEBUG_INFO_DWARF4 |
102 |
KBUILD_CFLAGS += $(call cc-option, -gdwarf-4,) |
103 |
-@@ -886,7 +890,7 @@ export mod_sign_cmd |
104 |
+@@ -886,7 +899,7 @@ export mod_sign_cmd |
105 |
|
106 |
|
107 |
ifeq ($(KBUILD_EXTMOD),) |
108 |
@@ -460,57 +474,16 @@ index a23df41..314f8da 100644 |
109 |
|
110 |
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ |
111 |
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \ |
112 |
-@@ -937,6 +941,8 @@ endif |
113 |
- |
114 |
- # The actual objects are generated when descending, |
115 |
- # make sure no implicit rule kicks in |
116 |
-+$(filter-out $(init-y),$(vmlinux-deps)): KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
117 |
-+$(filter-out $(init-y),$(vmlinux-deps)): KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
118 |
- $(sort $(vmlinux-deps)): $(vmlinux-dirs) ; |
119 |
- |
120 |
- # Handle descending into subdirectories listed in $(vmlinux-dirs) |
121 |
-@@ -946,7 +952,7 @@ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ; |
122 |
- # Error messages still appears in the original language |
123 |
- |
124 |
- PHONY += $(vmlinux-dirs) |
125 |
--$(vmlinux-dirs): prepare scripts |
126 |
-+$(vmlinux-dirs): gcc-plugins prepare scripts |
127 |
- $(Q)$(MAKE) $(build)=$@ |
128 |
- |
129 |
- define filechk_kernel.release |
130 |
-@@ -989,10 +995,13 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ |
131 |
+@@ -989,7 +1002,7 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ |
132 |
|
133 |
archprepare: archheaders archscripts prepare1 scripts_basic |
134 |
|
135 |
-+prepare0: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
136 |
-+prepare0: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
137 |
- prepare0: archprepare FORCE |
138 |
+-prepare0: archprepare FORCE |
139 |
++prepare0: archprepare gcc-plugins FORCE |
140 |
$(Q)$(MAKE) $(build)=. |
141 |
|
142 |
# All the preparing.. |
143 |
-+prepare: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) |
144 |
- prepare: prepare0 |
145 |
- |
146 |
- # Generate some files |
147 |
-@@ -1103,6 +1112,8 @@ all: modules |
148 |
- # using awk while concatenating to the final file. |
149 |
- |
150 |
- PHONY += modules |
151 |
-+modules: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
152 |
-+modules: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
153 |
- modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin |
154 |
- $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order |
155 |
- @$(kecho) ' Building modules, stage 2.'; |
156 |
-@@ -1118,7 +1129,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) |
157 |
- |
158 |
- # Target to prepare building external modules |
159 |
- PHONY += modules_prepare |
160 |
--modules_prepare: prepare scripts |
161 |
-+modules_prepare: gcc-plugins prepare scripts |
162 |
- |
163 |
- # Target to install modules |
164 |
- PHONY += modules_install |
165 |
-@@ -1184,7 +1195,11 @@ MRPROPER_FILES += .config .config.old .version .old_version \ |
166 |
+@@ -1184,7 +1197,11 @@ MRPROPER_FILES += .config .config.old .version .old_version \ |
167 |
Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \ |
168 |
signing_key.pem signing_key.priv signing_key.x509 \ |
169 |
x509.genkey extra_certificates signing_key.x509.keyid \ |
170 |
@@ -523,7 +496,7 @@ index a23df41..314f8da 100644 |
171 |
|
172 |
# clean - Delete most, but leave enough to build external modules |
173 |
# |
174 |
-@@ -1223,7 +1238,7 @@ distclean: mrproper |
175 |
+@@ -1223,7 +1240,7 @@ distclean: mrproper |
176 |
@find $(srctree) $(RCS_FIND_IGNORE) \ |
177 |
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \ |
178 |
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ |
179 |
@@ -532,59 +505,31 @@ index a23df41..314f8da 100644 |
180 |
-type f -print | xargs rm -f |
181 |
|
182 |
|
183 |
-@@ -1390,6 +1405,8 @@ PHONY += $(module-dirs) modules |
184 |
- $(module-dirs): crmodverdir $(objtree)/Module.symvers |
185 |
- $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) |
186 |
+diff --git a/arch/Kconfig b/arch/Kconfig |
187 |
+index f6b649d..5ba628b 100644 |
188 |
+--- a/arch/Kconfig |
189 |
++++ b/arch/Kconfig |
190 |
+@@ -353,6 +353,20 @@ config SECCOMP_FILTER |
191 |
|
192 |
-+modules: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
193 |
-+modules: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
194 |
- modules: $(module-dirs) |
195 |
- @$(kecho) ' Building modules, stage 2.'; |
196 |
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost |
197 |
-@@ -1531,17 +1548,21 @@ else |
198 |
- target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) |
199 |
- endif |
200 |
+ See Documentation/prctl/seccomp_filter.txt for details. |
201 |
|
202 |
--%.s: %.c prepare scripts FORCE |
203 |
-+%.s: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
204 |
-+%.s: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
205 |
-+%.s: %.c gcc-plugins prepare scripts FORCE |
206 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
207 |
- %.i: %.c prepare scripts FORCE |
208 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
209 |
--%.o: %.c prepare scripts FORCE |
210 |
-+%.o: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
211 |
-+%.o: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
212 |
-+%.o: %.c gcc-plugins prepare scripts FORCE |
213 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
214 |
- %.lst: %.c prepare scripts FORCE |
215 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
216 |
--%.s: %.S prepare scripts FORCE |
217 |
-+%.s: %.S gcc-plugins prepare scripts FORCE |
218 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
219 |
--%.o: %.S prepare scripts FORCE |
220 |
-+%.o: %.S gcc-plugins prepare scripts FORCE |
221 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
222 |
- %.symtypes: %.c prepare scripts FORCE |
223 |
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) |
224 |
-@@ -1553,11 +1574,15 @@ endif |
225 |
- $(build)=$(build-dir) |
226 |
- # Make sure the latest headers are built for Documentation |
227 |
- Documentation/: headers_install |
228 |
--%/: prepare scripts FORCE |
229 |
-+%/: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
230 |
-+%/: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
231 |
-+%/: gcc-plugins prepare scripts FORCE |
232 |
- $(cmd_crmodverdir) |
233 |
- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ |
234 |
- $(build)=$(build-dir) |
235 |
--%.ko: prepare scripts FORCE |
236 |
-+%.ko: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
237 |
-+%.ko: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
238 |
-+%.ko: gcc-plugins prepare scripts FORCE |
239 |
- $(cmd_crmodverdir) |
240 |
- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ |
241 |
- $(build)=$(build-dir) $(@:.ko=.o) |
242 |
++config HAVE_GCC_PLUGINS |
243 |
++ bool |
244 |
++ help |
245 |
++ An arch should select this symbol if it supports building with |
246 |
++ GCC plugins. |
247 |
++ |
248 |
++menuconfig GCC_PLUGINS |
249 |
++ bool "GCC plugins" |
250 |
++ depends on HAVE_GCC_PLUGINS |
251 |
++ default y |
252 |
++ help |
253 |
++ GCC plugins are loadable modules that provide extra features to the |
254 |
++ compiler. They are useful for runtime instrumentation and static analysis. |
255 |
++ |
256 |
+ config HAVE_CC_STACKPROTECTOR |
257 |
+ bool |
258 |
+ help |
259 |
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h |
260 |
index 572b228..e03acdd 100644 |
261 |
--- a/arch/alpha/include/asm/atomic.h |
262 |
@@ -928,10 +873,18 @@ index 8a188bc..26608f1 100644 |
263 |
Counts number of I and D TLB Misses and exports them via Debugfs |
264 |
The counters can be cleared via Debugfs as well |
265 |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig |
266 |
-index 4f799e5..cc1200e 100644 |
267 |
+index 4f799e5..c1e2b95 100644 |
268 |
--- a/arch/arm/Kconfig |
269 |
+++ b/arch/arm/Kconfig |
270 |
-@@ -1622,6 +1622,7 @@ config HIGHPTE |
271 |
+@@ -53,6 +53,7 @@ config ARM |
272 |
+ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) |
273 |
+ select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) |
274 |
+ select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) |
275 |
++ select HAVE_GCC_PLUGINS |
276 |
+ select HAVE_GENERIC_DMA_COHERENT |
277 |
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) |
278 |
+ select HAVE_IDE if PCI || ISA || PCMCIA |
279 |
+@@ -1622,6 +1623,7 @@ config HIGHPTE |
280 |
config CPU_SW_DOMAIN_PAN |
281 |
bool "Enable use of CPU domains to implement privileged no-access" |
282 |
depends on MMU && !ARM_LPAE |
283 |
@@ -939,7 +892,7 @@ index 4f799e5..cc1200e 100644 |
284 |
default y |
285 |
help |
286 |
Increase kernel security by ensuring that normal kernel accesses |
287 |
-@@ -1698,7 +1699,7 @@ config ALIGNMENT_TRAP |
288 |
+@@ -1698,7 +1700,7 @@ config ALIGNMENT_TRAP |
289 |
|
290 |
config UACCESS_WITH_MEMCPY |
291 |
bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()" |
292 |
@@ -948,7 +901,7 @@ index 4f799e5..cc1200e 100644 |
293 |
default y if CPU_FEROCEON |
294 |
help |
295 |
Implement faster copy_to_user and clear_user methods for CPU |
296 |
-@@ -1953,6 +1954,7 @@ config KEXEC |
297 |
+@@ -1953,6 +1955,7 @@ config KEXEC |
298 |
depends on (!SMP || PM_SLEEP_SMP) |
299 |
depends on !CPU_V7M |
300 |
select KEXEC_CORE |
301 |
@@ -956,7 +909,7 @@ index 4f799e5..cc1200e 100644 |
302 |
help |
303 |
kexec is a system call that implements the ability to shutdown your |
304 |
current kernel, and to start another kernel. It is like a reboot |
305 |
-@@ -1997,7 +1999,7 @@ config EFI_STUB |
306 |
+@@ -1997,7 +2000,7 @@ config EFI_STUB |
307 |
|
308 |
config EFI |
309 |
bool "UEFI runtime support" |
310 |
@@ -977,6 +930,19 @@ index c6b6175..2884505 100644 |
311 |
---help--- |
312 |
Say Y here if you want to show the kernel pagetable layout in a |
313 |
debugfs file. This information is only useful for kernel developers |
314 |
+diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile |
315 |
+index 43788b1..2efefcf 100644 |
316 |
+--- a/arch/arm/boot/compressed/Makefile |
317 |
++++ b/arch/arm/boot/compressed/Makefile |
318 |
+@@ -106,6 +106,8 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS) |
319 |
+ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) |
320 |
+ endif |
321 |
+ |
322 |
++KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) |
323 |
++ |
324 |
+ # -fstack-protector-strong triggers protection checks in this code, |
325 |
+ # but it is being used too early to link to meaningful stack_chk logic. |
326 |
+ nossp_flags := $(call cc-option, -fno-stack-protector) |
327 |
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h |
328 |
index 9e10c45..24a14ce 100644 |
329 |
--- a/arch/arm/include/asm/atomic.h |
330 |
@@ -3357,7 +3323,7 @@ index 6bd1089..e999400 100644 |
331 |
{ |
332 |
unsigned long ua_flags; |
333 |
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c |
334 |
-index c169cc3..f290a77 100644 |
335 |
+index c169cc3..b007ec6 100644 |
336 |
--- a/arch/arm/mach-exynos/suspend.c |
337 |
+++ b/arch/arm/mach-exynos/suspend.c |
338 |
@@ -734,8 +734,10 @@ void __init exynos_pm_init(void) |
339 |
@@ -3367,8 +3333,8 @@ index c169cc3..f290a77 100644 |
340 |
- exynos_pm_syscore_ops.suspend = pm_data->pm_suspend; |
341 |
- exynos_pm_syscore_ops.resume = pm_data->pm_resume; |
342 |
+ pax_open_kernel(); |
343 |
-+ *(void **)&exynos_pm_syscore_ops.suspend = pm_data->pm_suspend; |
344 |
-+ *(void **)&exynos_pm_syscore_ops.resume = pm_data->pm_resume; |
345 |
++ const_cast(exynos_pm_syscore_ops.suspend) = pm_data->pm_suspend; |
346 |
++ const_cast(exynos_pm_syscore_ops.resume) = pm_data->pm_resume; |
347 |
+ pax_close_kernel(); |
348 |
|
349 |
register_syscore_ops(&exynos_pm_syscore_ops); |
350 |
@@ -3501,7 +3467,7 @@ index 2af6ff6..1f2959f 100644 |
351 |
/* omap_hwmod_list contains all registered struct omap_hwmods */ |
352 |
static LIST_HEAD(omap_hwmod_list); |
353 |
diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c |
354 |
-index 95fee54..cfa9cf1 100644 |
355 |
+index 95fee54..b5dd79d 100644 |
356 |
--- a/arch/arm/mach-omap2/powerdomains43xx_data.c |
357 |
+++ b/arch/arm/mach-omap2/powerdomains43xx_data.c |
358 |
@@ -10,6 +10,7 @@ |
359 |
@@ -3518,7 +3484,7 @@ index 95fee54..cfa9cf1 100644 |
360 |
{ |
361 |
- omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp; |
362 |
+ pax_open_kernel(); |
363 |
-+ *(void **)&omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp; |
364 |
++ const_cast(omap4_pwrdm_operations.pwrdm_has_voltdm) = am43xx_check_vcvp; |
365 |
+ pax_close_kernel(); |
366 |
pwrdm_register_platform_funcs(&omap4_pwrdm_operations); |
367 |
pwrdm_register_pwrdms(powerdomains_am43xx); |
368 |
@@ -3548,7 +3514,7 @@ index ff0a68c..b312aa0 100644 |
369 |
sizeof(struct omap_wd_timer_platform_data)); |
370 |
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", |
371 |
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c |
372 |
-index aba75c8..b55a9d7 100644 |
373 |
+index aba75c8..b2b340f 100644 |
374 |
--- a/arch/arm/mach-shmobile/platsmp-apmu.c |
375 |
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c |
376 |
@@ -22,6 +22,7 @@ |
377 |
@@ -3565,7 +3531,7 @@ index aba75c8..b55a9d7 100644 |
378 |
{ |
379 |
- shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend; |
380 |
+ pax_open_kernel(); |
381 |
-+ *(void **)&shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend; |
382 |
++ const_cast(shmobile_suspend_ops.enter) = shmobile_smp_apmu_enter_suspend; |
383 |
+ pax_close_kernel(); |
384 |
} |
385 |
#endif |
386 |
@@ -3727,7 +3693,7 @@ index c8c8b9e..c55cc79 100644 |
387 |
atomic64_set(&mm->context.id, asid); |
388 |
} |
389 |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c |
390 |
-index daafcf1..8205ed6 100644 |
391 |
+index daafcf1..a04e1fd 100644 |
392 |
--- a/arch/arm/mm/fault.c |
393 |
+++ b/arch/arm/mm/fault.c |
394 |
@@ -25,6 +25,7 @@ |
395 |
@@ -3841,7 +3807,7 @@ index daafcf1..8205ed6 100644 |
396 |
pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", |
397 |
inf->name, fsr, addr); |
398 |
show_pte(current->mm, addr); |
399 |
-@@ -574,15 +647,104 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs * |
400 |
+@@ -574,15 +647,118 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs * |
401 |
ifsr_info[nr].name = name; |
402 |
} |
403 |
|
404 |
@@ -3879,6 +3845,13 @@ index daafcf1..8205ed6 100644 |
405 |
+ */ |
406 |
+ // dmb(); implied by the exception |
407 |
+ regs->ARM_pc = regs->ARM_lr; |
408 |
++#ifdef CONFIG_ARM_THUMB |
409 |
++ if (regs->ARM_lr & 1) { |
410 |
++ regs->ARM_cpsr |= PSR_T_BIT; |
411 |
++ regs->ARM_pc &= ~0x1U; |
412 |
++ } else |
413 |
++ regs->ARM_cpsr &= ~PSR_T_BIT; |
414 |
++#endif |
415 |
+ return; |
416 |
+ } |
417 |
+ if (pc == 0xffff0fc0UL) { |
418 |
@@ -3901,6 +3874,13 @@ index daafcf1..8205ed6 100644 |
419 |
+ */ |
420 |
+ regs->ARM_r0 = current_thread_info()->tp_value[0]; |
421 |
+ regs->ARM_pc = regs->ARM_lr; |
422 |
++#ifdef CONFIG_ARM_THUMB |
423 |
++ if (regs->ARM_lr & 1) { |
424 |
++ regs->ARM_cpsr |= PSR_T_BIT; |
425 |
++ regs->ARM_pc &= ~0x1U; |
426 |
++ } else |
427 |
++ regs->ARM_cpsr &= ~PSR_T_BIT; |
428 |
++#endif |
429 |
+ return; |
430 |
+ } |
431 |
+ } |
432 |
@@ -4655,6 +4635,18 @@ index a5bc92d..0bb4730 100644 |
433 |
omap_sram_size - omap_sram_skip); |
434 |
+ pax_close_kernel(); |
435 |
} |
436 |
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig |
437 |
+index 8cc6228..6d6e4f8 100644 |
438 |
+--- a/arch/arm64/Kconfig |
439 |
++++ b/arch/arm64/Kconfig |
440 |
+@@ -70,6 +70,7 @@ config ARM64 |
441 |
+ select HAVE_FTRACE_MCOUNT_RECORD |
442 |
+ select HAVE_FUNCTION_TRACER |
443 |
+ select HAVE_FUNCTION_GRAPH_TRACER |
444 |
++ select HAVE_GCC_PLUGINS |
445 |
+ select HAVE_GENERIC_DMA_COHERENT |
446 |
+ select HAVE_HW_BREAKPOINT if PERF_EVENTS |
447 |
+ select HAVE_IRQ_TIME_ACCOUNTING |
448 |
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug |
449 |
index e13c4bf..3feaea7 100644 |
450 |
--- a/arch/arm64/Kconfig.debug |
451 |
@@ -5602,10 +5594,18 @@ index 4efe96a..60e8699 100644 |
452 |
#define SMP_CACHE_BYTES L1_CACHE_BYTES |
453 |
|
454 |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig |
455 |
-index d3da79d..e607104 100644 |
456 |
+index d3da79d..e317c97 100644 |
457 |
--- a/arch/mips/Kconfig |
458 |
+++ b/arch/mips/Kconfig |
459 |
-@@ -2656,6 +2656,7 @@ source "kernel/Kconfig.preempt" |
460 |
+@@ -49,6 +49,7 @@ config MIPS |
461 |
+ select GENERIC_CMOS_UPDATE |
462 |
+ select HAVE_MOD_ARCH_SPECIFIC |
463 |
+ select VIRT_TO_BUS |
464 |
++ select HAVE_GCC_PLUGINS |
465 |
+ select MODULES_USE_ELF_REL if MODULES |
466 |
+ select MODULES_USE_ELF_RELA if MODULES && 64BIT |
467 |
+ select CLONE_BACKWARDS |
468 |
+@@ -2656,6 +2657,7 @@ source "kernel/Kconfig.preempt" |
469 |
config KEXEC |
470 |
bool "Kexec system call" |
471 |
select KEXEC_CORE |
472 |
@@ -7607,10 +7607,18 @@ index f906444..0bb73ae 100644 |
473 |
/* |
474 |
* If for any reason at all we couldn't handle the fault, make |
475 |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig |
476 |
-index 9faa18c..6061610 100644 |
477 |
+index 9faa18c..b24277a 100644 |
478 |
--- a/arch/powerpc/Kconfig |
479 |
+++ b/arch/powerpc/Kconfig |
480 |
-@@ -419,6 +419,7 @@ config KEXEC |
481 |
+@@ -143,6 +143,7 @@ config PPC |
482 |
+ select ARCH_USE_BUILTIN_BSWAP |
483 |
+ select OLD_SIGSUSPEND |
484 |
+ select OLD_SIGACTION if PPC32 |
485 |
++ select HAVE_GCC_PLUGINS |
486 |
+ select HAVE_DEBUG_STACKOVERFLOW |
487 |
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK |
488 |
+ select ARCH_USE_CMPXCHG_LOCKREF if PPC64 |
489 |
+@@ -419,6 +420,7 @@ config KEXEC |
490 |
bool "kexec system call" |
491 |
depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) || PPC_BOOK3E |
492 |
select KEXEC_CORE |
493 |
@@ -7619,7 +7627,7 @@ index 9faa18c..6061610 100644 |
494 |
kexec is a system call that implements the ability to shutdown your |
495 |
current kernel, and to start another kernel. It is like a reboot |
496 |
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h |
497 |
-index 55f106e..70cc82a 100644 |
498 |
+index 55f106e..5968afb 100644 |
499 |
--- a/arch/powerpc/include/asm/atomic.h |
500 |
+++ b/arch/powerpc/include/asm/atomic.h |
501 |
@@ -12,6 +12,11 @@ |
502 |
@@ -7886,19 +7894,7 @@ index 55f106e..70cc82a 100644 |
503 |
PPC_ATOMIC_EXIT_BARRIER |
504 |
" subf %0,%2,%0 \n\ |
505 |
2:" |
506 |
-@@ -252,6 +299,11 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) |
507 |
- } |
508 |
- #define atomic_dec_if_positive atomic_dec_if_positive |
509 |
- |
510 |
-+#define smp_mb__before_atomic_dec() smp_mb() |
511 |
-+#define smp_mb__after_atomic_dec() smp_mb() |
512 |
-+#define smp_mb__before_atomic_inc() smp_mb() |
513 |
-+#define smp_mb__after_atomic_inc() smp_mb() |
514 |
-+ |
515 |
- #ifdef __powerpc64__ |
516 |
- |
517 |
- #define ATOMIC64_INIT(i) { (i) } |
518 |
-@@ -265,37 +317,60 @@ static __inline__ long atomic64_read(const atomic64_t *v) |
519 |
+@@ -265,37 +312,60 @@ static __inline__ long atomic64_read(const atomic64_t *v) |
520 |
return t; |
521 |
} |
522 |
|
523 |
@@ -7963,7 +7959,7 @@ index 55f106e..70cc82a 100644 |
524 |
PPC_ATOMIC_EXIT_BARRIER \ |
525 |
: "=&r" (t) \ |
526 |
: "r" (a), "r" (&v->counter) \ |
527 |
-@@ -304,6 +379,9 @@ static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \ |
528 |
+@@ -304,6 +374,9 @@ static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \ |
529 |
return t; \ |
530 |
} |
531 |
|
532 |
@@ -7973,7 +7969,7 @@ index 55f106e..70cc82a 100644 |
533 |
#define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op) |
534 |
|
535 |
ATOMIC64_OPS(add, add) |
536 |
-@@ -314,40 +392,33 @@ ATOMIC64_OP(xor, xor) |
537 |
+@@ -314,40 +387,33 @@ ATOMIC64_OP(xor, xor) |
538 |
|
539 |
#undef ATOMIC64_OPS |
540 |
#undef ATOMIC64_OP_RETURN |
541 |
@@ -8033,7 +8029,7 @@ index 55f106e..70cc82a 100644 |
542 |
} |
543 |
|
544 |
/* |
545 |
-@@ -360,36 +431,18 @@ static __inline__ long atomic64_inc_return(atomic64_t *v) |
546 |
+@@ -360,36 +426,18 @@ static __inline__ long atomic64_inc_return(atomic64_t *v) |
547 |
*/ |
548 |
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) |
549 |
|
550 |
@@ -8081,7 +8077,7 @@ index 55f106e..70cc82a 100644 |
551 |
} |
552 |
|
553 |
#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) |
554 |
-@@ -422,6 +475,16 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) |
555 |
+@@ -422,6 +470,16 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) |
556 |
#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) |
557 |
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
558 |
|
559 |
@@ -8090,7 +8086,7 @@ index 55f106e..70cc82a 100644 |
560 |
+ return cmpxchg(&(v->counter), old, new); |
561 |
+} |
562 |
+ |
563 |
-+static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new) |
564 |
++static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new) |
565 |
+{ |
566 |
+ return xchg(&(v->counter), new); |
567 |
+} |
568 |
@@ -8098,7 +8094,7 @@ index 55f106e..70cc82a 100644 |
569 |
/** |
570 |
* atomic64_add_unless - add unless the number is a given value |
571 |
* @v: pointer of type atomic64_t |
572 |
-@@ -437,13 +500,29 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
573 |
+@@ -437,13 +495,29 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
574 |
|
575 |
__asm__ __volatile__ ( |
576 |
PPC_ATOMIC_ENTRY_BARRIER |
577 |
@@ -8698,17 +8694,17 @@ index b7c20f0..4adc0f1 100644 |
578 |
|
579 |
static inline unsigned long clear_user(void __user *addr, unsigned long size) |
580 |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile |
581 |
-index 794f22a..f8de42b 100644 |
582 |
+index 794f22a..9a76447 100644 |
583 |
--- a/arch/powerpc/kernel/Makefile |
584 |
+++ b/arch/powerpc/kernel/Makefile |
585 |
@@ -14,6 +14,11 @@ CFLAGS_prom_init.o += -fPIC |
586 |
CFLAGS_btext.o += -fPIC |
587 |
endif |
588 |
|
589 |
-+CFLAGS_REMOVE_cputable.o = $(LATENT_ENTROPY_PLUGIN_CFLAGS) |
590 |
-+CFLAGS_REMOVE_prom_init.o = $(LATENT_ENTROPY_PLUGIN_CFLAGS) |
591 |
-+CFLAGS_REMOVE_btext.o = $(LATENT_ENTROPY_PLUGIN_CFLAGS) |
592 |
-+CFLAGS_REMOVE_prom.o = $(LATENT_ENTROPY_PLUGIN_CFLAGS) |
593 |
++CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) |
594 |
++CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) |
595 |
++CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) |
596 |
++CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) |
597 |
+ |
598 |
ifdef CONFIG_FUNCTION_TRACER |
599 |
# Do not trace early boot code |
600 |
@@ -9678,6 +9674,18 @@ index 6777177..d44b592 100644 |
601 |
info.high_limit = TASK_SIZE; |
602 |
addr = vm_unmapped_area(&info); |
603 |
} |
604 |
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig |
605 |
+index 57ffaf2..4d1fe9a 100644 |
606 |
+--- a/arch/sparc/Kconfig |
607 |
++++ b/arch/sparc/Kconfig |
608 |
+@@ -39,6 +39,7 @@ config SPARC |
609 |
+ select GENERIC_STRNCPY_FROM_USER |
610 |
+ select GENERIC_STRNLEN_USER |
611 |
+ select MODULES_USE_ELF_RELA |
612 |
++ select HAVE_GCC_PLUGINS |
613 |
+ select ODD_RT_SIGACTION |
614 |
+ select OLD_SIGSUSPEND |
615 |
+ select ARCH_HAS_SG_CHAIN |
616 |
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h |
617 |
index f2fbf9e..fea461e 100644 |
618 |
--- a/arch/sparc/include/asm/atomic_64.h |
619 |
@@ -12221,16 +12229,14 @@ index c034dc3..cf1cc96 100644 |
620 |
|
621 |
/* |
622 |
diff --git a/arch/um/Makefile b/arch/um/Makefile |
623 |
-index e3abe6f..ae224ef 100644 |
624 |
+index e3abe6f..33a363c 100644 |
625 |
--- a/arch/um/Makefile |
626 |
+++ b/arch/um/Makefile |
627 |
-@@ -73,6 +73,10 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ |
628 |
+@@ -73,6 +73,8 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ |
629 |
-D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \ |
630 |
-idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__ |
631 |
|
632 |
-+ifdef CONSTIFY_PLUGIN |
633 |
-+USER_CFLAGS += -fplugin-arg-constify_plugin-no-constify |
634 |
-+endif |
635 |
++USER_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(USER_CFLAGS)) |
636 |
+ |
637 |
#This will adjust *FLAGS accordingly to the platform. |
638 |
include $(ARCH_DIR)/Makefile-os-$(OS) |
639 |
@@ -12338,7 +12344,7 @@ index ad8f795..2c7eec6 100644 |
640 |
/* |
641 |
* Memory returned by kmalloc() may be used for DMA, so we must make |
642 |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
643 |
-index 3bf45a0..7b04039 100644 |
644 |
+index 3bf45a0..25ca7da 100644 |
645 |
--- a/arch/x86/Kconfig |
646 |
+++ b/arch/x86/Kconfig |
647 |
@@ -38,14 +38,13 @@ config X86 |
648 |
@@ -12366,7 +12372,15 @@ index 3bf45a0..7b04039 100644 |
649 |
select HAVE_CMPXCHG_DOUBLE |
650 |
select HAVE_CMPXCHG_LOCAL |
651 |
select HAVE_CONTEXT_TRACKING if X86_64 |
652 |
-@@ -290,7 +289,7 @@ config X86_64_SMP |
653 |
+@@ -109,6 +108,7 @@ config X86 |
654 |
+ select HAVE_FUNCTION_GRAPH_FP_TEST |
655 |
+ select HAVE_FUNCTION_GRAPH_TRACER |
656 |
+ select HAVE_FUNCTION_TRACER |
657 |
++ select HAVE_GCC_PLUGINS |
658 |
+ select HAVE_GENERIC_DMA_COHERENT if X86_32 |
659 |
+ select HAVE_HW_BREAKPOINT |
660 |
+ select HAVE_IDE |
661 |
+@@ -290,7 +290,7 @@ config X86_64_SMP |
662 |
|
663 |
config X86_32_LAZY_GS |
664 |
def_bool y |
665 |
@@ -12375,7 +12389,7 @@ index 3bf45a0..7b04039 100644 |
666 |
|
667 |
config ARCH_HWEIGHT_CFLAGS |
668 |
string |
669 |
-@@ -674,6 +673,7 @@ config SCHED_OMIT_FRAME_POINTER |
670 |
+@@ -674,6 +674,7 @@ config SCHED_OMIT_FRAME_POINTER |
671 |
|
672 |
menuconfig HYPERVISOR_GUEST |
673 |
bool "Linux guest support" |
674 |
@@ -12383,7 +12397,7 @@ index 3bf45a0..7b04039 100644 |
675 |
---help--- |
676 |
Say Y here to enable options for running Linux under various hyper- |
677 |
visors. This option enables basic hypervisor detection and platform |
678 |
-@@ -1073,6 +1073,7 @@ config VM86 |
679 |
+@@ -1073,6 +1074,7 @@ config VM86 |
680 |
|
681 |
config X86_16BIT |
682 |
bool "Enable support for 16-bit segments" if EXPERT |
683 |
@@ -12391,7 +12405,7 @@ index 3bf45a0..7b04039 100644 |
684 |
default y |
685 |
depends on MODIFY_LDT_SYSCALL |
686 |
---help--- |
687 |
-@@ -1227,6 +1228,7 @@ choice |
688 |
+@@ -1227,6 +1229,7 @@ choice |
689 |
|
690 |
config NOHIGHMEM |
691 |
bool "off" |
692 |
@@ -12399,7 +12413,7 @@ index 3bf45a0..7b04039 100644 |
693 |
---help--- |
694 |
Linux can use up to 64 Gigabytes of physical memory on x86 systems. |
695 |
However, the address space of 32-bit x86 processors is only 4 |
696 |
-@@ -1263,6 +1265,7 @@ config NOHIGHMEM |
697 |
+@@ -1263,6 +1266,7 @@ config NOHIGHMEM |
698 |
|
699 |
config HIGHMEM4G |
700 |
bool "4GB" |
701 |
@@ -12407,7 +12421,7 @@ index 3bf45a0..7b04039 100644 |
702 |
---help--- |
703 |
Select this if you have a 32-bit processor and between 1 and 4 |
704 |
gigabytes of physical RAM. |
705 |
-@@ -1315,7 +1318,7 @@ config PAGE_OFFSET |
706 |
+@@ -1315,7 +1319,7 @@ config PAGE_OFFSET |
707 |
hex |
708 |
default 0xB0000000 if VMSPLIT_3G_OPT |
709 |
default 0x80000000 if VMSPLIT_2G |
710 |
@@ -12416,7 +12430,7 @@ index 3bf45a0..7b04039 100644 |
711 |
default 0x40000000 if VMSPLIT_1G |
712 |
default 0xC0000000 |
713 |
depends on X86_32 |
714 |
-@@ -1336,7 +1339,6 @@ config X86_PAE |
715 |
+@@ -1336,7 +1340,6 @@ config X86_PAE |
716 |
|
717 |
config ARCH_PHYS_ADDR_T_64BIT |
718 |
def_bool y |
719 |
@@ -12424,7 +12438,7 @@ index 3bf45a0..7b04039 100644 |
720 |
|
721 |
config ARCH_DMA_ADDR_T_64BIT |
722 |
def_bool y |
723 |
-@@ -1467,7 +1469,7 @@ config ARCH_PROC_KCORE_TEXT |
724 |
+@@ -1467,7 +1470,7 @@ config ARCH_PROC_KCORE_TEXT |
725 |
|
726 |
config ILLEGAL_POINTER_VALUE |
727 |
hex |
728 |
@@ -12433,7 +12447,7 @@ index 3bf45a0..7b04039 100644 |
729 |
default 0xdead000000000000 if X86_64 |
730 |
|
731 |
source "mm/Kconfig" |
732 |
-@@ -1776,6 +1778,7 @@ source kernel/Kconfig.hz |
733 |
+@@ -1776,6 +1779,7 @@ source kernel/Kconfig.hz |
734 |
config KEXEC |
735 |
bool "kexec system call" |
736 |
select KEXEC_CORE |
737 |
@@ -12441,7 +12455,7 @@ index 3bf45a0..7b04039 100644 |
738 |
---help--- |
739 |
kexec is a system call that implements the ability to shutdown your |
740 |
current kernel, and to start another kernel. It is like a reboot |
741 |
-@@ -1958,7 +1961,9 @@ config X86_NEED_RELOCS |
742 |
+@@ -1958,7 +1962,9 @@ config X86_NEED_RELOCS |
743 |
|
744 |
config PHYSICAL_ALIGN |
745 |
hex "Alignment value to which kernel should be aligned" |
746 |
@@ -12452,7 +12466,7 @@ index 3bf45a0..7b04039 100644 |
747 |
range 0x2000 0x1000000 if X86_32 |
748 |
range 0x200000 0x1000000 if X86_64 |
749 |
---help--- |
750 |
-@@ -2041,6 +2046,7 @@ config COMPAT_VDSO |
751 |
+@@ -2041,6 +2047,7 @@ config COMPAT_VDSO |
752 |
def_bool n |
753 |
prompt "Disable the 32-bit vDSO (needed for glibc 2.3.3)" |
754 |
depends on X86_32 || IA32_EMULATION |
755 |
@@ -12460,7 +12474,7 @@ index 3bf45a0..7b04039 100644 |
756 |
---help--- |
757 |
Certain buggy versions of glibc will crash if they are |
758 |
presented with a 32-bit vDSO that is not mapped at the address |
759 |
-@@ -2081,15 +2087,6 @@ choice |
760 |
+@@ -2081,15 +2088,6 @@ choice |
761 |
|
762 |
If unsure, select "Emulate". |
763 |
|
764 |
@@ -12476,7 +12490,7 @@ index 3bf45a0..7b04039 100644 |
765 |
config LEGACY_VSYSCALL_EMULATE |
766 |
bool "Emulate" |
767 |
help |
768 |
-@@ -2170,6 +2167,22 @@ config MODIFY_LDT_SYSCALL |
769 |
+@@ -2170,6 +2168,22 @@ config MODIFY_LDT_SYSCALL |
770 |
|
771 |
Saying 'N' here may make sense for embedded or server kernels. |
772 |
|
773 |
@@ -12610,20 +12624,6 @@ index 4086abc..52a0a9b 100644 |
774 |
+*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils. |
775 |
+*** Please upgrade your binutils to 2.18 or newer |
776 |
+endef |
777 |
-diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile |
778 |
-index bbe1a62..ec6a3ec 100644 |
779 |
---- a/arch/x86/boot/Makefile |
780 |
-+++ b/arch/x86/boot/Makefile |
781 |
-@@ -58,6 +58,9 @@ clean-files += cpustr.h |
782 |
- # --------------------------------------------------------------------------- |
783 |
- |
784 |
- KBUILD_CFLAGS := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP |
785 |
-+ifdef CONSTIFY_PLUGIN |
786 |
-+KBUILD_CFLAGS += -fplugin-arg-constify_plugin-no-constify |
787 |
-+endif |
788 |
- KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ |
789 |
- GCOV_PROFILE := n |
790 |
- UBSAN_SANITIZE := n |
791 |
diff --git a/arch/x86/boot/bitops.h b/arch/x86/boot/bitops.h |
792 |
index 878e4b9..20537ab 100644 |
793 |
--- a/arch/x86/boot/bitops.h |
794 |
@@ -12660,17 +12660,13 @@ index 9011a88..06aa820 100644 |
795 |
} |
796 |
|
797 |
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile |
798 |
-index f9ce75d..0b1600d 100644 |
799 |
+index f9ce75d..245ea76 100644 |
800 |
--- a/arch/x86/boot/compressed/Makefile |
801 |
+++ b/arch/x86/boot/compressed/Makefile |
802 |
-@@ -30,6 +30,26 @@ KBUILD_CFLAGS += $(cflags-y) |
803 |
- KBUILD_CFLAGS += -mno-mmx -mno-sse |
804 |
+@@ -31,6 +31,23 @@ KBUILD_CFLAGS += -mno-mmx -mno-sse |
805 |
KBUILD_CFLAGS += $(call cc-option,-ffreestanding) |
806 |
KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) |
807 |
-+ifdef CONSTIFY_PLUGIN |
808 |
-+KBUILD_CFLAGS += -fplugin-arg-constify_plugin-no-constify |
809 |
-+endif |
810 |
-+ |
811 |
+ |
812 |
+ifdef CONFIG_DEBUG_INFO |
813 |
+ifdef CONFIG_DEBUG_INFO_SPLIT |
814 |
+KBUILD_CFLAGS += $(call cc-option, -gsplit-dwarf, -g) |
815 |
@@ -12687,9 +12683,10 @@ index f9ce75d..0b1600d 100644 |
816 |
+KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) \ |
817 |
+ $(call cc-option,-fno-var-tracking) |
818 |
+endif |
819 |
- |
820 |
++ |
821 |
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ |
822 |
GCOV_PROFILE := n |
823 |
+ UBSAN_SANITIZE :=n |
824 |
diff --git a/arch/x86/boot/compressed/efi_stub_32.S b/arch/x86/boot/compressed/efi_stub_32.S |
825 |
index a53440e..c3dbf1e 100644 |
826 |
--- a/arch/x86/boot/compressed/efi_stub_32.S |
827 |
@@ -15756,7 +15753,7 @@ index e32206e0..809adae 100644 |
828 |
|
829 |
.macro REMOVE_PT_GPREGS_FROM_STACK addskip=0 |
830 |
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c |
831 |
-index 1a4477c..95199ec4 100644 |
832 |
+index 1a4477c..7061819 100644 |
833 |
--- a/arch/x86/entry/common.c |
834 |
+++ b/arch/x86/entry/common.c |
835 |
@@ -32,9 +32,7 @@ |
836 |
@@ -15869,7 +15866,7 @@ index 1a4477c..95199ec4 100644 |
837 |
+ [param4] "m" (regs->si), |
838 |
+ [param5] "m" (regs->di), |
839 |
+ [param6] "m" (regs->bp) |
840 |
-+ : "di", "si", "dx", "cx", "r8", "r9", "memory"); |
841 |
++ : "ax", "di", "si", "dx", "cx", "r8", "r9", "r10", "r11", "memory"); |
842 |
+#else |
843 |
+ asm volatile("pushl %[param6]\n\t" |
844 |
+ "pushl %[param5]\n\t" |
845 |
@@ -22879,7 +22876,7 @@ index 82c34ee..940fa40 100644 |
846 |
unsigned, unsigned, unsigned); |
847 |
|
848 |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h |
849 |
-index c7b5510..2ab8977 100644 |
850 |
+index c7b5510..f6d5ca4 100644 |
851 |
--- a/arch/x86/include/asm/thread_info.h |
852 |
+++ b/arch/x86/include/asm/thread_info.h |
853 |
@@ -39,7 +39,7 @@ |
854 |
@@ -22961,7 +22958,7 @@ index c7b5510..2ab8977 100644 |
855 |
} |
856 |
|
857 |
static inline unsigned long current_stack_pointer(void) |
858 |
-@@ -179,14 +182,9 @@ static inline unsigned long current_stack_pointer(void) |
859 |
+@@ -179,41 +182,9 @@ static inline unsigned long current_stack_pointer(void) |
860 |
|
861 |
#else /* !__ASSEMBLY__ */ |
862 |
|
863 |
@@ -22973,11 +22970,38 @@ index c7b5510..2ab8977 100644 |
864 |
#define GET_THREAD_INFO(reg) \ |
865 |
- _ASM_MOV PER_CPU_VAR(cpu_current_top_of_stack),reg ; \ |
866 |
- _ASM_SUB $(THREAD_SIZE),reg ; |
867 |
+- |
868 |
+-/* |
869 |
+- * ASM operand which evaluates to a 'thread_info' address of |
870 |
+- * the current task, if it is known that "reg" is exactly "off" |
871 |
+- * bytes below the top of the stack currently. |
872 |
+- * |
873 |
+- * ( The kernel stack's size is known at build time, it is usually |
874 |
+- * 2 or 4 pages, and the bottom of the kernel stack contains |
875 |
+- * the thread_info structure. So to access the thread_info very |
876 |
+- * quickly from assembly code we can calculate down from the |
877 |
+- * top of the kernel stack to the bottom, using constant, |
878 |
+- * build-time calculations only. ) |
879 |
+- * |
880 |
+- * For example, to fetch the current thread_info->flags value into %eax |
881 |
+- * on x86-64 defconfig kernels, in syscall entry code where RSP is |
882 |
+- * currently at exactly SIZEOF_PTREGS bytes away from the top of the |
883 |
+- * stack: |
884 |
+- * |
885 |
+- * mov ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS), %eax |
886 |
+- * |
887 |
+- * will translate to: |
888 |
+- * |
889 |
+- * 8b 84 24 b8 c0 ff ff mov -0x3f48(%rsp), %eax |
890 |
+- * |
891 |
+- * which is below the current RSP by almost 16K. |
892 |
+- */ |
893 |
+-#define ASM_THREAD_INFO(field, reg, off) ((field)+(off)-THREAD_SIZE)(reg) |
894 |
+ _ASM_MOV PER_CPU_VAR(current_tinfo),reg ; |
895 |
|
896 |
- /* |
897 |
- * ASM operand which evaluates to a 'thread_info' address of |
898 |
-@@ -279,5 +277,12 @@ static inline bool is_ia32_task(void) |
899 |
+ #endif |
900 |
+ |
901 |
+@@ -279,5 +250,12 @@ static inline bool is_ia32_task(void) |
902 |
extern void arch_task_cache_init(void); |
903 |
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); |
904 |
extern void arch_release_task_struct(struct task_struct *tsk); |
905 |
@@ -25722,7 +25746,7 @@ index 2cad71d..5f1baf2 100644 |
906 |
__bts_event_stop(event); |
907 |
|
908 |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_cqm.c b/arch/x86/kernel/cpu/perf_event_intel_cqm.c |
909 |
-index a316ca9..99344f4 100644 |
910 |
+index a316ca9..07e219e 100644 |
911 |
--- a/arch/x86/kernel/cpu/perf_event_intel_cqm.c |
912 |
+++ b/arch/x86/kernel/cpu/perf_event_intel_cqm.c |
913 |
@@ -1364,7 +1364,9 @@ static int __init intel_cqm_init(void) |
914 |
@@ -25731,7 +25755,7 @@ index a316ca9..99344f4 100644 |
915 |
|
916 |
- event_attr_intel_cqm_llc_scale.event_str = str; |
917 |
+ pax_open_kernel(); |
918 |
-+ *(const char **)&event_attr_intel_cqm_llc_scale.event_str = str; |
919 |
++ const_cast(event_attr_intel_cqm_llc_scale.event_str) = str; |
920 |
+ pax_close_kernel(); |
921 |
|
922 |
ret = intel_cqm_setup_rmid_cache(); |
923 |
@@ -25798,7 +25822,7 @@ index 653f88d..11b6b78 100644 |
924 |
if (!insn.opcode.got) |
925 |
return X86_BR_ABORT; |
926 |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c |
927 |
-index c0bbd10..727ae15e 100644 |
928 |
+index c0bbd10..53a5dc6 100644 |
929 |
--- a/arch/x86/kernel/cpu/perf_event_intel_pt.c |
930 |
+++ b/arch/x86/kernel/cpu/perf_event_intel_pt.c |
931 |
@@ -133,14 +133,10 @@ static const struct attribute_group *pt_attr_groups[] = { |
932 |
@@ -25839,22 +25863,22 @@ index c0bbd10..727ae15e 100644 |
933 |
+ struct dev_ext_attribute *de_attr = &de_attrs[i]; |
934 |
|
935 |
- de_attr->attr.attr.name = pt_caps[i].name; |
936 |
-+ *(const char **)&de_attr->attr.attr.name = pt_caps[i].name; |
937 |
++ const_cast(de_attr->attr.attr.name) = pt_caps[i].name; |
938 |
|
939 |
sysfs_attr_init(&de_attr->attr.attr); |
940 |
|
941 |
- de_attr->attr.attr.mode = S_IRUGO; |
942 |
- de_attr->attr.show = pt_cap_show; |
943 |
- de_attr->var = (void *)i; |
944 |
-+ *(umode_t *)&de_attr->attr.attr.mode = S_IRUGO; |
945 |
-+ *(void **)&de_attr->attr.show = pt_cap_show; |
946 |
-+ *(void **)&de_attr->var = (void *)i; |
947 |
++ const_cast(de_attr->attr.attr.mode) = S_IRUGO; |
948 |
++ const_cast(de_attr->attr.show) = pt_cap_show; |
949 |
++ const_cast(de_attr->var) = (void *)i; |
950 |
|
951 |
attrs[i] = &de_attr->attr.attr; |
952 |
} |
953 |
|
954 |
- pt_cap_group.attrs = attrs; |
955 |
-+ *(struct attribute ***)&pt_cap_group.attrs = attrs; |
956 |
++ const_cast(pt_cap_group.attrs) = attrs; |
957 |
+ pax_close_kernel(); |
958 |
|
959 |
return 0; |
960 |
@@ -27813,7 +27837,7 @@ index 64341aa..b1e6632 100644 |
961 |
+EXPORT_SYMBOL(cpu_pgd); |
962 |
+#endif |
963 |
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c |
964 |
-index be22f5a..c5d0e1f 100644 |
965 |
+index be22f5a..a04fa14 100644 |
966 |
--- a/arch/x86/kernel/i8259.c |
967 |
+++ b/arch/x86/kernel/i8259.c |
968 |
@@ -110,7 +110,7 @@ static int i8259A_irq_pending(unsigned int irq) |
969 |
@@ -27845,10 +27869,10 @@ index be22f5a..c5d0e1f 100644 |
970 |
* when acking. |
971 |
*/ |
972 |
- i8259A_chip.irq_mask_ack = disable_8259A_irq; |
973 |
-+ *(void **)&i8259A_chip.irq_mask_ack = disable_8259A_irq; |
974 |
++ const_cast(i8259A_chip.irq_mask_ack) = disable_8259A_irq; |
975 |
else |
976 |
- i8259A_chip.irq_mask_ack = mask_and_ack_8259A; |
977 |
-+ *(void **)&i8259A_chip.irq_mask_ack = mask_and_ack_8259A; |
978 |
++ const_cast(i8259A_chip.irq_mask_ack) = mask_and_ack_8259A; |
979 |
+ pax_close_kernel(); |
980 |
|
981 |
udelay(100); /* wait for 8259A to initialize */ |
982 |
@@ -29041,7 +29065,7 @@ index 6d9582e..f746287 100644 |
983 |
return; |
984 |
} |
985 |
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c |
986 |
-index 33ee3e0..ca43dee 100644 |
987 |
+index 33ee3e0..6d23e5c 100644 |
988 |
--- a/arch/x86/kernel/paravirt-spinlocks.c |
989 |
+++ b/arch/x86/kernel/paravirt-spinlocks.c |
990 |
@@ -23,16 +23,32 @@ bool pv_is_native_spin_unlock(void) |
991 |
@@ -29058,7 +29082,7 @@ index 33ee3e0..ca43dee 100644 |
992 |
+static void native_kick(int cpu) |
993 |
+{ |
994 |
+} |
995 |
-+//#else /* !CONFIG_QUEUED_SPINLOCKS */ |
996 |
++#else /* !CONFIG_QUEUED_SPINLOCKS */ |
997 |
+static void native_unlock_kick(struct arch_spinlock *lock, __ticket_t ticket) |
998 |
+{ |
999 |
+} |
1000 |
@@ -37439,7 +37463,7 @@ index 4e664bd..2beeaa2 100644 |
1001 |
return NULL; |
1002 |
|
1003 |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c |
1004 |
-index 1d2e639..d7f0e67 100644 |
1005 |
+index 1d2e639..6473b8a 100644 |
1006 |
--- a/arch/x86/oprofile/nmi_int.c |
1007 |
+++ b/arch/x86/oprofile/nmi_int.c |
1008 |
@@ -23,6 +23,7 @@ |
1009 |
@@ -37467,14 +37491,14 @@ index 1d2e639..d7f0e67 100644 |
1010 |
- model->num_virt_counters = model->num_counters; |
1011 |
+ if (!model->num_virt_counters) { |
1012 |
+ pax_open_kernel(); |
1013 |
-+ *(unsigned int *)&model->num_virt_counters = model->num_counters; |
1014 |
++ const_cast(model->num_virt_counters) = model->num_counters; |
1015 |
+ pax_close_kernel(); |
1016 |
+ } |
1017 |
|
1018 |
mux_init(ops); |
1019 |
|
1020 |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c |
1021 |
-index 50d86c0..7985318 100644 |
1022 |
+index 50d86c0..b0b9ae0 100644 |
1023 |
--- a/arch/x86/oprofile/op_model_amd.c |
1024 |
+++ b/arch/x86/oprofile/op_model_amd.c |
1025 |
@@ -519,9 +519,11 @@ static int op_amd_init(struct oprofile_operations *ops) |
1026 |
@@ -37485,15 +37509,15 @@ index 50d86c0..7985318 100644 |
1027 |
- op_amd_spec.num_controls = num_counters; |
1028 |
- op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); |
1029 |
+ pax_open_kernel(); |
1030 |
-+ *(unsigned int *)&op_amd_spec.num_counters = num_counters; |
1031 |
-+ *(unsigned int *)&op_amd_spec.num_controls = num_counters; |
1032 |
-+ *(unsigned int *)&op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); |
1033 |
++ const_cast(op_amd_spec.num_counters) = num_counters; |
1034 |
++ const_cast(op_amd_spec.num_controls) = num_counters; |
1035 |
++ const_cast(op_amd_spec.num_virt_counters) = max(num_counters, NUM_VIRT_COUNTERS); |
1036 |
+ pax_close_kernel(); |
1037 |
|
1038 |
return 0; |
1039 |
} |
1040 |
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c |
1041 |
-index d90528e..0127e2b 100644 |
1042 |
+index d90528e..a44aa09 100644 |
1043 |
--- a/arch/x86/oprofile/op_model_ppro.c |
1044 |
+++ b/arch/x86/oprofile/op_model_ppro.c |
1045 |
@@ -19,6 +19,7 @@ |
1046 |
@@ -37511,8 +37535,8 @@ index d90528e..0127e2b 100644 |
1047 |
- op_arch_perfmon_spec.num_counters = num_counters; |
1048 |
- op_arch_perfmon_spec.num_controls = num_counters; |
1049 |
+ pax_open_kernel(); |
1050 |
-+ *(unsigned int *)&op_arch_perfmon_spec.num_counters = num_counters; |
1051 |
-+ *(unsigned int *)&op_arch_perfmon_spec.num_controls = num_counters; |
1052 |
++ const_cast(op_arch_perfmon_spec.num_counters) = num_counters; |
1053 |
++ const_cast(op_arch_perfmon_spec.num_controls) = num_counters; |
1054 |
+ pax_close_kernel(); |
1055 |
} |
1056 |
|
1057 |
@@ -37808,7 +37832,7 @@ index 9770e55..76067ec 100644 |
1058 |
} |
1059 |
EXPORT_SYMBOL(pcibios_set_irq_routing); |
1060 |
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c |
1061 |
-index d57e480..20eb97a 100644 |
1062 |
+index d57e480..fc4db30 100644 |
1063 |
--- a/arch/x86/pci/vmd.c |
1064 |
+++ b/arch/x86/pci/vmd.c |
1065 |
@@ -374,7 +374,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd) |
1066 |
@@ -37816,7 +37840,7 @@ index d57e480..20eb97a 100644 |
1067 |
do { \ |
1068 |
if (source->fn) \ |
1069 |
- dest->fn = vmd_##fn; \ |
1070 |
-+ *(void **)&dest->fn = vmd_##fn; \ |
1071 |
++ const_cast(dest->fn) = vmd_##fn; \ |
1072 |
} while (0) |
1073 |
|
1074 |
static void vmd_setup_dma_ops(struct vmd_dev *vmd) |
1075 |
@@ -38238,20 +38262,6 @@ index 0b7a63d..dff2199 100644 |
1076 |
trampoline_pgd[511] = init_level4_pgt[511].pgd; |
1077 |
#endif |
1078 |
} |
1079 |
-diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile |
1080 |
-index 3e75fcf..4cfefb8 100644 |
1081 |
---- a/arch/x86/realmode/rm/Makefile |
1082 |
-+++ b/arch/x86/realmode/rm/Makefile |
1083 |
-@@ -68,6 +68,9 @@ $(obj)/realmode.relocs: $(obj)/realmode.elf FORCE |
1084 |
- |
1085 |
- KBUILD_CFLAGS := $(LINUXINCLUDE) $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \ |
1086 |
- -I$(srctree)/arch/x86/boot |
1087 |
-+ifdef CONSTIFY_PLUGIN |
1088 |
-+KBUILD_CFLAGS += -fplugin-arg-constify_plugin-no-constify |
1089 |
-+endif |
1090 |
- KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ |
1091 |
- GCOV_PROFILE := n |
1092 |
- UBSAN_SANITIZE := n |
1093 |
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S |
1094 |
index a28221d..93c40f1 100644 |
1095 |
--- a/arch/x86/realmode/rm/header.S |
1096 |
@@ -39659,7 +39669,7 @@ index b719ab3..371e2a6 100644 |
1097 |
enum acpi_battery_files { |
1098 |
info_tag = 0, |
1099 |
diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c |
1100 |
-index a83e3c6..c3d617f 100644 |
1101 |
+index a83e3c6..7f4a90b 100644 |
1102 |
--- a/drivers/acpi/bgrt.c |
1103 |
+++ b/drivers/acpi/bgrt.c |
1104 |
@@ -86,8 +86,10 @@ static int __init bgrt_init(void) |
1105 |
@@ -39669,8 +39679,8 @@ index a83e3c6..c3d617f 100644 |
1106 |
- bin_attr_image.private = bgrt_image; |
1107 |
- bin_attr_image.size = bgrt_image_size; |
1108 |
+ pax_open_kernel(); |
1109 |
-+ *(void **)&bin_attr_image.private = bgrt_image; |
1110 |
-+ *(size_t *)&bin_attr_image.size = bgrt_image_size; |
1111 |
++ const_cast(bin_attr_image.private) = bgrt_image; |
1112 |
++ const_cast(bin_attr_image.size) = bgrt_image_size; |
1113 |
+ pax_close_kernel(); |
1114 |
|
1115 |
bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); |
1116 |
@@ -39966,7 +39976,7 @@ index 7d00b7a..d5fd80d 100644 |
1117 |
int ret; |
1118 |
|
1119 |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c |
1120 |
-index 55e257c..28b9a25 100644 |
1121 |
+index 55e257c..554c697 100644 |
1122 |
--- a/drivers/ata/libata-core.c |
1123 |
+++ b/drivers/ata/libata-core.c |
1124 |
@@ -103,7 +103,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev); |
1125 |
@@ -40009,7 +40019,7 @@ index 55e257c..28b9a25 100644 |
1126 |
*pp = NULL; |
1127 |
|
1128 |
- ops->inherits = NULL; |
1129 |
-+ *(struct ata_port_operations **)&ops->inherits = NULL; |
1130 |
++ const_cast(ops->inherits) = NULL; |
1131 |
|
1132 |
+ pax_close_kernel(); |
1133 |
spin_unlock(&lock); |
1134 |
@@ -40051,7 +40061,7 @@ index f840ca1..edd6ef3 100644 |
1135 |
extern int libata_fua; |
1136 |
extern int libata_noacpi; |
1137 |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c |
1138 |
-index 80fe0f6..8c0fa3f 100644 |
1139 |
+index 80fe0f6..d95a192 100644 |
1140 |
--- a/drivers/ata/pata_arasan_cf.c |
1141 |
+++ b/drivers/ata/pata_arasan_cf.c |
1142 |
@@ -864,7 +864,9 @@ static int arasan_cf_probe(struct platform_device *pdev) |
1143 |
@@ -40060,7 +40070,7 @@ index 80fe0f6..8c0fa3f 100644 |
1144 |
if (quirk & CF_BROKEN_PIO) { |
1145 |
- ap->ops->set_piomode = NULL; |
1146 |
+ pax_open_kernel(); |
1147 |
-+ *(void **)&ap->ops->set_piomode = NULL; |
1148 |
++ const_cast(ap->ops->set_piomode) = NULL; |
1149 |
+ pax_close_kernel(); |
1150 |
ap->pio_mask = 0; |
1151 |
} |
1152 |
@@ -41138,7 +41148,7 @@ index 560751b..3a4847a 100644 |
1153 |
static ssize_t show_node_state(struct device *dev, |
1154 |
struct device_attribute *attr, char *buf) |
1155 |
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c |
1156 |
-index 279e539..b87ed03 100644 |
1157 |
+index 279e539..4c9d7fb 100644 |
1158 |
--- a/drivers/base/platform-msi.c |
1159 |
+++ b/drivers/base/platform-msi.c |
1160 |
@@ -24,6 +24,8 @@ |
1161 |
@@ -41157,10 +41167,10 @@ index 279e539..b87ed03 100644 |
1162 |
+ pax_open_kernel(); |
1163 |
if (ops->msi_init == NULL) |
1164 |
- ops->msi_init = platform_msi_init; |
1165 |
-+ *(void **)&ops->msi_init = platform_msi_init; |
1166 |
++ const_cast(ops->msi_init) = platform_msi_init; |
1167 |
if (ops->set_desc == NULL) |
1168 |
- ops->set_desc = platform_msi_set_desc; |
1169 |
-+ *(void **)&ops->set_desc = platform_msi_set_desc; |
1170 |
++ const_cast(ops->set_desc) = platform_msi_set_desc; |
1171 |
+ pax_close_kernel(); |
1172 |
} |
1173 |
|
1174 |
@@ -41172,25 +41182,25 @@ index 279e539..b87ed03 100644 |
1175 |
+ pax_open_kernel(); |
1176 |
if (!chip->irq_mask) |
1177 |
- chip->irq_mask = irq_chip_mask_parent; |
1178 |
-+ *(void **)&chip->irq_mask = irq_chip_mask_parent; |
1179 |
++ const_cast(chip->irq_mask) = irq_chip_mask_parent; |
1180 |
if (!chip->irq_unmask) |
1181 |
- chip->irq_unmask = irq_chip_unmask_parent; |
1182 |
-+ *(void **)&chip->irq_unmask = irq_chip_unmask_parent; |
1183 |
++ const_cast(chip->irq_unmask) = irq_chip_unmask_parent; |
1184 |
if (!chip->irq_eoi) |
1185 |
- chip->irq_eoi = irq_chip_eoi_parent; |
1186 |
-+ *(void **)&chip->irq_eoi = irq_chip_eoi_parent; |
1187 |
++ const_cast(chip->irq_eoi) = irq_chip_eoi_parent; |
1188 |
if (!chip->irq_set_affinity) |
1189 |
- chip->irq_set_affinity = msi_domain_set_affinity; |
1190 |
-+ *(void **)&chip->irq_set_affinity = msi_domain_set_affinity; |
1191 |
++ const_cast(chip->irq_set_affinity) = msi_domain_set_affinity; |
1192 |
if (!chip->irq_write_msi_msg) |
1193 |
- chip->irq_write_msi_msg = platform_msi_write_msg; |
1194 |
-+ *(void **)&chip->irq_write_msi_msg = platform_msi_write_msg; |
1195 |
++ const_cast(chip->irq_write_msi_msg) = platform_msi_write_msg; |
1196 |
+ pax_close_kernel(); |
1197 |
} |
1198 |
|
1199 |
static void platform_msi_free_descs(struct device *dev, int base, int nvec) |
1200 |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c |
1201 |
-index 0caf92a..cff4879 100644 |
1202 |
+index 0caf92a..62c184c 100644 |
1203 |
--- a/drivers/base/power/domain.c |
1204 |
+++ b/drivers/base/power/domain.c |
1205 |
@@ -1804,8 +1804,10 @@ int genpd_dev_pm_attach(struct device *dev) |
1206 |
@@ -41200,8 +41210,8 @@ index 0caf92a..cff4879 100644 |
1207 |
- dev->pm_domain->detach = genpd_dev_pm_detach; |
1208 |
- dev->pm_domain->sync = genpd_dev_pm_sync; |
1209 |
+ pax_open_kernel(); |
1210 |
-+ *(void **)&dev->pm_domain->detach = genpd_dev_pm_detach; |
1211 |
-+ *(void **)&dev->pm_domain->sync = genpd_dev_pm_sync; |
1212 |
++ const_cast(dev->pm_domain->detach) = genpd_dev_pm_detach; |
1213 |
++ const_cast(dev->pm_domain->sync) = genpd_dev_pm_sync; |
1214 |
+ pax_close_kernel(); |
1215 |
|
1216 |
mutex_lock(&pd->lock); |
1217 |
@@ -42349,7 +42359,7 @@ index 24a652f..2dffae6 100644 |
1218 |
int err; |
1219 |
|
1220 |
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c |
1221 |
-index 577cc4b..bfe0c2d 100644 |
1222 |
+index 577cc4b..129a13e 100644 |
1223 |
--- a/drivers/bus/arm-cci.c |
1224 |
+++ b/drivers/bus/arm-cci.c |
1225 |
@@ -1249,16 +1249,22 @@ static int cci_pmu_init_attrs(struct cci_pmu *cci_pmu, struct platform_device *p |
1226 |
@@ -42358,7 +42368,7 @@ index 577cc4b..bfe0c2d 100644 |
1227 |
return -ENOMEM; |
1228 |
- pmu_event_attr_group.attrs = attrs; |
1229 |
+ pax_open_kernel(); |
1230 |
-+ *(struct attribute ***)&pmu_event_attr_group.attrs = attrs; |
1231 |
++ const_cast(pmu_event_attr_group.attrs) = attrs; |
1232 |
+ pax_close_kernel(); |
1233 |
} |
1234 |
if (model->nformat_attrs) { |
1235 |
@@ -42368,18 +42378,18 @@ index 577cc4b..bfe0c2d 100644 |
1236 |
return -ENOMEM; |
1237 |
- pmu_format_attr_group.attrs = attrs; |
1238 |
+ pax_open_kernel(); |
1239 |
-+ *(struct attribute ***)&pmu_format_attr_group.attrs = attrs; |
1240 |
++ const_cast(pmu_format_attr_group.attrs) = attrs; |
1241 |
+ pax_close_kernel(); |
1242 |
} |
1243 |
- pmu_cpumask_attr.var = cci_pmu; |
1244 |
+ pax_open_kernel(); |
1245 |
-+ *(void **)&pmu_cpumask_attr.var = cci_pmu; |
1246 |
++ const_cast(pmu_cpumask_attr.var) = cci_pmu; |
1247 |
+ pax_close_kernel(); |
1248 |
|
1249 |
return 0; |
1250 |
} |
1251 |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c |
1252 |
-index 1b257ea..ea76b22 100644 |
1253 |
+index 1b257ea..2280898 100644 |
1254 |
--- a/drivers/cdrom/cdrom.c |
1255 |
+++ b/drivers/cdrom/cdrom.c |
1256 |
@@ -610,7 +610,6 @@ int register_cdrom(struct cdrom_device_info *cdi) |
1257 |
@@ -42398,7 +42408,7 @@ index 1b257ea..ea76b22 100644 |
1258 |
- cdo->generic_packet = cdrom_dummy_generic_packet; |
1259 |
+ if (!cdo->generic_packet) { |
1260 |
+ pax_open_kernel(); |
1261 |
-+ *(void **)&cdo->generic_packet = cdrom_dummy_generic_packet; |
1262 |
++ const_cast(cdo->generic_packet) = cdrom_dummy_generic_packet; |
1263 |
+ pax_close_kernel(); |
1264 |
+ } |
1265 |
|
1266 |
@@ -43150,7 +43160,7 @@ index aa872d2..afeae37 100644 |
1267 |
/** |
1268 |
* struct samsung_clk_reg_dump: register dump of clock controller registers. |
1269 |
diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c |
1270 |
-index aa7a6e6..e67210d 100644 |
1271 |
+index aa7a6e6..1e9b426 100644 |
1272 |
--- a/drivers/clk/socfpga/clk-gate.c |
1273 |
+++ b/drivers/clk/socfpga/clk-gate.c |
1274 |
@@ -21,6 +21,7 @@ |
1275 |
@@ -43177,14 +43187,14 @@ index aa7a6e6..e67210d 100644 |
1276 |
- gateclk_ops.enable = clk_gate_ops.enable; |
1277 |
- gateclk_ops.disable = clk_gate_ops.disable; |
1278 |
+ pax_open_kernel(); |
1279 |
-+ *(void **)&gateclk_ops.enable = clk_gate_ops.enable; |
1280 |
-+ *(void **)&gateclk_ops.disable = clk_gate_ops.disable; |
1281 |
++ const_cast(gateclk_ops.enable) = clk_gate_ops.enable; |
1282 |
++ const_cast(gateclk_ops.disable) = clk_gate_ops.disable; |
1283 |
+ pax_close_kernel(); |
1284 |
} |
1285 |
|
1286 |
rc = of_property_read_u32(node, "fixed-divider", &fixed_div); |
1287 |
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c |
1288 |
-index c7f4631..463813a 100644 |
1289 |
+index c7f4631..8d1b7d0 100644 |
1290 |
--- a/drivers/clk/socfpga/clk-pll.c |
1291 |
+++ b/drivers/clk/socfpga/clk-pll.c |
1292 |
@@ -20,6 +20,7 @@ |
1293 |
@@ -43211,14 +43221,14 @@ index c7f4631..463813a 100644 |
1294 |
- clk_pll_ops.enable = clk_gate_ops.enable; |
1295 |
- clk_pll_ops.disable = clk_gate_ops.disable; |
1296 |
+ pax_open_kernel(); |
1297 |
-+ *(void **)&clk_pll_ops.enable = clk_gate_ops.enable; |
1298 |
-+ *(void **)&clk_pll_ops.disable = clk_gate_ops.disable; |
1299 |
++ const_cast(clk_pll_ops.enable) = clk_gate_ops.enable; |
1300 |
++ const_cast(clk_pll_ops.disable) = clk_gate_ops.disable; |
1301 |
+ pax_close_kernel(); |
1302 |
|
1303 |
clk = clk_register(NULL, &pll_clk->hw.hw); |
1304 |
if (WARN_ON(IS_ERR(clk))) { |
1305 |
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c |
1306 |
-index b5bcd77..0f7bd99 100644 |
1307 |
+index b5bcd77..fc230cb 100644 |
1308 |
--- a/drivers/clk/ti/clk.c |
1309 |
+++ b/drivers/clk/ti/clk.c |
1310 |
@@ -25,6 +25,8 @@ |
1311 |
@@ -43237,14 +43247,14 @@ index b5bcd77..0f7bd99 100644 |
1312 |
- ops->clk_readl = clk_memmap_readl; |
1313 |
- ops->clk_writel = clk_memmap_writel; |
1314 |
+ pax_open_kernel(); |
1315 |
-+ *(void **)&ops->clk_readl = clk_memmap_readl; |
1316 |
-+ *(void **)&ops->clk_writel = clk_memmap_writel; |
1317 |
++ const_cast(ops->clk_readl) = clk_memmap_readl; |
1318 |
++ const_cast(ops->clk_writel) = clk_memmap_writel; |
1319 |
+ pax_close_kernel(); |
1320 |
|
1321 |
return 0; |
1322 |
} |
1323 |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c |
1324 |
-index 51eef87..d944fa7 100644 |
1325 |
+index 51eef87..f530cf9 100644 |
1326 |
--- a/drivers/cpufreq/acpi-cpufreq.c |
1327 |
+++ b/drivers/cpufreq/acpi-cpufreq.c |
1328 |
@@ -682,8 +682,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) |
1329 |
@@ -43255,7 +43265,7 @@ index 51eef87..d944fa7 100644 |
1330 |
- acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; |
1331 |
+ if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { |
1332 |
+ pax_open_kernel(); |
1333 |
-+ *(u8 *)&acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; |
1334 |
++ const_cast(acpi_cpufreq_driver.flags) |= CPUFREQ_CONST_LOOPS; |
1335 |
+ pax_close_kernel(); |
1336 |
+ } |
1337 |
|
1338 |
@@ -43267,7 +43277,7 @@ index 51eef87..d944fa7 100644 |
1339 |
case ACPI_ADR_SPACE_FIXED_HARDWARE: |
1340 |
- acpi_cpufreq_driver.get = get_cur_freq_on_cpu; |
1341 |
+ pax_open_kernel(); |
1342 |
-+ *(void **)&acpi_cpufreq_driver.get = get_cur_freq_on_cpu; |
1343 |
++ const_cast(acpi_cpufreq_driver.get) = get_cur_freq_on_cpu; |
1344 |
+ pax_close_kernel(); |
1345 |
break; |
1346 |
default: |
1347 |
@@ -43279,14 +43289,14 @@ index 51eef87..d944fa7 100644 |
1348 |
- acpi_cpufreq_driver.set_boost = set_boost; |
1349 |
- acpi_cpufreq_driver.boost_enabled = boost_state(0); |
1350 |
+ pax_open_kernel(); |
1351 |
-+ *(void **)&acpi_cpufreq_driver.set_boost = set_boost; |
1352 |
-+ *(bool *)&acpi_cpufreq_driver.boost_enabled = boost_state(0); |
1353 |
++ const_cast(acpi_cpufreq_driver.set_boost) = set_boost; |
1354 |
++ const_cast(acpi_cpufreq_driver.boost_enabled) = boost_state(0); |
1355 |
+ pax_close_kernel(); |
1356 |
|
1357 |
cpu_notifier_register_begin(); |
1358 |
|
1359 |
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c |
1360 |
-index 0ca74d0..15705fb 100644 |
1361 |
+index 0ca74d0..1a0d302 100644 |
1362 |
--- a/drivers/cpufreq/cpufreq-dt.c |
1363 |
+++ b/drivers/cpufreq/cpufreq-dt.c |
1364 |
@@ -461,7 +461,9 @@ static int dt_cpufreq_probe(struct platform_device *pdev) |
1365 |
@@ -43295,13 +43305,13 @@ index 0ca74d0..15705fb 100644 |
1366 |
|
1367 |
- dt_cpufreq_driver.driver_data = dev_get_platdata(&pdev->dev); |
1368 |
+ pax_open_kernel(); |
1369 |
-+ *(void **)&dt_cpufreq_driver.driver_data = dev_get_platdata(&pdev->dev); |
1370 |
++ const_cast(dt_cpufreq_driver.driver_data) = dev_get_platdata(&pdev->dev); |
1371 |
+ pax_close_kernel(); |
1372 |
|
1373 |
ret = cpufreq_register_driver(&dt_cpufreq_driver); |
1374 |
if (ret) |
1375 |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c |
1376 |
-index e979ec7..a024e16 100644 |
1377 |
+index e979ec7..a76375c 100644 |
1378 |
--- a/drivers/cpufreq/cpufreq.c |
1379 |
+++ b/drivers/cpufreq/cpufreq.c |
1380 |
@@ -474,12 +474,12 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_transition_end); |
1381 |
@@ -43343,7 +43353,7 @@ index e979ec7..a024e16 100644 |
1382 |
write_lock_irqsave(&cpufreq_driver_lock, flags); |
1383 |
- cpufreq_driver->boost_enabled = state; |
1384 |
+ pax_open_kernel(); |
1385 |
-+ *(bool *)&cpufreq_driver->boost_enabled = state; |
1386 |
++ const_cast(cpufreq_driver->boost_enabled) = state; |
1387 |
+ pax_close_kernel(); |
1388 |
write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1389 |
|
1390 |
@@ -43352,7 +43362,7 @@ index e979ec7..a024e16 100644 |
1391 |
write_lock_irqsave(&cpufreq_driver_lock, flags); |
1392 |
- cpufreq_driver->boost_enabled = !state; |
1393 |
+ pax_open_kernel(); |
1394 |
-+ *(bool *)&cpufreq_driver->boost_enabled = !state; |
1395 |
++ const_cast(cpufreq_driver->boost_enabled) = !state; |
1396 |
+ pax_close_kernel(); |
1397 |
write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1398 |
|
1399 |
@@ -43363,7 +43373,7 @@ index e979ec7..a024e16 100644 |
1400 |
|
1401 |
- cpufreq_driver->set_boost = cpufreq_boost_set_sw; |
1402 |
+ pax_open_kernel(); |
1403 |
-+ *(void **)&cpufreq_driver->set_boost = cpufreq_boost_set_sw; |
1404 |
++ const_cast(cpufreq_driver->set_boost) = cpufreq_boost_set_sw; |
1405 |
+ pax_close_kernel(); |
1406 |
|
1407 |
/* This will get removed on driver unregister */ |
1408 |
@@ -43376,7 +43386,7 @@ index e979ec7..a024e16 100644 |
1409 |
- driver_data->flags |= CPUFREQ_CONST_LOOPS; |
1410 |
+ if (driver_data->setpolicy) { |
1411 |
+ pax_open_kernel(); |
1412 |
-+ *(u8 *)&driver_data->flags |= CPUFREQ_CONST_LOOPS; |
1413 |
++ const_cast(driver_data->flags) |= CPUFREQ_CONST_LOOPS; |
1414 |
+ pax_close_kernel(); |
1415 |
+ } |
1416 |
|
1417 |
@@ -43445,7 +43455,7 @@ index 91e767a0..3b40724 100644 |
1418 |
struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data; \ |
1419 |
return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ |
1420 |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c |
1421 |
-index eae5107..26e7a39 100644 |
1422 |
+index eae5107..3dd6408 100644 |
1423 |
--- a/drivers/cpufreq/cpufreq_ondemand.c |
1424 |
+++ b/drivers/cpufreq/cpufreq_ondemand.c |
1425 |
@@ -534,7 +534,7 @@ static void od_exit(struct dbs_data *dbs_data, bool notify) |
1426 |
@@ -43463,7 +43473,7 @@ index eae5107..26e7a39 100644 |
1427 |
{ |
1428 |
- od_ops.powersave_bias_target = f; |
1429 |
+ pax_open_kernel(); |
1430 |
-+ *(void **)&od_ops.powersave_bias_target = f; |
1431 |
++ const_cast(od_ops.powersave_bias_target) = f; |
1432 |
+ pax_close_kernel(); |
1433 |
od_set_powersave_bias(powersave_bias); |
1434 |
} |
1435 |
@@ -43473,7 +43483,7 @@ index eae5107..26e7a39 100644 |
1436 |
{ |
1437 |
- od_ops.powersave_bias_target = generic_powersave_bias_target; |
1438 |
+ pax_open_kernel(); |
1439 |
-+ *(void **)&od_ops.powersave_bias_target = generic_powersave_bias_target; |
1440 |
++ const_cast(od_ops.powersave_bias_target) = generic_powersave_bias_target; |
1441 |
+ pax_close_kernel(); |
1442 |
od_set_powersave_bias(0); |
1443 |
} |
1444 |
@@ -43634,7 +43644,7 @@ index e895123..05de99b 100644 |
1445 |
|
1446 |
#if IS_ENABLED(CONFIG_ACPI) |
1447 |
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c |
1448 |
-index 5dd95da..abc3837 100644 |
1449 |
+index 5dd95da..ac41e5e 100644 |
1450 |
--- a/drivers/cpufreq/p4-clockmod.c |
1451 |
+++ b/drivers/cpufreq/p4-clockmod.c |
1452 |
@@ -134,10 +134,14 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) |
1453 |
@@ -43643,13 +43653,13 @@ index 5dd95da..abc3837 100644 |
1454 |
case 0x1C: /* Atom */ |
1455 |
- p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
1456 |
+ pax_open_kernel(); |
1457 |
-+ *(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
1458 |
++ const_cast(p4clockmod_driver.flags) |= CPUFREQ_CONST_LOOPS; |
1459 |
+ pax_close_kernel(); |
1460 |
return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE); |
1461 |
case 0x0D: /* Pentium M (Dothan) */ |
1462 |
- p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
1463 |
+ pax_open_kernel(); |
1464 |
-+ *(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
1465 |
++ const_cast(p4clockmod_driver.flags) |= CPUFREQ_CONST_LOOPS; |
1466 |
+ pax_close_kernel(); |
1467 |
/* fall through */ |
1468 |
case 0x09: /* Pentium M (Banias) */ |
1469 |
@@ -43660,7 +43670,7 @@ index 5dd95da..abc3837 100644 |
1470 |
* throttling is active or not. */ |
1471 |
- p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
1472 |
+ pax_open_kernel(); |
1473 |
-+ *(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; |
1474 |
++ const_cast(p4clockmod_driver.flags) |= CPUFREQ_CONST_LOOPS; |
1475 |
+ pax_close_kernel(); |
1476 |
|
1477 |
if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) { |
1478 |
@@ -43776,7 +43786,7 @@ index 9bb42ba..b01b4a2 100644 |
1479 |
|
1480 |
MODULE_AUTHOR("David S. Miller <davem@××××××.com>"); |
1481 |
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c |
1482 |
-index 7d4a315..21bb886 100644 |
1483 |
+index 7d4a315..ce41fb3 100644 |
1484 |
--- a/drivers/cpufreq/speedstep-centrino.c |
1485 |
+++ b/drivers/cpufreq/speedstep-centrino.c |
1486 |
@@ -351,8 +351,11 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) |
1487 |
@@ -43787,7 +43797,7 @@ index 7d4a315..21bb886 100644 |
1488 |
- centrino_driver.flags |= CPUFREQ_CONST_LOOPS; |
1489 |
+ if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) { |
1490 |
+ pax_open_kernel(); |
1491 |
-+ *(u8 *)¢rino_driver.flags |= CPUFREQ_CONST_LOOPS; |
1492 |
++ const_cast(centrino_driver.flags) |= CPUFREQ_CONST_LOOPS; |
1493 |
+ pax_close_kernel(); |
1494 |
+ } |
1495 |
|
1496 |
@@ -44575,7 +44585,7 @@ index 94a58a0..5b8dd03 100644 |
1497 |
}; |
1498 |
|
1499 |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c |
1500 |
-index 88bebe1..c7b636f 100644 |
1501 |
+index 88bebe1..e599fad 100644 |
1502 |
--- a/drivers/firmware/dmi_scan.c |
1503 |
+++ b/drivers/firmware/dmi_scan.c |
1504 |
@@ -712,14 +712,18 @@ static int __init dmi_init(void) |
1505 |
@@ -44585,8 +44595,8 @@ index 88bebe1..c7b636f 100644 |
1506 |
- bin_attr_smbios_entry_point.size = smbios_entry_point_size; |
1507 |
- bin_attr_smbios_entry_point.private = smbios_entry_point; |
1508 |
+ pax_open_kernel(); |
1509 |
-+ *(size_t *)&bin_attr_smbios_entry_point.size = smbios_entry_point_size; |
1510 |
-+ *(void **)&bin_attr_smbios_entry_point.private = smbios_entry_point; |
1511 |
++ const_cast(bin_attr_smbios_entry_point.size) = smbios_entry_point_size; |
1512 |
++ const_cast(bin_attr_smbios_entry_point.private) = smbios_entry_point; |
1513 |
+ pax_close_kernel(); |
1514 |
ret = sysfs_create_bin_file(tables_kobj, &bin_attr_smbios_entry_point); |
1515 |
if (ret) |
1516 |
@@ -44595,8 +44605,8 @@ index 88bebe1..c7b636f 100644 |
1517 |
- bin_attr_DMI.size = dmi_len; |
1518 |
- bin_attr_DMI.private = dmi_table; |
1519 |
+ pax_open_kernel(); |
1520 |
-+ *(size_t *)&bin_attr_DMI.size = dmi_len; |
1521 |
-+ *(void **)&bin_attr_DMI.private = dmi_table; |
1522 |
++ const_cast(bin_attr_DMI.size) = dmi_len; |
1523 |
++ const_cast(bin_attr_DMI.private) = dmi_table; |
1524 |
+ pax_close_kernel(); |
1525 |
ret = sysfs_create_bin_file(tables_kobj, &bin_attr_DMI); |
1526 |
if (!ret) |
1527 |
@@ -44623,7 +44633,7 @@ index d425374..1da1716 100644 |
1528 |
EXPORT_SYMBOL_GPL(cper_next_record_id); |
1529 |
|
1530 |
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c |
1531 |
-index c51f3b2..d1cc54e 100644 |
1532 |
+index c51f3b2..54523fd 100644 |
1533 |
--- a/drivers/firmware/efi/efi.c |
1534 |
+++ b/drivers/firmware/efi/efi.c |
1535 |
@@ -176,15 +176,17 @@ static struct attribute_group efi_subsys_attr_group = { |
1536 |
@@ -44641,11 +44651,11 @@ index c51f3b2..d1cc54e 100644 |
1537 |
- generic_ops.get_next_variable = efi.get_next_variable; |
1538 |
- generic_ops.query_variable_store = efi_query_variable_store; |
1539 |
+ pax_open_kernel(); |
1540 |
-+ *(void **)&generic_ops.get_variable = efi.get_variable; |
1541 |
-+ *(void **)&generic_ops.set_variable = efi.set_variable; |
1542 |
-+ *(void **)&generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; |
1543 |
-+ *(void **)&generic_ops.get_next_variable = efi.get_next_variable; |
1544 |
-+ *(void **)&generic_ops.query_variable_store = efi_query_variable_store; |
1545 |
++ const_cast(generic_ops.get_variable) = efi.get_variable; |
1546 |
++ const_cast(generic_ops.set_variable) = efi.set_variable; |
1547 |
++ const_cast(generic_ops.set_variable_nonblocking) = efi.set_variable_nonblocking; |
1548 |
++ const_cast(generic_ops.get_next_variable) = efi.get_next_variable; |
1549 |
++ const_cast(generic_ops.query_variable_store) = efi_query_variable_store; |
1550 |
+ pax_close_kernel(); |
1551 |
|
1552 |
return efivars_register(&generic_efivars, &generic_ops, efi_kobj); |
1553 |
@@ -44690,7 +44700,7 @@ index f1ab05e..ab51228 100644 |
1554 |
.ident = "Google Board", |
1555 |
.matches = { |
1556 |
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c |
1557 |
-index 2f569aa..26e4f39 100644 |
1558 |
+index 2f569aa..3af5497 100644 |
1559 |
--- a/drivers/firmware/google/memconsole.c |
1560 |
+++ b/drivers/firmware/google/memconsole.c |
1561 |
@@ -136,7 +136,7 @@ static bool __init found_memconsole(void) |
1562 |
@@ -44708,7 +44718,7 @@ index 2f569aa..26e4f39 100644 |
1563 |
|
1564 |
- memconsole_bin_attr.size = memconsole_length; |
1565 |
+ pax_open_kernel(); |
1566 |
-+ *(size_t *)&memconsole_bin_attr.size = memconsole_length; |
1567 |
++ const_cast(memconsole_bin_attr.size) = memconsole_length; |
1568 |
+ pax_close_kernel(); |
1569 |
+ |
1570 |
return sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr); |
1571 |
@@ -44840,7 +44850,7 @@ index ac8deb0..f3caa10 100644 |
1572 |
return -EINVAL; |
1573 |
} |
1574 |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c |
1575 |
-index 5c1ba87..ab4a059 100644 |
1576 |
+index 5c1ba87..f711915 100644 |
1577 |
--- a/drivers/gpio/gpiolib.c |
1578 |
+++ b/drivers/gpio/gpiolib.c |
1579 |
@@ -669,8 +669,10 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) |
1580 |
@@ -44850,8 +44860,8 @@ index 5c1ba87..ab4a059 100644 |
1581 |
- gpiochip->irqchip->irq_request_resources = NULL; |
1582 |
- gpiochip->irqchip->irq_release_resources = NULL; |
1583 |
+ pax_open_kernel(); |
1584 |
-+ *(void **)&gpiochip->irqchip->irq_request_resources = NULL; |
1585 |
-+ *(void **)&gpiochip->irqchip->irq_release_resources = NULL; |
1586 |
++ const_cast(gpiochip->irqchip->irq_request_resources) = NULL; |
1587 |
++ const_cast(gpiochip->irqchip->irq_release_resources) = NULL; |
1588 |
+ pax_close_kernel(); |
1589 |
gpiochip->irqchip = NULL; |
1590 |
} |
1591 |
@@ -44863,8 +44873,8 @@ index 5c1ba87..ab4a059 100644 |
1592 |
- irqchip->irq_request_resources = gpiochip_irq_reqres; |
1593 |
- irqchip->irq_release_resources = gpiochip_irq_relres; |
1594 |
+ pax_open_kernel(); |
1595 |
-+ *(void **)&irqchip->irq_request_resources = gpiochip_irq_reqres; |
1596 |
-+ *(void **)&irqchip->irq_release_resources = gpiochip_irq_relres; |
1597 |
++ const_cast(irqchip->irq_request_resources) = gpiochip_irq_reqres; |
1598 |
++ const_cast(irqchip->irq_release_resources) = gpiochip_irq_relres; |
1599 |
+ pax_close_kernel(); |
1600 |
} |
1601 |
|
1602 |
@@ -45050,7 +45060,7 @@ index 51bfc11..4d4112a 100644 |
1603 |
|
1604 |
static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = { |
1605 |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |
1606 |
-index 9ef1db8..bfd5d78 100644 |
1607 |
+index 9ef1db8..5eec19b 100644 |
1608 |
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |
1609 |
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |
1610 |
@@ -495,7 +495,7 @@ static struct drm_driver kms_driver = { |
1611 |
@@ -45082,7 +45092,7 @@ index 9ef1db8..bfd5d78 100644 |
1612 |
- driver->num_ioctls = amdgpu_max_kms_ioctl; |
1613 |
+ |
1614 |
+ pax_open_kernel(); |
1615 |
-+ *(int *)&kms_driver.num_ioctls = amdgpu_max_kms_ioctl; |
1616 |
++ const_cast(kms_driver.num_ioctls) = amdgpu_max_kms_ioctl; |
1617 |
+ pax_close_kernel(); |
1618 |
+ |
1619 |
amdgpu_register_atpx_handler(); |
1620 |
@@ -46288,7 +46298,7 @@ index d918567..6cfd904 100644 |
1621 |
/** |
1622 |
* Determine if the device really is AGP or not. |
1623 |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c |
1624 |
-index 44f4a13..0063c1b 100644 |
1625 |
+index 44f4a13..af9f6f5 100644 |
1626 |
--- a/drivers/gpu/drm/i810/i810_drv.c |
1627 |
+++ b/drivers/gpu/drm/i810/i810_drv.c |
1628 |
@@ -87,7 +87,11 @@ static int __init i810_init(void) |
1629 |
@@ -46298,7 +46308,7 @@ index 44f4a13..0063c1b 100644 |
1630 |
- driver.num_ioctls = i810_max_ioctl; |
1631 |
+ |
1632 |
+ pax_open_kernel(); |
1633 |
-+ *(int *)&driver.num_ioctls = i810_max_ioctl; |
1634 |
++ const_cast(driver.num_ioctls) = i810_max_ioctl; |
1635 |
+ pax_close_kernel(); |
1636 |
+ |
1637 |
return drm_pci_init(&driver, &i810_pci_driver); |
1638 |
@@ -46547,7 +46557,7 @@ index 97f3a56..32c712e 100644 |
1639 |
ret = drm_ioctl(filp, cmd, arg); |
1640 |
|
1641 |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c |
1642 |
-index fa8afa7..0bac957 100644 |
1643 |
+index fa8afa7..7375300 100644 |
1644 |
--- a/drivers/gpu/drm/i915/i915_irq.c |
1645 |
+++ b/drivers/gpu/drm/i915/i915_irq.c |
1646 |
@@ -4490,14 +4490,15 @@ void intel_irq_init(struct drm_i915_private *dev_priv) |
1647 |
@@ -46558,14 +46568,14 @@ index fa8afa7..0bac957 100644 |
1648 |
if (IS_GEN2(dev_priv)) { |
1649 |
dev->max_vblank_count = 0; |
1650 |
- dev->driver->get_vblank_counter = i8xx_get_vblank_counter; |
1651 |
-+ *(void **)&dev->driver->get_vblank_counter = i8xx_get_vblank_counter; |
1652 |
++ const_cast(dev->driver->get_vblank_counter) = i8xx_get_vblank_counter; |
1653 |
} else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { |
1654 |
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ |
1655 |
- dev->driver->get_vblank_counter = g4x_get_vblank_counter; |
1656 |
-+ *(void **)&dev->driver->get_vblank_counter = g4x_get_vblank_counter; |
1657 |
++ const_cast(dev->driver->get_vblank_counter) = g4x_get_vblank_counter; |
1658 |
} else { |
1659 |
- dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1660 |
-+ *(void **)&dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1661 |
++ const_cast(dev->driver->get_vblank_counter) = i915_get_vblank_counter; |
1662 |
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1663 |
} |
1664 |
|
1665 |
@@ -46575,8 +46585,8 @@ index fa8afa7..0bac957 100644 |
1666 |
|
1667 |
- dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
1668 |
- dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
1669 |
-+ *(void **)&dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
1670 |
-+ *(void **)&dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
1671 |
++ const_cast(dev->driver->get_vblank_timestamp) = i915_get_vblank_timestamp; |
1672 |
++ const_cast(dev->driver->get_scanout_position) = i915_get_crtc_scanoutpos; |
1673 |
|
1674 |
if (IS_CHERRYVIEW(dev_priv)) { |
1675 |
- dev->driver->irq_handler = cherryview_irq_handler; |
1676 |
@@ -46585,12 +46595,12 @@ index fa8afa7..0bac957 100644 |
1677 |
- dev->driver->irq_uninstall = cherryview_irq_uninstall; |
1678 |
- dev->driver->enable_vblank = valleyview_enable_vblank; |
1679 |
- dev->driver->disable_vblank = valleyview_disable_vblank; |
1680 |
-+ *(void **)&dev->driver->irq_handler = cherryview_irq_handler; |
1681 |
-+ *(void **)&dev->driver->irq_preinstall = cherryview_irq_preinstall; |
1682 |
-+ *(void **)&dev->driver->irq_postinstall = cherryview_irq_postinstall; |
1683 |
-+ *(void **)&dev->driver->irq_uninstall = cherryview_irq_uninstall; |
1684 |
-+ *(void **)&dev->driver->enable_vblank = valleyview_enable_vblank; |
1685 |
-+ *(void **)&dev->driver->disable_vblank = valleyview_disable_vblank; |
1686 |
++ const_cast(dev->driver->irq_handler) = cherryview_irq_handler; |
1687 |
++ const_cast(dev->driver->irq_preinstall) = cherryview_irq_preinstall; |
1688 |
++ const_cast(dev->driver->irq_postinstall) = cherryview_irq_postinstall; |
1689 |
++ const_cast(dev->driver->irq_uninstall) = cherryview_irq_uninstall; |
1690 |
++ const_cast(dev->driver->enable_vblank) = valleyview_enable_vblank; |
1691 |
++ const_cast(dev->driver->disable_vblank) = valleyview_disable_vblank; |
1692 |
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
1693 |
} else if (IS_VALLEYVIEW(dev_priv)) { |
1694 |
- dev->driver->irq_handler = valleyview_irq_handler; |
1695 |
@@ -46599,12 +46609,12 @@ index fa8afa7..0bac957 100644 |
1696 |
- dev->driver->irq_uninstall = valleyview_irq_uninstall; |
1697 |
- dev->driver->enable_vblank = valleyview_enable_vblank; |
1698 |
- dev->driver->disable_vblank = valleyview_disable_vblank; |
1699 |
-+ *(void **)&dev->driver->irq_handler = valleyview_irq_handler; |
1700 |
-+ *(void **)&dev->driver->irq_preinstall = valleyview_irq_preinstall; |
1701 |
-+ *(void **)&dev->driver->irq_postinstall = valleyview_irq_postinstall; |
1702 |
-+ *(void **)&dev->driver->irq_uninstall = valleyview_irq_uninstall; |
1703 |
-+ *(void **)&dev->driver->enable_vblank = valleyview_enable_vblank; |
1704 |
-+ *(void **)&dev->driver->disable_vblank = valleyview_disable_vblank; |
1705 |
++ const_cast(dev->driver->irq_handler) = valleyview_irq_handler; |
1706 |
++ const_cast(dev->driver->irq_preinstall) = valleyview_irq_preinstall; |
1707 |
++ const_cast(dev->driver->irq_postinstall) = valleyview_irq_postinstall; |
1708 |
++ const_cast(dev->driver->irq_uninstall) = valleyview_irq_uninstall; |
1709 |
++ const_cast(dev->driver->enable_vblank) = valleyview_enable_vblank; |
1710 |
++ const_cast(dev->driver->disable_vblank) = valleyview_disable_vblank; |
1711 |
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
1712 |
} else if (INTEL_INFO(dev_priv)->gen >= 8) { |
1713 |
- dev->driver->irq_handler = gen8_irq_handler; |
1714 |
@@ -46613,12 +46623,12 @@ index fa8afa7..0bac957 100644 |
1715 |
- dev->driver->irq_uninstall = gen8_irq_uninstall; |
1716 |
- dev->driver->enable_vblank = gen8_enable_vblank; |
1717 |
- dev->driver->disable_vblank = gen8_disable_vblank; |
1718 |
-+ *(void **)&dev->driver->irq_handler = gen8_irq_handler; |
1719 |
-+ *(void **)&dev->driver->irq_preinstall = gen8_irq_reset; |
1720 |
-+ *(void **)&dev->driver->irq_postinstall = gen8_irq_postinstall; |
1721 |
-+ *(void **)&dev->driver->irq_uninstall = gen8_irq_uninstall; |
1722 |
-+ *(void **)&dev->driver->enable_vblank = gen8_enable_vblank; |
1723 |
-+ *(void **)&dev->driver->disable_vblank = gen8_disable_vblank; |
1724 |
++ const_cast(dev->driver->irq_handler) = gen8_irq_handler; |
1725 |
++ const_cast(dev->driver->irq_preinstall) = gen8_irq_reset; |
1726 |
++ const_cast(dev->driver->irq_postinstall) = gen8_irq_postinstall; |
1727 |
++ const_cast(dev->driver->irq_uninstall) = gen8_irq_uninstall; |
1728 |
++ const_cast(dev->driver->enable_vblank) = gen8_enable_vblank; |
1729 |
++ const_cast(dev->driver->disable_vblank) = gen8_disable_vblank; |
1730 |
if (IS_BROXTON(dev)) |
1731 |
dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; |
1732 |
else if (HAS_PCH_SPT(dev)) |
1733 |
@@ -46632,12 +46642,12 @@ index fa8afa7..0bac957 100644 |
1734 |
- dev->driver->irq_uninstall = ironlake_irq_uninstall; |
1735 |
- dev->driver->enable_vblank = ironlake_enable_vblank; |
1736 |
- dev->driver->disable_vblank = ironlake_disable_vblank; |
1737 |
-+ *(void **)&dev->driver->irq_handler = ironlake_irq_handler; |
1738 |
-+ *(void **)&dev->driver->irq_preinstall = ironlake_irq_reset; |
1739 |
-+ *(void **)&dev->driver->irq_postinstall = ironlake_irq_postinstall; |
1740 |
-+ *(void **)&dev->driver->irq_uninstall = ironlake_irq_uninstall; |
1741 |
-+ *(void **)&dev->driver->enable_vblank = ironlake_enable_vblank; |
1742 |
-+ *(void **)&dev->driver->disable_vblank = ironlake_disable_vblank; |
1743 |
++ const_cast(dev->driver->irq_handler) = ironlake_irq_handler; |
1744 |
++ const_cast(dev->driver->irq_preinstall) = ironlake_irq_reset; |
1745 |
++ const_cast(dev->driver->irq_postinstall) = ironlake_irq_postinstall; |
1746 |
++ const_cast(dev->driver->irq_uninstall) = ironlake_irq_uninstall; |
1747 |
++ const_cast(dev->driver->enable_vblank) = ironlake_enable_vblank; |
1748 |
++ const_cast(dev->driver->disable_vblank) = ironlake_disable_vblank; |
1749 |
dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; |
1750 |
} else { |
1751 |
if (INTEL_INFO(dev_priv)->gen == 2) { |
1752 |
@@ -46645,42 +46655,42 @@ index fa8afa7..0bac957 100644 |
1753 |
- dev->driver->irq_postinstall = i8xx_irq_postinstall; |
1754 |
- dev->driver->irq_handler = i8xx_irq_handler; |
1755 |
- dev->driver->irq_uninstall = i8xx_irq_uninstall; |
1756 |
-+ *(void **)&dev->driver->irq_preinstall = i8xx_irq_preinstall; |
1757 |
-+ *(void **)&dev->driver->irq_postinstall = i8xx_irq_postinstall; |
1758 |
-+ *(void **)&dev->driver->irq_handler = i8xx_irq_handler; |
1759 |
-+ *(void **)&dev->driver->irq_uninstall = i8xx_irq_uninstall; |
1760 |
++ const_cast(dev->driver->irq_preinstall) = i8xx_irq_preinstall; |
1761 |
++ const_cast(dev->driver->irq_postinstall) = i8xx_irq_postinstall; |
1762 |
++ const_cast(dev->driver->irq_handler) = i8xx_irq_handler; |
1763 |
++ const_cast(dev->driver->irq_uninstall) = i8xx_irq_uninstall; |
1764 |
} else if (INTEL_INFO(dev_priv)->gen == 3) { |
1765 |
- dev->driver->irq_preinstall = i915_irq_preinstall; |
1766 |
- dev->driver->irq_postinstall = i915_irq_postinstall; |
1767 |
- dev->driver->irq_uninstall = i915_irq_uninstall; |
1768 |
- dev->driver->irq_handler = i915_irq_handler; |
1769 |
-+ *(void **)&dev->driver->irq_preinstall = i915_irq_preinstall; |
1770 |
-+ *(void **)&dev->driver->irq_postinstall = i915_irq_postinstall; |
1771 |
-+ *(void **)&dev->driver->irq_uninstall = i915_irq_uninstall; |
1772 |
-+ *(void **)&dev->driver->irq_handler = i915_irq_handler; |
1773 |
++ const_cast(dev->driver->irq_preinstall) = i915_irq_preinstall; |
1774 |
++ const_cast(dev->driver->irq_postinstall) = i915_irq_postinstall; |
1775 |
++ const_cast(dev->driver->irq_uninstall) = i915_irq_uninstall; |
1776 |
++ const_cast(dev->driver->irq_handler) = i915_irq_handler; |
1777 |
} else { |
1778 |
- dev->driver->irq_preinstall = i965_irq_preinstall; |
1779 |
- dev->driver->irq_postinstall = i965_irq_postinstall; |
1780 |
- dev->driver->irq_uninstall = i965_irq_uninstall; |
1781 |
- dev->driver->irq_handler = i965_irq_handler; |
1782 |
-+ *(void **)&dev->driver->irq_preinstall = i965_irq_preinstall; |
1783 |
-+ *(void **)&dev->driver->irq_postinstall = i965_irq_postinstall; |
1784 |
-+ *(void **)&dev->driver->irq_uninstall = i965_irq_uninstall; |
1785 |
-+ *(void **)&dev->driver->irq_handler = i965_irq_handler; |
1786 |
++ const_cast(dev->driver->irq_preinstall) = i965_irq_preinstall; |
1787 |
++ const_cast(dev->driver->irq_postinstall) = i965_irq_postinstall; |
1788 |
++ const_cast(dev->driver->irq_uninstall) = i965_irq_uninstall; |
1789 |
++ const_cast(dev->driver->irq_handler) = i965_irq_handler; |
1790 |
} |
1791 |
if (I915_HAS_HOTPLUG(dev_priv)) |
1792 |
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
1793 |
- dev->driver->enable_vblank = i915_enable_vblank; |
1794 |
- dev->driver->disable_vblank = i915_disable_vblank; |
1795 |
-+ *(void **)&dev->driver->enable_vblank = i915_enable_vblank; |
1796 |
-+ *(void **)&dev->driver->disable_vblank = i915_disable_vblank; |
1797 |
++ const_cast(dev->driver->enable_vblank) = i915_enable_vblank; |
1798 |
++ const_cast(dev->driver->disable_vblank) = i915_disable_vblank; |
1799 |
} |
1800 |
+ pax_close_kernel(); |
1801 |
} |
1802 |
|
1803 |
/** |
1804 |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
1805 |
-index 39b00b9..aa9fc8a 100644 |
1806 |
+index 39b00b9..244538d 100644 |
1807 |
--- a/drivers/gpu/drm/i915/intel_display.c |
1808 |
+++ b/drivers/gpu/drm/i915/intel_display.c |
1809 |
@@ -15111,13 +15111,13 @@ struct intel_quirk { |
1810 |
@@ -46693,8 +46703,9 @@ index 39b00b9..aa9fc8a 100644 |
1811 |
/* For systems that don't have a meaningful PCI subdevice/subvendor ID */ |
1812 |
struct intel_dmi_quirk { |
1813 |
void (*hook)(struct drm_device *dev); |
1814 |
- const struct dmi_system_id (*dmi_id_list)[]; |
1815 |
+- const struct dmi_system_id (*dmi_id_list)[]; |
1816 |
-}; |
1817 |
++ const struct dmi_system_id *dmi_id_list; |
1818 |
+} __do_const; |
1819 |
|
1820 |
static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) |
1821 |
@@ -46726,10 +46737,19 @@ index 39b00b9..aa9fc8a 100644 |
1822 |
+ |
1823 |
+static const struct intel_dmi_quirk intel_dmi_quirks[] = { |
1824 |
+ { |
1825 |
-+ .dmi_id_list = &intel_dmi_quirks_table, |
1826 |
++ .dmi_id_list = intel_dmi_quirks_table, |
1827 |
.hook = quirk_invert_brightness, |
1828 |
}, |
1829 |
}; |
1830 |
+@@ -15219,7 +15221,7 @@ static void intel_init_quirks(struct drm_device *dev) |
1831 |
+ q->hook(dev); |
1832 |
+ } |
1833 |
+ for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { |
1834 |
+- if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) |
1835 |
++ if (dmi_check_system(intel_dmi_quirks[i].dmi_id_list) != 0) |
1836 |
+ intel_dmi_quirks[i].hook(dev); |
1837 |
+ } |
1838 |
+ } |
1839 |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c |
1840 |
index 2f57d79..7152e6e 100644 |
1841 |
--- a/drivers/gpu/drm/imx/imx-drm-core.c |
1842 |
@@ -46744,7 +46764,7 @@ index 2f57d79..7152e6e 100644 |
1843 |
|
1844 |
imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL); |
1845 |
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c |
1846 |
-index 5e2f131..d227dbc 100644 |
1847 |
+index 5e2f131..c134c7c 100644 |
1848 |
--- a/drivers/gpu/drm/mga/mga_drv.c |
1849 |
+++ b/drivers/gpu/drm/mga/mga_drv.c |
1850 |
@@ -92,7 +92,10 @@ static struct pci_driver mga_pci_driver = { |
1851 |
@@ -46753,7 +46773,7 @@ index 5e2f131..d227dbc 100644 |
1852 |
{ |
1853 |
- driver.num_ioctls = mga_max_ioctl; |
1854 |
+ pax_open_kernel(); |
1855 |
-+ *(int *)&driver.num_ioctls = mga_max_ioctl; |
1856 |
++ const_cast(driver.num_ioctls) = mga_max_ioctl; |
1857 |
+ pax_close_kernel(); |
1858 |
+ |
1859 |
return drm_pci_init(&driver, &mga_pci_driver); |
1860 |
@@ -47140,7 +47160,7 @@ index fe4c222..48b7b75 100644 |
1861 |
omap_irq.o \ |
1862 |
omap_debugfs.o \ |
1863 |
diff --git a/drivers/gpu/drm/omapdrm/dss/display.c b/drivers/gpu/drm/omapdrm/dss/display.c |
1864 |
-index ef5b902..47cf7f5 100644 |
1865 |
+index ef5b902..2ae011b 100644 |
1866 |
--- a/drivers/gpu/drm/omapdrm/dss/display.c |
1867 |
+++ b/drivers/gpu/drm/omapdrm/dss/display.c |
1868 |
@@ -161,12 +161,14 @@ int omapdss_register_display(struct omap_dss_device *dssdev) |
1869 |
@@ -47150,13 +47170,13 @@ index ef5b902..47cf7f5 100644 |
1870 |
+ pax_open_kernel(); |
1871 |
if (drv && drv->get_resolution == NULL) |
1872 |
- drv->get_resolution = omapdss_default_get_resolution; |
1873 |
-+ *(void **)&drv->get_resolution = omapdss_default_get_resolution; |
1874 |
++ const_cast(drv->get_resolution) = omapdss_default_get_resolution; |
1875 |
if (drv && drv->get_recommended_bpp == NULL) |
1876 |
- drv->get_recommended_bpp = omapdss_default_get_recommended_bpp; |
1877 |
-+ *(void **)&drv->get_recommended_bpp = omapdss_default_get_recommended_bpp; |
1878 |
++ const_cast(drv->get_recommended_bpp) = omapdss_default_get_recommended_bpp; |
1879 |
if (drv && drv->get_timings == NULL) |
1880 |
- drv->get_timings = omapdss_default_get_timings; |
1881 |
-+ *(void **)&drv->get_timings = omapdss_default_get_timings; |
1882 |
++ const_cast(drv->get_timings) = omapdss_default_get_timings; |
1883 |
+ pax_close_kernel(); |
1884 |
|
1885 |
mutex_lock(&panel_list_mutex); |
1886 |
@@ -47232,7 +47252,7 @@ index 47e5264..3393741 100644 |
1887 |
{ |
1888 |
struct drm_device *ddev = connector->dev; |
1889 |
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c |
1890 |
-index 7307b07..8eecdd0 100644 |
1891 |
+index 7307b07..3346540 100644 |
1892 |
--- a/drivers/gpu/drm/qxl/qxl_drv.c |
1893 |
+++ b/drivers/gpu/drm/qxl/qxl_drv.c |
1894 |
@@ -37,7 +37,7 @@ |
1895 |
@@ -47251,7 +47271,7 @@ index 7307b07..8eecdd0 100644 |
1896 |
- qxl_driver.num_ioctls = qxl_max_ioctls; |
1897 |
+ |
1898 |
+ pax_open_kernel(); |
1899 |
-+ *(int *)&qxl_driver.num_ioctls = qxl_max_ioctls; |
1900 |
++ const_cast(qxl_driver.num_ioctls) = qxl_max_ioctls; |
1901 |
+ pax_close_kernel(); |
1902 |
+ |
1903 |
return drm_pci_init(&qxl_driver, &qxl_pci_driver); |
1904 |
@@ -47362,7 +47382,7 @@ index 0bf1e20..42a7310 100644 |
1905 |
ret = drm_irq_install(qdev->ddev, qdev->ddev->pdev->irq); |
1906 |
qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; |
1907 |
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c |
1908 |
-index 9534127..3fbab8c 100644 |
1909 |
+index 9534127..1d17b3f 100644 |
1910 |
--- a/drivers/gpu/drm/qxl/qxl_ttm.c |
1911 |
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c |
1912 |
@@ -103,7 +103,7 @@ static void qxl_ttm_global_fini(struct qxl_device *qdev) |
1913 |
@@ -47416,8 +47436,8 @@ index 9534127..3fbab8c 100644 |
1914 |
- else |
1915 |
- qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_PRIV0].priv; |
1916 |
+ pax_open_kernel(); |
1917 |
-+ *(void **)&qxl_mem_types_list[0].data = qdev->mman.bdev.man[TTM_PL_VRAM].priv; |
1918 |
-+ *(void **)&qxl_mem_types_list[1].data = qdev->mman.bdev.man[TTM_PL_PRIV0].priv; |
1919 |
++ const_cast(qxl_mem_types_list[0].data) = qdev->mman.bdev.man[TTM_PL_VRAM].priv; |
1920 |
++ const_cast(qxl_mem_types_list[1].data) = qdev->mman.bdev.man[TTM_PL_PRIV0].priv; |
1921 |
+ pax_close_kernel(); |
1922 |
|
1923 |
- } |
1924 |
@@ -47440,7 +47460,7 @@ index 14fd83b5f..b2acbd19 100644 |
1925 |
/* We don't support anything other than bus-mastering ring mode, |
1926 |
* but the ring can be in either AGP or PCI space for the ring |
1927 |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c |
1928 |
-index c57b4de..2614d79 100644 |
1929 |
+index c57b4de..1a875fb 100644 |
1930 |
--- a/drivers/gpu/drm/r128/r128_drv.c |
1931 |
+++ b/drivers/gpu/drm/r128/r128_drv.c |
1932 |
@@ -94,7 +94,9 @@ static struct pci_driver r128_pci_driver = { |
1933 |
@@ -47449,7 +47469,7 @@ index c57b4de..2614d79 100644 |
1934 |
{ |
1935 |
- driver.num_ioctls = r128_max_ioctl; |
1936 |
+ pax_open_kernel(); |
1937 |
-+ *(int *)&driver.num_ioctls = r128_max_ioctl; |
1938 |
++ const_cast(driver.num_ioctls) = r128_max_ioctl; |
1939 |
+ pax_close_kernel(); |
1940 |
|
1941 |
return drm_pci_init(&driver, &r128_pci_driver); |
1942 |
@@ -47659,7 +47679,7 @@ index 4197ca1..f07709e 100644 |
1943 |
|
1944 |
static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { |
1945 |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c |
1946 |
-index e266ffc..0392d08 100644 |
1947 |
+index e266ffc..e510e3f 100644 |
1948 |
--- a/drivers/gpu/drm/radeon/radeon_drv.c |
1949 |
+++ b/drivers/gpu/drm/radeon/radeon_drv.c |
1950 |
@@ -130,7 +130,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int crtc, |
1951 |
@@ -47688,7 +47708,7 @@ index e266ffc..0392d08 100644 |
1952 |
- driver->num_ioctls = radeon_max_kms_ioctl; |
1953 |
+ |
1954 |
+ pax_open_kernel(); |
1955 |
-+ *(int *)&driver->num_ioctls = radeon_max_kms_ioctl; |
1956 |
++ const_cast(driver->num_ioctls) = radeon_max_kms_ioctl; |
1957 |
+ pax_close_kernel(); |
1958 |
+ |
1959 |
radeon_register_atpx_handler(); |
1960 |
@@ -47808,7 +47828,7 @@ index d47dff9..0752202 100644 |
1961 |
-int savage_max_ioctl = ARRAY_SIZE(savage_ioctls); |
1962 |
+const int savage_max_ioctl = ARRAY_SIZE(savage_ioctls); |
1963 |
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c |
1964 |
-index 21aed1f..5db7419 100644 |
1965 |
+index 21aed1f..85d23a0 100644 |
1966 |
--- a/drivers/gpu/drm/savage/savage_drv.c |
1967 |
+++ b/drivers/gpu/drm/savage/savage_drv.c |
1968 |
@@ -76,7 +76,10 @@ static struct pci_driver savage_pci_driver = { |
1969 |
@@ -47817,7 +47837,7 @@ index 21aed1f..5db7419 100644 |
1970 |
{ |
1971 |
- driver.num_ioctls = savage_max_ioctl; |
1972 |
+ pax_open_kernel(); |
1973 |
-+ *(int *)&driver.num_ioctls = savage_max_ioctl; |
1974 |
++ const_cast(driver.num_ioctls) = savage_max_ioctl; |
1975 |
+ pax_close_kernel(); |
1976 |
+ |
1977 |
return drm_pci_init(&driver, &savage_pci_driver); |
1978 |
@@ -47837,7 +47857,7 @@ index 37b6995..9b31aaf 100644 |
1979 |
#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) |
1980 |
|
1981 |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c |
1982 |
-index 79bce76..4fd9a20 100644 |
1983 |
+index 79bce76..6c02219 100644 |
1984 |
--- a/drivers/gpu/drm/sis/sis_drv.c |
1985 |
+++ b/drivers/gpu/drm/sis/sis_drv.c |
1986 |
@@ -128,7 +128,10 @@ static struct pci_driver sis_pci_driver = { |
1987 |
@@ -47846,7 +47866,7 @@ index 79bce76..4fd9a20 100644 |
1988 |
{ |
1989 |
- driver.num_ioctls = sis_max_ioctl; |
1990 |
+ pax_open_kernel(); |
1991 |
-+ *(int *)&driver.num_ioctls = sis_max_ioctl; |
1992 |
++ const_cast(driver.num_ioctls) = sis_max_ioctl; |
1993 |
+ pax_close_kernel(); |
1994 |
+ |
1995 |
return drm_pci_init(&driver, &sis_pci_driver); |
1996 |
@@ -47875,7 +47895,7 @@ index 93ad8a5..48f0a57 100644 |
1997 |
-int sis_max_ioctl = ARRAY_SIZE(sis_ioctls); |
1998 |
+const int sis_max_ioctl = ARRAY_SIZE(sis_ioctls); |
1999 |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c |
2000 |
-index dde6f20..1969ca6 100644 |
2001 |
+index dde6f20..a74f8b9 100644 |
2002 |
--- a/drivers/gpu/drm/tegra/dc.c |
2003 |
+++ b/drivers/gpu/drm/tegra/dc.c |
2004 |
@@ -1657,7 +1657,7 @@ static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor) |
2005 |
@@ -47883,7 +47903,7 @@ index dde6f20..1969ca6 100644 |
2006 |
|
2007 |
for (i = 0; i < ARRAY_SIZE(debugfs_files); i++) |
2008 |
- dc->debugfs_files[i].data = dc; |
2009 |
-+ *(void **)&dc->debugfs_files[i].data = dc; |
2010 |
++ const_cast(dc->debugfs_files[i].data) = dc; |
2011 |
|
2012 |
err = drm_debugfs_create_files(dc->debugfs_files, |
2013 |
ARRAY_SIZE(debugfs_files), |
2014 |
@@ -47914,7 +47934,7 @@ index b7ef492..8968507 100644 |
2015 |
struct dentry *debugfs; |
2016 |
}; |
2017 |
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c |
2018 |
-index 757c6e8..710a6ff 100644 |
2019 |
+index 757c6e8..36532d6 100644 |
2020 |
--- a/drivers/gpu/drm/tegra/sor.c |
2021 |
+++ b/drivers/gpu/drm/tegra/sor.c |
2022 |
@@ -1003,8 +1003,11 @@ static int tegra_sor_debugfs_init(struct tegra_sor *sor, |
2023 |
@@ -47925,7 +47945,7 @@ index 757c6e8..710a6ff 100644 |
2024 |
- sor->debugfs_files[i].data = sor; |
2025 |
+ for (i = 0; i < ARRAY_SIZE(debugfs_files); i++) { |
2026 |
+ pax_open_kernel(); |
2027 |
-+ *(void **)&sor->debugfs_files[i].data = sor; |
2028 |
++ const_cast(sor->debugfs_files[i].data) = sor; |
2029 |
+ pax_close_kernel(); |
2030 |
+ } |
2031 |
|
2032 |
@@ -48205,7 +48225,7 @@ index d17d8f2..67e8e48b 100644 |
2033 |
-int via_max_ioctl = ARRAY_SIZE(via_ioctls); |
2034 |
+const int via_max_ioctl = ARRAY_SIZE(via_ioctls); |
2035 |
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c |
2036 |
-index ed8aa8f..16c84fc 100644 |
2037 |
+index ed8aa8f..114cc8d 100644 |
2038 |
--- a/drivers/gpu/drm/via/via_drv.c |
2039 |
+++ b/drivers/gpu/drm/via/via_drv.c |
2040 |
@@ -107,7 +107,10 @@ static struct pci_driver via_pci_driver = { |
2041 |
@@ -48214,7 +48234,7 @@ index ed8aa8f..16c84fc 100644 |
2042 |
{ |
2043 |
- driver.num_ioctls = via_max_ioctl; |
2044 |
+ pax_open_kernel(); |
2045 |
-+ *(int *)&driver.num_ioctls = via_max_ioctl; |
2046 |
++ const_cast(driver.num_ioctls) = via_max_ioctl; |
2047 |
+ pax_close_kernel(); |
2048 |
+ |
2049 |
via_init_command_verifier(); |
2050 |
@@ -49094,7 +49114,7 @@ index d127ace..6ee866f 100644 |
2051 |
int i, j = 1; |
2052 |
|
2053 |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c |
2054 |
-index 146eed70b..7679efd 100644 |
2055 |
+index 146eed70b..7312f08 100644 |
2056 |
--- a/drivers/idle/intel_idle.c |
2057 |
+++ b/drivers/idle/intel_idle.c |
2058 |
@@ -1060,8 +1060,10 @@ static void sklh_idle_state_table_update(void) |
2059 |
@@ -49104,8 +49124,8 @@ index 146eed70b..7679efd 100644 |
2060 |
- skl_cstates[5].disabled = 1; /* C8-SKL */ |
2061 |
- skl_cstates[6].disabled = 1; /* C9-SKL */ |
2062 |
+ pax_open_kernel(); |
2063 |
-+ *(bool *)&skl_cstates[5].disabled = 1; /* C8-SKL */ |
2064 |
-+ *(bool *)&skl_cstates[6].disabled = 1; /* C9-SKL */ |
2065 |
++ const_cast(skl_cstates[5].disabled) = 1; /* C8-SKL */ |
2066 |
++ const_cast(skl_cstates[6].disabled) = 1; /* C9-SKL */ |
2067 |
+ pax_close_kernel(); |
2068 |
} |
2069 |
/* |
2070 |
@@ -50103,18 +50123,6 @@ index 8c4daf7..77a87ab 100644 |
2071 |
nesqp->destroyed = 1; |
2072 |
|
2073 |
/* Blow away the connection if it exists. */ |
2074 |
-diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h |
2075 |
-index 7df16f7..7e1b21e 100644 |
2076 |
---- a/drivers/infiniband/hw/qib/qib.h |
2077 |
-+++ b/drivers/infiniband/hw/qib/qib.h |
2078 |
-@@ -52,6 +52,7 @@ |
2079 |
- #include <linux/kref.h> |
2080 |
- #include <linux/sched.h> |
2081 |
- #include <linux/kthread.h> |
2082 |
-+#include <linux/slab.h> |
2083 |
- |
2084 |
- #include "qib_common.h" |
2085 |
- #include "qib_verbs.h" |
2086 |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c |
2087 |
index 6c8ff10..73cfbb6 100644 |
2088 |
--- a/drivers/infiniband/hw/qib/qib_iba7322.c |
2089 |
@@ -50492,7 +50500,7 @@ index 2087534..c3f6b6c 100644 |
2090 |
return -ENOMEM; |
2091 |
|
2092 |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c |
2093 |
-index 59ee4b8..6632759 100644 |
2094 |
+index 59ee4b8..e4b6234 100644 |
2095 |
--- a/drivers/iommu/arm-smmu.c |
2096 |
+++ b/drivers/iommu/arm-smmu.c |
2097 |
@@ -341,7 +341,7 @@ enum arm_smmu_domain_stage { |
2098 |
@@ -50528,7 +50536,7 @@ index 59ee4b8..6632759 100644 |
2099 |
/* Update our support page sizes to reflect the page table format */ |
2100 |
- arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; |
2101 |
+ pax_open_kernel(); |
2102 |
-+ *(unsigned long *)&arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; |
2103 |
++ const_cast(arm_smmu_ops.pgsize_bitmap) = pgtbl_cfg.pgsize_bitmap; |
2104 |
+ pax_close_kernel(); |
2105 |
|
2106 |
/* Initialise the context bank with our page table cfg */ |
2107 |
@@ -50630,7 +50638,7 @@ index 59ee4b8..6632759 100644 |
2108 |
|
2109 |
- arm_smmu_ops.pgsize_bitmap &= size; |
2110 |
+ pax_open_kernel(); |
2111 |
-+ *(unsigned long *)&arm_smmu_ops.pgsize_bitmap &= size; |
2112 |
++ const_cast(arm_smmu_ops.pgsize_bitmap) &= size; |
2113 |
+ pax_close_kernel(); |
2114 |
dev_notice(smmu->dev, "\tSupported page sizes: 0x%08lx\n", size); |
2115 |
|
2116 |
@@ -51582,7 +51590,7 @@ index fef6586..22353ff 100644 |
2117 |
} else if ((DIDD_Table[x].type > 0) |
2118 |
&& (DIDD_Table[x].type < 16)) { /* IDI Adapter found */ |
2119 |
diff --git a/drivers/isdn/hardware/eicon/mntfunc.c b/drivers/isdn/hardware/eicon/mntfunc.c |
2120 |
-index 1cd9aff..1a3e2b6 100644 |
2121 |
+index 1cd9aff..3775d52 100644 |
2122 |
--- a/drivers/isdn/hardware/eicon/mntfunc.c |
2123 |
+++ b/drivers/isdn/hardware/eicon/mntfunc.c |
2124 |
@@ -26,8 +26,13 @@ extern void DIVA_DIDD_Read(void *, int); |
2125 |
@@ -51592,7 +51600,7 @@ index 1cd9aff..1a3e2b6 100644 |
2126 |
+ |
2127 |
+static void didd_nothing(ENTITY IDI_CALL_ENTITY_T *e) |
2128 |
+{ |
2129 |
-+ diva_maint_prtComp(e); |
2130 |
++ diva_maint_prtComp((char *)e); |
2131 |
+} |
2132 |
static DESCRIPTOR MaintDescriptor = |
2133 |
-{ IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp }; |
2134 |
@@ -52967,10 +52975,50 @@ index 6b420a5..d5acb8f 100644 |
2135 |
|
2136 |
struct gc_stat { |
2137 |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c |
2138 |
-index 22b9e34..ac456ec 100644 |
2139 |
+index 22b9e34..d8406e7 100644 |
2140 |
--- a/drivers/md/bcache/btree.c |
2141 |
+++ b/drivers/md/bcache/btree.c |
2142 |
-@@ -468,7 +468,7 @@ void __bch_btree_node_write(struct btree *b, struct closure *parent) |
2143 |
+@@ -337,15 +337,17 @@ static void btree_complete_write(struct btree *b, struct btree_write *w) |
2144 |
+ w->journal = NULL; |
2145 |
+ } |
2146 |
+ |
2147 |
+-static void btree_node_write_unlock(struct closure *cl) |
2148 |
++static void btree_node_write_unlock(struct work_struct *work) |
2149 |
+ { |
2150 |
++ struct closure *cl = container_of(work, struct closure, work); |
2151 |
+ struct btree *b = container_of(cl, struct btree, io); |
2152 |
+ |
2153 |
+ up(&b->io_mutex); |
2154 |
+ } |
2155 |
+ |
2156 |
+-static void __btree_node_write_done(struct closure *cl) |
2157 |
++static void __btree_node_write_done(struct work_struct *work) |
2158 |
+ { |
2159 |
++ struct closure *cl = container_of(work, struct closure, work); |
2160 |
+ struct btree *b = container_of(cl, struct btree, io); |
2161 |
+ struct btree_write *w = btree_prev_write(b); |
2162 |
+ |
2163 |
+@@ -359,8 +361,9 @@ static void __btree_node_write_done(struct closure *cl) |
2164 |
+ closure_return_with_destructor(cl, btree_node_write_unlock); |
2165 |
+ } |
2166 |
+ |
2167 |
+-static void btree_node_write_done(struct closure *cl) |
2168 |
++static void btree_node_write_done(struct work_struct *work) |
2169 |
+ { |
2170 |
++ struct closure *cl = container_of(work, struct closure, work); |
2171 |
+ struct btree *b = container_of(cl, struct btree, io); |
2172 |
+ struct bio_vec *bv; |
2173 |
+ int n; |
2174 |
+@@ -368,7 +371,7 @@ static void btree_node_write_done(struct closure *cl) |
2175 |
+ bio_for_each_segment_all(bv, b->bio, n) |
2176 |
+ __free_page(bv->bv_page); |
2177 |
+ |
2178 |
+- __btree_node_write_done(cl); |
2179 |
++ __btree_node_write_done(&cl->work); |
2180 |
+ } |
2181 |
+ |
2182 |
+ static void btree_node_write_endio(struct bio *bio) |
2183 |
+@@ -468,7 +471,7 @@ void __bch_btree_node_write(struct btree *b, struct closure *parent) |
2184 |
|
2185 |
do_btree_node_write(b); |
2186 |
|
2187 |
@@ -52979,12 +53027,44 @@ index 22b9e34..ac456ec 100644 |
2188 |
&PTR_CACHE(b->c, &b->key, 0)->btree_sectors_written); |
2189 |
|
2190 |
b->written += set_blocks(i, block_bytes(b->c)); |
2191 |
+diff --git a/drivers/md/bcache/closure.c b/drivers/md/bcache/closure.c |
2192 |
+index 9eaf1d6..86e6fa1 100644 |
2193 |
+--- a/drivers/md/bcache/closure.c |
2194 |
++++ b/drivers/md/bcache/closure.c |
2195 |
+@@ -29,12 +29,12 @@ static inline void closure_put_after_sub(struct closure *cl, int flags) |
2196 |
+ closure_queue(cl); |
2197 |
+ } else { |
2198 |
+ struct closure *parent = cl->parent; |
2199 |
+- closure_fn *destructor = cl->fn; |
2200 |
++ work_func_t destructor = cl->fn; |
2201 |
+ |
2202 |
+ closure_debug_destroy(cl); |
2203 |
+ |
2204 |
+ if (destructor) |
2205 |
+- destructor(cl); |
2206 |
++ destructor(&cl->work); |
2207 |
+ |
2208 |
+ if (parent) |
2209 |
+ closure_put(parent); |
2210 |
diff --git a/drivers/md/bcache/closure.h b/drivers/md/bcache/closure.h |
2211 |
-index 782cc2c..4fdd593 100644 |
2212 |
+index 782cc2c..34864f4 100644 |
2213 |
--- a/drivers/md/bcache/closure.h |
2214 |
+++ b/drivers/md/bcache/closure.h |
2215 |
-@@ -238,7 +238,7 @@ static inline void closure_set_stopped(struct closure *cl) |
2216 |
- static inline void set_closure_fn(struct closure *cl, closure_fn *fn, |
2217 |
+@@ -151,7 +151,7 @@ struct closure { |
2218 |
+ struct workqueue_struct *wq; |
2219 |
+ struct task_struct *task; |
2220 |
+ struct llist_node list; |
2221 |
+- closure_fn *fn; |
2222 |
++ work_func_t fn; |
2223 |
+ }; |
2224 |
+ struct work_struct work; |
2225 |
+ }; |
2226 |
+@@ -235,10 +235,10 @@ static inline void closure_set_stopped(struct closure *cl) |
2227 |
+ atomic_sub(CLOSURE_RUNNING, &cl->remaining); |
2228 |
+ } |
2229 |
+ |
2230 |
+-static inline void set_closure_fn(struct closure *cl, closure_fn *fn, |
2231 |
++static inline void set_closure_fn(struct closure *cl, work_func_t fn, |
2232 |
struct workqueue_struct *wq) |
2233 |
{ |
2234 |
- BUG_ON(object_is_on_stack(cl)); |
2235 |
@@ -52992,6 +53072,24 @@ index 782cc2c..4fdd593 100644 |
2236 |
closure_set_ip(cl); |
2237 |
cl->fn = fn; |
2238 |
cl->wq = wq; |
2239 |
+@@ -253,7 +253,7 @@ static inline void closure_queue(struct closure *cl) |
2240 |
+ INIT_WORK(&cl->work, cl->work.func); |
2241 |
+ BUG_ON(!queue_work(wq, &cl->work)); |
2242 |
+ } else |
2243 |
+- cl->fn(cl); |
2244 |
++ cl->fn(&cl->work); |
2245 |
+ } |
2246 |
+ |
2247 |
+ /** |
2248 |
+@@ -372,7 +372,7 @@ do { \ |
2249 |
+ * asynchronously out of a new closure - @parent will then wait for @cl to |
2250 |
+ * finish. |
2251 |
+ */ |
2252 |
+-static inline void closure_call(struct closure *cl, closure_fn fn, |
2253 |
++static inline void closure_call(struct closure *cl, work_func_t fn, |
2254 |
+ struct workqueue_struct *wq, |
2255 |
+ struct closure *parent) |
2256 |
+ { |
2257 |
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c |
2258 |
index 86a0bb8..0832b32 100644 |
2259 |
--- a/drivers/md/bcache/io.c |
2260 |
@@ -53035,10 +53133,46 @@ index 86a0bb8..0832b32 100644 |
2261 |
errors >>= IO_ERROR_SHIFT; |
2262 |
|
2263 |
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c |
2264 |
-index 29eba72..348efc9 100644 |
2265 |
+index 29eba72..1d0108a 100644 |
2266 |
--- a/drivers/md/bcache/journal.c |
2267 |
+++ b/drivers/md/bcache/journal.c |
2268 |
-@@ -621,7 +621,7 @@ static void journal_write_unlocked(struct closure *cl) |
2269 |
+@@ -555,10 +555,11 @@ static void journal_write_endio(struct bio *bio) |
2270 |
+ closure_put(&w->c->journal.io); |
2271 |
+ } |
2272 |
+ |
2273 |
+-static void journal_write(struct closure *); |
2274 |
++static void journal_write(struct work_struct *); |
2275 |
+ |
2276 |
+-static void journal_write_done(struct closure *cl) |
2277 |
++static void journal_write_done(struct work_struct *work) |
2278 |
+ { |
2279 |
++ struct closure *cl = container_of(work, struct closure, work); |
2280 |
+ struct journal *j = container_of(cl, struct journal, io); |
2281 |
+ struct journal_write *w = (j->cur == j->w) |
2282 |
+ ? &j->w[1] |
2283 |
+@@ -568,17 +569,19 @@ static void journal_write_done(struct closure *cl) |
2284 |
+ continue_at_nobarrier(cl, journal_write, system_wq); |
2285 |
+ } |
2286 |
+ |
2287 |
+-static void journal_write_unlock(struct closure *cl) |
2288 |
++static void journal_write_unlock(struct work_struct *work) |
2289 |
+ { |
2290 |
++ struct closure *cl = container_of(work, struct closure, work); |
2291 |
+ struct cache_set *c = container_of(cl, struct cache_set, journal.io); |
2292 |
+ |
2293 |
+ c->journal.io_in_flight = 0; |
2294 |
+ spin_unlock(&c->journal.lock); |
2295 |
+ } |
2296 |
+ |
2297 |
+-static void journal_write_unlocked(struct closure *cl) |
2298 |
++static void journal_write_unlocked(struct work_struct *work) |
2299 |
+ __releases(c->journal.lock) |
2300 |
+ { |
2301 |
++ struct closure *cl = container_of(work, struct closure, work); |
2302 |
+ struct cache_set *c = container_of(cl, struct cache_set, journal.io); |
2303 |
+ struct cache *ca; |
2304 |
+ struct journal_write *w = c->journal.cur; |
2305 |
+@@ -621,7 +624,7 @@ static void journal_write_unlocked(struct closure *cl) |
2306 |
ca = PTR_CACHE(c, k, i); |
2307 |
bio = &ca->journal.bio; |
2308 |
|
2309 |
@@ -53047,6 +53181,278 @@ index 29eba72..348efc9 100644 |
2310 |
|
2311 |
bio_reset(bio); |
2312 |
bio->bi_iter.bi_sector = PTR_OFFSET(k, i); |
2313 |
+@@ -653,12 +656,13 @@ static void journal_write_unlocked(struct closure *cl) |
2314 |
+ continue_at(cl, journal_write_done, NULL); |
2315 |
+ } |
2316 |
+ |
2317 |
+-static void journal_write(struct closure *cl) |
2318 |
++static void journal_write(struct work_struct *work) |
2319 |
+ { |
2320 |
++ struct closure *cl = container_of(work, struct closure, work); |
2321 |
+ struct cache_set *c = container_of(cl, struct cache_set, journal.io); |
2322 |
+ |
2323 |
+ spin_lock(&c->journal.lock); |
2324 |
+- journal_write_unlocked(cl); |
2325 |
++ journal_write_unlocked(&cl->work); |
2326 |
+ } |
2327 |
+ |
2328 |
+ static void journal_try_write(struct cache_set *c) |
2329 |
+diff --git a/drivers/md/bcache/movinggc.c b/drivers/md/bcache/movinggc.c |
2330 |
+index b929fc9..4557031 100644 |
2331 |
+--- a/drivers/md/bcache/movinggc.c |
2332 |
++++ b/drivers/md/bcache/movinggc.c |
2333 |
+@@ -34,14 +34,16 @@ static bool moving_pred(struct keybuf *buf, struct bkey *k) |
2334 |
+ |
2335 |
+ /* Moving GC - IO loop */ |
2336 |
+ |
2337 |
+-static void moving_io_destructor(struct closure *cl) |
2338 |
++static void moving_io_destructor(struct work_struct *work) |
2339 |
+ { |
2340 |
++ struct closure *cl = container_of(work, struct closure, work); |
2341 |
+ struct moving_io *io = container_of(cl, struct moving_io, cl); |
2342 |
+ kfree(io); |
2343 |
+ } |
2344 |
+ |
2345 |
+-static void write_moving_finish(struct closure *cl) |
2346 |
++static void write_moving_finish(struct work_struct *work) |
2347 |
+ { |
2348 |
++ struct closure *cl = container_of(work, struct closure, work); |
2349 |
+ struct moving_io *io = container_of(cl, struct moving_io, cl); |
2350 |
+ struct bio *bio = &io->bio.bio; |
2351 |
+ struct bio_vec *bv; |
2352 |
+@@ -92,8 +94,9 @@ static void moving_init(struct moving_io *io) |
2353 |
+ bch_bio_map(bio, NULL); |
2354 |
+ } |
2355 |
+ |
2356 |
+-static void write_moving(struct closure *cl) |
2357 |
++static void write_moving(struct work_struct *work) |
2358 |
+ { |
2359 |
++ struct closure *cl = container_of(work, struct closure, work); |
2360 |
+ struct moving_io *io = container_of(cl, struct moving_io, cl); |
2361 |
+ struct data_insert_op *op = &io->op; |
2362 |
+ |
2363 |
+@@ -116,8 +119,9 @@ static void write_moving(struct closure *cl) |
2364 |
+ continue_at(cl, write_moving_finish, op->wq); |
2365 |
+ } |
2366 |
+ |
2367 |
+-static void read_moving_submit(struct closure *cl) |
2368 |
++static void read_moving_submit(struct work_struct *work) |
2369 |
+ { |
2370 |
++ struct closure *cl = container_of(work, struct closure, work); |
2371 |
+ struct moving_io *io = container_of(cl, struct moving_io, cl); |
2372 |
+ struct bio *bio = &io->bio.bio; |
2373 |
+ |
2374 |
+diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c |
2375 |
+index 25fa844..8181a97 100644 |
2376 |
+--- a/drivers/md/bcache/request.c |
2377 |
++++ b/drivers/md/bcache/request.c |
2378 |
+@@ -24,7 +24,7 @@ |
2379 |
+ |
2380 |
+ struct kmem_cache *bch_search_cache; |
2381 |
+ |
2382 |
+-static void bch_data_insert_start(struct closure *); |
2383 |
++static void bch_data_insert_start(struct work_struct *); |
2384 |
+ |
2385 |
+ static unsigned cache_mode(struct cached_dev *dc, struct bio *bio) |
2386 |
+ { |
2387 |
+@@ -53,8 +53,9 @@ static void bio_csum(struct bio *bio, struct bkey *k) |
2388 |
+ |
2389 |
+ /* Insert data into cache */ |
2390 |
+ |
2391 |
+-static void bch_data_insert_keys(struct closure *cl) |
2392 |
++static void bch_data_insert_keys(struct work_struct *work) |
2393 |
+ { |
2394 |
++ struct closure *cl = container_of(work, struct closure, work); |
2395 |
+ struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); |
2396 |
+ atomic_t *journal_ref = NULL; |
2397 |
+ struct bkey *replace_key = op->replace ? &op->replace_key : NULL; |
2398 |
+@@ -143,8 +144,9 @@ out: |
2399 |
+ continue_at(cl, bch_data_insert_keys, op->wq); |
2400 |
+ } |
2401 |
+ |
2402 |
+-static void bch_data_insert_error(struct closure *cl) |
2403 |
++static void bch_data_insert_error(struct work_struct *work) |
2404 |
+ { |
2405 |
++ struct closure *cl = container_of(work, struct closure, work); |
2406 |
+ struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); |
2407 |
+ |
2408 |
+ /* |
2409 |
+@@ -170,7 +172,7 @@ static void bch_data_insert_error(struct closure *cl) |
2410 |
+ |
2411 |
+ op->insert_keys.top = dst; |
2412 |
+ |
2413 |
+- bch_data_insert_keys(cl); |
2414 |
++ bch_data_insert_keys(&cl->work); |
2415 |
+ } |
2416 |
+ |
2417 |
+ static void bch_data_insert_endio(struct bio *bio) |
2418 |
+@@ -191,8 +193,9 @@ static void bch_data_insert_endio(struct bio *bio) |
2419 |
+ bch_bbio_endio(op->c, bio, bio->bi_error, "writing data to cache"); |
2420 |
+ } |
2421 |
+ |
2422 |
+-static void bch_data_insert_start(struct closure *cl) |
2423 |
++static void bch_data_insert_start(struct work_struct *work) |
2424 |
+ { |
2425 |
++ struct closure *cl = container_of(work, struct closure, work); |
2426 |
+ struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); |
2427 |
+ struct bio *bio = op->bio, *n; |
2428 |
+ |
2429 |
+@@ -313,8 +316,9 @@ err: |
2430 |
+ * If s->bypass is true, instead of inserting the data it invalidates the |
2431 |
+ * region of the cache represented by s->cache_bio and op->inode. |
2432 |
+ */ |
2433 |
+-void bch_data_insert(struct closure *cl) |
2434 |
++void bch_data_insert(struct work_struct *work) |
2435 |
+ { |
2436 |
++ struct closure *cl = container_of(work, struct closure, work); |
2437 |
+ struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); |
2438 |
+ |
2439 |
+ trace_bcache_write(op->c, op->inode, op->bio, |
2440 |
+@@ -322,7 +326,7 @@ void bch_data_insert(struct closure *cl) |
2441 |
+ |
2442 |
+ bch_keylist_init(&op->insert_keys); |
2443 |
+ bio_get(op->bio); |
2444 |
+- bch_data_insert_start(cl); |
2445 |
++ bch_data_insert_start(&cl->work); |
2446 |
+ } |
2447 |
+ |
2448 |
+ /* Congested? */ |
2449 |
+@@ -570,8 +574,9 @@ static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k) |
2450 |
+ return n == bio ? MAP_DONE : MAP_CONTINUE; |
2451 |
+ } |
2452 |
+ |
2453 |
+-static void cache_lookup(struct closure *cl) |
2454 |
++static void cache_lookup(struct work_struct *work) |
2455 |
+ { |
2456 |
++ struct closure *cl = container_of(work, struct closure, work); |
2457 |
+ struct search *s = container_of(cl, struct search, iop.cl); |
2458 |
+ struct bio *bio = &s->bio.bio; |
2459 |
+ int ret; |
2460 |
+@@ -631,8 +636,9 @@ static void do_bio_hook(struct search *s, struct bio *orig_bio) |
2461 |
+ bio_cnt_set(bio, 3); |
2462 |
+ } |
2463 |
+ |
2464 |
+-static void search_free(struct closure *cl) |
2465 |
++static void search_free(struct work_struct *work) |
2466 |
+ { |
2467 |
++ struct closure *cl = container_of(work, struct closure, work); |
2468 |
+ struct search *s = container_of(cl, struct search, cl); |
2469 |
+ bio_complete(s); |
2470 |
+ |
2471 |
+@@ -676,19 +682,21 @@ static inline struct search *search_alloc(struct bio *bio, |
2472 |
+ |
2473 |
+ /* Cached devices */ |
2474 |
+ |
2475 |
+-static void cached_dev_bio_complete(struct closure *cl) |
2476 |
++static void cached_dev_bio_complete(struct work_struct *work) |
2477 |
+ { |
2478 |
++ struct closure *cl = container_of(work, struct closure, work); |
2479 |
+ struct search *s = container_of(cl, struct search, cl); |
2480 |
+ struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
2481 |
+ |
2482 |
+- search_free(cl); |
2483 |
++ search_free(&cl->work); |
2484 |
+ cached_dev_put(dc); |
2485 |
+ } |
2486 |
+ |
2487 |
+ /* Process reads */ |
2488 |
+ |
2489 |
+-static void cached_dev_cache_miss_done(struct closure *cl) |
2490 |
++static void cached_dev_cache_miss_done(struct work_struct *work) |
2491 |
+ { |
2492 |
++ struct closure *cl = container_of(work, struct closure, work); |
2493 |
+ struct search *s = container_of(cl, struct search, cl); |
2494 |
+ |
2495 |
+ if (s->iop.replace_collision) |
2496 |
+@@ -702,11 +710,12 @@ static void cached_dev_cache_miss_done(struct closure *cl) |
2497 |
+ __free_page(bv->bv_page); |
2498 |
+ } |
2499 |
+ |
2500 |
+- cached_dev_bio_complete(cl); |
2501 |
++ cached_dev_bio_complete(&cl->work); |
2502 |
+ } |
2503 |
+ |
2504 |
+-static void cached_dev_read_error(struct closure *cl) |
2505 |
++static void cached_dev_read_error(struct work_struct *work) |
2506 |
+ { |
2507 |
++ struct closure *cl = container_of(work, struct closure, work); |
2508 |
+ struct search *s = container_of(cl, struct search, cl); |
2509 |
+ struct bio *bio = &s->bio.bio; |
2510 |
+ |
2511 |
+@@ -725,8 +734,9 @@ static void cached_dev_read_error(struct closure *cl) |
2512 |
+ continue_at(cl, cached_dev_cache_miss_done, NULL); |
2513 |
+ } |
2514 |
+ |
2515 |
+-static void cached_dev_read_done(struct closure *cl) |
2516 |
++static void cached_dev_read_done(struct work_struct *work) |
2517 |
+ { |
2518 |
++ struct closure *cl = container_of(work, struct closure, work); |
2519 |
+ struct search *s = container_of(cl, struct search, cl); |
2520 |
+ struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
2521 |
+ |
2522 |
+@@ -765,8 +775,9 @@ static void cached_dev_read_done(struct closure *cl) |
2523 |
+ continue_at(cl, cached_dev_cache_miss_done, NULL); |
2524 |
+ } |
2525 |
+ |
2526 |
+-static void cached_dev_read_done_bh(struct closure *cl) |
2527 |
++static void cached_dev_read_done_bh(struct work_struct *work) |
2528 |
+ { |
2529 |
++ struct closure *cl = container_of(work, struct closure, work); |
2530 |
+ struct search *s = container_of(cl, struct search, cl); |
2531 |
+ struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
2532 |
+ |
2533 |
+@@ -864,13 +875,14 @@ static void cached_dev_read(struct cached_dev *dc, struct search *s) |
2534 |
+ |
2535 |
+ /* Process writes */ |
2536 |
+ |
2537 |
+-static void cached_dev_write_complete(struct closure *cl) |
2538 |
++static void cached_dev_write_complete(struct work_struct *work) |
2539 |
+ { |
2540 |
++ struct closure *cl = container_of(work, struct closure, work); |
2541 |
+ struct search *s = container_of(cl, struct search, cl); |
2542 |
+ struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
2543 |
+ |
2544 |
+ up_read_non_owner(&dc->writeback_lock); |
2545 |
+- cached_dev_bio_complete(cl); |
2546 |
++ cached_dev_bio_complete(&cl->work); |
2547 |
+ } |
2548 |
+ |
2549 |
+ static void cached_dev_write(struct cached_dev *dc, struct search *s) |
2550 |
+@@ -942,8 +954,9 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s) |
2551 |
+ continue_at(cl, cached_dev_write_complete, NULL); |
2552 |
+ } |
2553 |
+ |
2554 |
+-static void cached_dev_nodata(struct closure *cl) |
2555 |
++static void cached_dev_nodata(struct work_struct *work) |
2556 |
+ { |
2557 |
++ struct closure *cl = container_of(work, struct closure, work); |
2558 |
+ struct search *s = container_of(cl, struct search, cl); |
2559 |
+ struct bio *bio = &s->bio.bio; |
2560 |
+ |
2561 |
+@@ -1063,8 +1076,9 @@ static int flash_dev_cache_miss(struct btree *b, struct search *s, |
2562 |
+ return MAP_CONTINUE; |
2563 |
+ } |
2564 |
+ |
2565 |
+-static void flash_dev_nodata(struct closure *cl) |
2566 |
++static void flash_dev_nodata(struct work_struct *work) |
2567 |
+ { |
2568 |
++ struct closure *cl = container_of(work, struct closure, work); |
2569 |
+ struct search *s = container_of(cl, struct search, cl); |
2570 |
+ |
2571 |
+ if (s->iop.flush_journal) |
2572 |
+diff --git a/drivers/md/bcache/request.h b/drivers/md/bcache/request.h |
2573 |
+index 1ff3687..b8f4a05 100644 |
2574 |
+--- a/drivers/md/bcache/request.h |
2575 |
++++ b/drivers/md/bcache/request.h |
2576 |
+@@ -33,7 +33,7 @@ struct data_insert_op { |
2577 |
+ }; |
2578 |
+ |
2579 |
+ unsigned bch_get_congested(struct cache_set *); |
2580 |
+-void bch_data_insert(struct closure *cl); |
2581 |
++void bch_data_insert(struct work_struct *work); |
2582 |
+ |
2583 |
+ void bch_cached_dev_request_init(struct cached_dev *dc); |
2584 |
+ void bch_flash_dev_request_init(struct bcache_device *d); |
2585 |
diff --git a/drivers/md/bcache/stats.c b/drivers/md/bcache/stats.c |
2586 |
index 0ca072c..5e6e5c3 100644 |
2587 |
--- a/drivers/md/bcache/stats.c |
2588 |
@@ -53161,10 +53567,43 @@ index adbff14..018c2d2 100644 |
2589 |
struct cache_stat_collector collector; |
2590 |
|
2591 |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c |
2592 |
-index a296425..397607e 100644 |
2593 |
+index a296425..c5d881c 100644 |
2594 |
--- a/drivers/md/bcache/super.c |
2595 |
+++ b/drivers/md/bcache/super.c |
2596 |
-@@ -530,7 +530,7 @@ void bch_prio_write(struct cache *ca) |
2597 |
+@@ -241,8 +241,9 @@ static void __write_super(struct cache_sb *sb, struct bio *bio) |
2598 |
+ submit_bio(REQ_WRITE, bio); |
2599 |
+ } |
2600 |
+ |
2601 |
+-static void bch_write_bdev_super_unlock(struct closure *cl) |
2602 |
++static void bch_write_bdev_super_unlock(struct work_struct *work) |
2603 |
+ { |
2604 |
++ struct closure *cl = container_of(work, struct closure, work); |
2605 |
+ struct cached_dev *dc = container_of(cl, struct cached_dev, sb_write); |
2606 |
+ |
2607 |
+ up(&dc->sb_write_mutex); |
2608 |
+@@ -275,8 +276,9 @@ static void write_super_endio(struct bio *bio) |
2609 |
+ closure_put(&ca->set->sb_write); |
2610 |
+ } |
2611 |
+ |
2612 |
+-static void bcache_write_super_unlock(struct closure *cl) |
2613 |
++static void bcache_write_super_unlock(struct work_struct *work) |
2614 |
+ { |
2615 |
++ struct closure *cl = container_of(work, struct closure, work); |
2616 |
+ struct cache_set *c = container_of(cl, struct cache_set, sb_write); |
2617 |
+ |
2618 |
+ up(&c->sb_write_mutex); |
2619 |
+@@ -326,8 +328,9 @@ static void uuid_endio(struct bio *bio) |
2620 |
+ closure_put(cl); |
2621 |
+ } |
2622 |
+ |
2623 |
+-static void uuid_io_unlock(struct closure *cl) |
2624 |
++static void uuid_io_unlock(struct work_struct *work) |
2625 |
+ { |
2626 |
++ struct closure *cl = container_of(work, struct closure, work); |
2627 |
+ struct cache_set *c = container_of(cl, struct cache_set, uuid_write); |
2628 |
+ |
2629 |
+ up(&c->uuid_write_mutex); |
2630 |
+@@ -530,7 +533,7 @@ void bch_prio_write(struct cache *ca) |
2631 |
|
2632 |
ca->disk_buckets->seq++; |
2633 |
|
2634 |
@@ -53173,6 +53612,83 @@ index a296425..397607e 100644 |
2635 |
&ca->meta_sectors_written); |
2636 |
|
2637 |
//pr_debug("free %zu, free_inc %zu, unused %zu", fifo_used(&ca->free), |
2638 |
+@@ -1049,8 +1052,9 @@ void bch_cached_dev_release(struct kobject *kobj) |
2639 |
+ module_put(THIS_MODULE); |
2640 |
+ } |
2641 |
+ |
2642 |
+-static void cached_dev_free(struct closure *cl) |
2643 |
++static void cached_dev_free(struct work_struct *work) |
2644 |
+ { |
2645 |
++ struct closure *cl = container_of(work, struct closure, work); |
2646 |
+ struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl); |
2647 |
+ |
2648 |
+ cancel_delayed_work_sync(&dc->writeback_rate_update); |
2649 |
+@@ -1074,8 +1078,9 @@ static void cached_dev_free(struct closure *cl) |
2650 |
+ kobject_put(&dc->disk.kobj); |
2651 |
+ } |
2652 |
+ |
2653 |
+-static void cached_dev_flush(struct closure *cl) |
2654 |
++static void cached_dev_flush(struct work_struct *work) |
2655 |
+ { |
2656 |
++ struct closure *cl = container_of(work, struct closure, work); |
2657 |
+ struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl); |
2658 |
+ struct bcache_device *d = &dc->disk; |
2659 |
+ |
2660 |
+@@ -1191,8 +1196,9 @@ void bch_flash_dev_release(struct kobject *kobj) |
2661 |
+ kfree(d); |
2662 |
+ } |
2663 |
+ |
2664 |
+-static void flash_dev_free(struct closure *cl) |
2665 |
++static void flash_dev_free(struct work_struct *work) |
2666 |
+ { |
2667 |
++ struct closure *cl = container_of(work, struct closure, work); |
2668 |
+ struct bcache_device *d = container_of(cl, struct bcache_device, cl); |
2669 |
+ mutex_lock(&bch_register_lock); |
2670 |
+ bcache_device_free(d); |
2671 |
+@@ -1200,8 +1206,9 @@ static void flash_dev_free(struct closure *cl) |
2672 |
+ kobject_put(&d->kobj); |
2673 |
+ } |
2674 |
+ |
2675 |
+-static void flash_dev_flush(struct closure *cl) |
2676 |
++static void flash_dev_flush(struct work_struct *work) |
2677 |
+ { |
2678 |
++ struct closure *cl = container_of(work, struct closure, work); |
2679 |
+ struct bcache_device *d = container_of(cl, struct bcache_device, cl); |
2680 |
+ |
2681 |
+ mutex_lock(&bch_register_lock); |
2682 |
+@@ -1320,8 +1327,9 @@ void bch_cache_set_release(struct kobject *kobj) |
2683 |
+ module_put(THIS_MODULE); |
2684 |
+ } |
2685 |
+ |
2686 |
+-static void cache_set_free(struct closure *cl) |
2687 |
++static void cache_set_free(struct work_struct *work) |
2688 |
+ { |
2689 |
++ struct closure *cl = container_of(work, struct closure, work); |
2690 |
+ struct cache_set *c = container_of(cl, struct cache_set, cl); |
2691 |
+ struct cache *ca; |
2692 |
+ unsigned i; |
2693 |
+@@ -1366,8 +1374,9 @@ static void cache_set_free(struct closure *cl) |
2694 |
+ kobject_put(&c->kobj); |
2695 |
+ } |
2696 |
+ |
2697 |
+-static void cache_set_flush(struct closure *cl) |
2698 |
++static void cache_set_flush(struct work_struct *work) |
2699 |
+ { |
2700 |
++ struct closure *cl = container_of(work, struct closure, work); |
2701 |
+ struct cache_set *c = container_of(cl, struct cache_set, caching); |
2702 |
+ struct cache *ca; |
2703 |
+ struct btree *b; |
2704 |
+@@ -1408,8 +1417,9 @@ static void cache_set_flush(struct closure *cl) |
2705 |
+ closure_return(cl); |
2706 |
+ } |
2707 |
+ |
2708 |
+-static void __cache_set_unregister(struct closure *cl) |
2709 |
++static void __cache_set_unregister(struct work_struct *work) |
2710 |
+ { |
2711 |
++ struct closure *cl = container_of(work, struct closure, work); |
2712 |
+ struct cache_set *c = container_of(cl, struct cache_set, caching); |
2713 |
+ struct cached_dev *dc; |
2714 |
+ size_t i; |
2715 |
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c |
2716 |
index b3ff57d..b2e30fb 100644 |
2717 |
--- a/drivers/md/bcache/sysfs.c |
2718 |
@@ -53215,6 +53731,51 @@ index b3ff57d..b2e30fb 100644 |
2719 |
} |
2720 |
|
2721 |
return size; |
2722 |
+diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c |
2723 |
+index b9346cd..708ea8f 100644 |
2724 |
+--- a/drivers/md/bcache/writeback.c |
2725 |
++++ b/drivers/md/bcache/writeback.c |
2726 |
+@@ -118,14 +118,16 @@ static void dirty_init(struct keybuf_key *w) |
2727 |
+ bch_bio_map(bio, NULL); |
2728 |
+ } |
2729 |
+ |
2730 |
+-static void dirty_io_destructor(struct closure *cl) |
2731 |
++static void dirty_io_destructor(struct work_struct *work) |
2732 |
+ { |
2733 |
++ struct closure *cl = container_of(work, struct closure, work); |
2734 |
+ struct dirty_io *io = container_of(cl, struct dirty_io, cl); |
2735 |
+ kfree(io); |
2736 |
+ } |
2737 |
+ |
2738 |
+-static void write_dirty_finish(struct closure *cl) |
2739 |
++static void write_dirty_finish(struct work_struct *work) |
2740 |
+ { |
2741 |
++ struct closure *cl = container_of(work, struct closure, work); |
2742 |
+ struct dirty_io *io = container_of(cl, struct dirty_io, cl); |
2743 |
+ struct keybuf_key *w = io->bio.bi_private; |
2744 |
+ struct cached_dev *dc = io->dc; |
2745 |
+@@ -177,8 +179,9 @@ static void dirty_endio(struct bio *bio) |
2746 |
+ closure_put(&io->cl); |
2747 |
+ } |
2748 |
+ |
2749 |
+-static void write_dirty(struct closure *cl) |
2750 |
++static void write_dirty(struct work_struct *work) |
2751 |
+ { |
2752 |
++ struct closure *cl = container_of(work, struct closure, work); |
2753 |
+ struct dirty_io *io = container_of(cl, struct dirty_io, cl); |
2754 |
+ struct keybuf_key *w = io->bio.bi_private; |
2755 |
+ |
2756 |
+@@ -204,8 +207,9 @@ static void read_dirty_endio(struct bio *bio) |
2757 |
+ dirty_endio(bio); |
2758 |
+ } |
2759 |
+ |
2760 |
+-static void read_dirty_submit(struct closure *cl) |
2761 |
++static void read_dirty_submit(struct work_struct *work) |
2762 |
+ { |
2763 |
++ struct closure *cl = container_of(work, struct closure, work); |
2764 |
+ struct dirty_io *io = container_of(cl, struct dirty_io, cl); |
2765 |
+ |
2766 |
+ closure_bio_submit(&io->bio, cl); |
2767 |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c |
2768 |
index d80cce4..d7f15c4 100644 |
2769 |
--- a/drivers/md/bitmap.c |
2770 |
@@ -54725,6 +55286,19 @@ index 80caa70..d076ecf 100644 |
2771 |
|
2772 |
vma->vm_ops = &zoran_vm_ops; |
2773 |
vma->vm_flags |= VM_DONTEXPAND; |
2774 |
+diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c |
2775 |
+index de32e3a..e6a7bff 100644 |
2776 |
+--- a/drivers/media/platform/am437x/am437x-vpfe.c |
2777 |
++++ b/drivers/media/platform/am437x/am437x-vpfe.c |
2778 |
+@@ -1706,7 +1706,7 @@ static int vpfe_get_app_input_index(struct vpfe_device *vpfe, |
2779 |
+ sdinfo = &cfg->sub_devs[i]; |
2780 |
+ client = v4l2_get_subdevdata(sdinfo->sd); |
2781 |
+ if (client->addr == curr_client->addr && |
2782 |
+- client->adapter->nr == client->adapter->nr) { |
2783 |
++ client->adapter->nr == curr_client->adapter->nr) { |
2784 |
+ if (vpfe->current_input >= 1) |
2785 |
+ return -1; |
2786 |
+ *app_input_index = j + vpfe->current_input; |
2787 |
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c |
2788 |
index 70c28d1..ff21b13 100644 |
2789 |
--- a/drivers/media/platform/omap/omap_vout.c |
2790 |
@@ -56578,7 +57152,7 @@ index f7ab115..16b2087 100644 |
2791 |
if (!irq) { |
2792 |
dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n"); |
2793 |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c |
2794 |
-index 40e51b0..b986312 100644 |
2795 |
+index 40e51b0..af35565 100644 |
2796 |
--- a/drivers/mfd/twl4030-irq.c |
2797 |
+++ b/drivers/mfd/twl4030-irq.c |
2798 |
@@ -34,6 +34,7 @@ |
2799 |
@@ -56597,16 +57171,16 @@ index 40e51b0..b986312 100644 |
2800 |
- twl4030_irq_chip.name = "twl4030"; |
2801 |
+ pax_open_kernel(); |
2802 |
+ memcpy((void *)&twl4030_irq_chip, &dummy_irq_chip, sizeof twl4030_irq_chip); |
2803 |
-+ *(const char **)&twl4030_irq_chip.name = "twl4030"; |
2804 |
++ const_cast(twl4030_irq_chip.name) = "twl4030"; |
2805 |
|
2806 |
- twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; |
2807 |
-+ *(void **)&twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; |
2808 |
++ const_cast(twl4030_sih_irq_chip.irq_ack) = dummy_irq_chip.irq_ack; |
2809 |
+ pax_close_kernel(); |
2810 |
|
2811 |
for (i = irq_base; i < irq_end; i++) { |
2812 |
irq_set_chip_and_handler(i, &twl4030_irq_chip, |
2813 |
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c |
2814 |
-index cc8645b..7cc15e4 100644 |
2815 |
+index cc8645b..ab85ae4 100644 |
2816 |
--- a/drivers/misc/c2port/core.c |
2817 |
+++ b/drivers/misc/c2port/core.c |
2818 |
@@ -922,7 +922,9 @@ struct c2port_device *c2port_device_register(char *name, |
2819 |
@@ -56615,7 +57189,7 @@ index cc8645b..7cc15e4 100644 |
2820 |
|
2821 |
- bin_attr_flash_data.size = ops->blocks_num * ops->block_size; |
2822 |
+ pax_open_kernel(); |
2823 |
-+ *(size_t *)&bin_attr_flash_data.size = ops->blocks_num * ops->block_size; |
2824 |
++ const_cast(bin_attr_flash_data.size) = ops->blocks_num * ops->block_size; |
2825 |
+ pax_close_kernel(); |
2826 |
|
2827 |
c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, |
2828 |
@@ -56705,7 +57279,7 @@ index c439c82..1f20f57 100644 |
2829 |
int mapped_btns[3]; |
2830 |
|
2831 |
diff --git a/drivers/misc/mic/scif/scif_api.c b/drivers/misc/mic/scif/scif_api.c |
2832 |
-index ddc9e4b..7b9c669 100644 |
2833 |
+index ddc9e4b..9e27f41 100644 |
2834 |
--- a/drivers/misc/mic/scif/scif_api.c |
2835 |
+++ b/drivers/misc/mic/scif/scif_api.c |
2836 |
@@ -1486,10 +1486,12 @@ int scif_client_register(struct scif_client *client) |
2837 |
@@ -56717,10 +57291,10 @@ index ddc9e4b..7b9c669 100644 |
2838 |
- si->add_dev = scif_add_client_dev; |
2839 |
- si->remove_dev = scif_remove_client_dev; |
2840 |
+ pax_open_kernel(); |
2841 |
-+ *(const char **)&si->name = client->name; |
2842 |
-+ *(struct bus_type **)&si->subsys = &scif_peer_bus; |
2843 |
-+ *(void **)&si->add_dev = scif_add_client_dev; |
2844 |
-+ *(void **)&si->remove_dev = scif_remove_client_dev; |
2845 |
++ const_cast(si->name) = client->name; |
2846 |
++ const_cast(si->subsys) = &scif_peer_bus; |
2847 |
++ const_cast(si->add_dev) = scif_add_client_dev; |
2848 |
++ const_cast(si->remove_dev) = scif_remove_client_dev; |
2849 |
+ pax_close_kernel(); |
2850 |
|
2851 |
return subsys_interface_register(&client->si); |
2852 |
@@ -57235,7 +57809,7 @@ index f695b58..7b7d017 100644 |
2853 |
+} __do_const; |
2854 |
#endif /* _DW_MMC_H_ */ |
2855 |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c |
2856 |
-index 0d6ca41..d438654 100644 |
2857 |
+index 0d6ca41..bdc6710 100644 |
2858 |
--- a/drivers/mmc/host/mmci.c |
2859 |
+++ b/drivers/mmc/host/mmci.c |
2860 |
@@ -1634,7 +1634,9 @@ static int mmci_probe(struct amba_device *dev, |
2861 |
@@ -57244,13 +57818,13 @@ index 0d6ca41..d438654 100644 |
2862 |
if (variant->busy_detect) { |
2863 |
- mmci_ops.card_busy = mmci_card_busy; |
2864 |
+ pax_open_kernel(); |
2865 |
-+ *(void **)&mmci_ops.card_busy = mmci_card_busy; |
2866 |
++ const_cast(mmci_ops.card_busy) = mmci_card_busy; |
2867 |
+ pax_close_kernel(); |
2868 |
mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE); |
2869 |
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; |
2870 |
mmc->max_busy_timeout = 0; |
2871 |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c |
2872 |
-index f6e4d97..57358ff 100644 |
2873 |
+index f6e4d97..8bd8c05 100644 |
2874 |
--- a/drivers/mmc/host/omap_hsmmc.c |
2875 |
+++ b/drivers/mmc/host/omap_hsmmc.c |
2876 |
@@ -2088,7 +2088,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev) |
2877 |
@@ -57259,13 +57833,13 @@ index f6e4d97..57358ff 100644 |
2878 |
dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); |
2879 |
- omap_hsmmc_ops.multi_io_quirk = omap_hsmmc_multi_io_quirk; |
2880 |
+ pax_open_kernel(); |
2881 |
-+ *(void **)&omap_hsmmc_ops.multi_io_quirk = omap_hsmmc_multi_io_quirk; |
2882 |
++ const_cast(omap_hsmmc_ops.multi_io_quirk) = omap_hsmmc_multi_io_quirk; |
2883 |
+ pax_close_kernel(); |
2884 |
} |
2885 |
|
2886 |
device_init_wakeup(&pdev->dev, true); |
2887 |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c |
2888 |
-index f25f292..a0e1250 100644 |
2889 |
+index f25f292..7f4b03f 100644 |
2890 |
--- a/drivers/mmc/host/sdhci-esdhc-imx.c |
2891 |
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c |
2892 |
@@ -1194,9 +1194,12 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) |
2893 |
@@ -57276,7 +57850,7 @@ index f25f292..a0e1250 100644 |
2894 |
- sdhci_esdhc_ops.platform_execute_tuning = |
2895 |
+ if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { |
2896 |
+ pax_open_kernel(); |
2897 |
-+ *(void **)&sdhci_esdhc_ops.platform_execute_tuning = |
2898 |
++ const_cast(sdhci_esdhc_ops.platform_execute_tuning) = |
2899 |
esdhc_executing_tuning; |
2900 |
+ pax_close_kernel(); |
2901 |
+ } |
2902 |
@@ -57284,7 +57858,7 @@ index f25f292..a0e1250 100644 |
2903 |
if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) |
2904 |
writel(readl(host->ioaddr + ESDHC_TUNING_CTRL) | |
2905 |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c |
2906 |
-index 70c724b..308aafc 100644 |
2907 |
+index 70c724b..0c24beb 100644 |
2908 |
--- a/drivers/mmc/host/sdhci-s3c.c |
2909 |
+++ b/drivers/mmc/host/sdhci-s3c.c |
2910 |
@@ -598,9 +598,11 @@ static int sdhci_s3c_probe(struct platform_device *pdev) |
2911 |
@@ -57295,9 +57869,9 @@ index 70c724b..308aafc 100644 |
2912 |
- sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; |
2913 |
- sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; |
2914 |
+ pax_open_kernel(); |
2915 |
-+ *(void **)&sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; |
2916 |
-+ *(void **)&sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; |
2917 |
-+ *(void **)&sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; |
2918 |
++ const_cast(sdhci_s3c_ops.set_clock) = sdhci_cmu_set_clock; |
2919 |
++ const_cast(sdhci_s3c_ops.get_min_clock) = sdhci_cmu_get_min_clock; |
2920 |
++ const_cast(sdhci_s3c_ops.get_max_clock) = sdhci_cmu_get_max_clock; |
2921 |
+ pax_close_kernel(); |
2922 |
} |
2923 |
|
2924 |
@@ -59971,7 +60545,7 @@ index 245c063..74ed9c9 100644 |
2925 |
mdio_cmd->op = op; |
2926 |
mdio_cmd->mdio_addr = loc; |
2927 |
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c |
2928 |
-index 34d269c..43dcc17 100644 |
2929 |
+index 34d269c..69e1ac2 100644 |
2930 |
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c |
2931 |
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c |
2932 |
@@ -475,7 +475,7 @@ static void stop_pci_io(struct octeon_device *oct) |
2933 |
@@ -60018,7 +60592,7 @@ index 34d269c..43dcc17 100644 |
2934 |
- lionetdevops.ndo_select_queue = select_q; |
2935 |
+ if (num_iqueues > 1) { |
2936 |
+ pax_open_kernel(); |
2937 |
-+ *(void **)&lionetdevops.ndo_select_queue = select_q; |
2938 |
++ const_cast(lionetdevops.ndo_select_queue) = select_q; |
2939 |
+ pax_close_kernel(); |
2940 |
+ } |
2941 |
|
2942 |
@@ -60316,7 +60890,7 @@ index e51892d..3e645f4 100644 |
2943 |
struct hix5hd2_priv *priv = netdev_priv(dev); |
2944 |
struct hix5hd2_desc *desc; |
2945 |
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |
2946 |
-index d4f92ed..38fdf5b 100644 |
2947 |
+index d4f92ed..d4755e0 100644 |
2948 |
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |
2949 |
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |
2950 |
@@ -857,16 +857,18 @@ int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev) |
2951 |
@@ -60327,11 +60901,11 @@ index d4f92ed..38fdf5b 100644 |
2952 |
switch (dsaf_dev->dsaf_ver) { |
2953 |
case AE_VERSION_1: |
2954 |
- hns_dsaf_ops.toggle_ring_irq = hns_ae_toggle_ring_irq; |
2955 |
-+ *(void **)&hns_dsaf_ops.toggle_ring_irq = hns_ae_toggle_ring_irq; |
2956 |
++ const_cast(hns_dsaf_ops.toggle_ring_irq) = hns_ae_toggle_ring_irq; |
2957 |
break; |
2958 |
case AE_VERSION_2: |
2959 |
- hns_dsaf_ops.toggle_ring_irq = hns_aev2_toggle_ring_irq; |
2960 |
-+ *(void **)&hns_dsaf_ops.toggle_ring_irq = hns_aev2_toggle_ring_irq; |
2961 |
++ const_cast(hns_dsaf_ops.toggle_ring_irq) = hns_aev2_toggle_ring_irq; |
2962 |
break; |
2963 |
default: |
2964 |
break; |
2965 |
@@ -60809,7 +61383,7 @@ index 6409a06..e5bd4d6 100644 |
2966 |
struct netxen_adapter *adapter = pci_get_drvdata(pdev); |
2967 |
|
2968 |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c |
2969 |
-index bf89216..4044d8c 100644 |
2970 |
+index bf89216..b08442a 100644 |
2971 |
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c |
2972 |
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c |
2973 |
@@ -2324,7 +2324,9 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) |
2974 |
@@ -60818,13 +61392,13 @@ index bf89216..4044d8c 100644 |
2975 |
ahw->nic_mode = QLCNIC_DEFAULT_MODE; |
2976 |
- adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; |
2977 |
+ pax_open_kernel(); |
2978 |
-+ *(void **)&adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; |
2979 |
++ const_cast(adapter->nic_ops->init_driver) = qlcnic_83xx_init_default_driver; |
2980 |
+ pax_close_kernel(); |
2981 |
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; |
2982 |
max_sds_rings = QLCNIC_MAX_SDS_RINGS; |
2983 |
max_tx_rings = QLCNIC_MAX_TX_RINGS; |
2984 |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c |
2985 |
-index 3490675..0b9e15a 100644 |
2986 |
+index 3490675..cf148ea 100644 |
2987 |
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c |
2988 |
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c |
2989 |
@@ -207,17 +207,23 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter) |
2990 |
@@ -60833,7 +61407,7 @@ index 3490675..0b9e15a 100644 |
2991 |
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; |
2992 |
- nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic; |
2993 |
+ pax_open_kernel(); |
2994 |
-+ *(void **)&nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic; |
2995 |
++ const_cast(nic_ops->init_driver) = qlcnic_83xx_init_non_privileged_vnic; |
2996 |
+ pax_close_kernel(); |
2997 |
break; |
2998 |
case QLCNIC_PRIV_FUNC: |
2999 |
@@ -60841,7 +61415,7 @@ index 3490675..0b9e15a 100644 |
3000 |
ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry; |
3001 |
- nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic; |
3002 |
+ pax_open_kernel(); |
3003 |
-+ *(void **)&nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic; |
3004 |
++ const_cast(nic_ops->init_driver) = qlcnic_83xx_init_privileged_vnic; |
3005 |
+ pax_close_kernel(); |
3006 |
break; |
3007 |
case QLCNIC_MGMT_FUNC: |
3008 |
@@ -60849,7 +61423,7 @@ index 3490675..0b9e15a 100644 |
3009 |
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; |
3010 |
- nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic; |
3011 |
+ pax_open_kernel(); |
3012 |
-+ *(void **)&nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic; |
3013 |
++ const_cast(nic_ops->init_driver) = qlcnic_83xx_init_mgmt_vnic; |
3014 |
+ pax_close_kernel(); |
3015 |
break; |
3016 |
default: |
3017 |
@@ -61604,7 +62178,7 @@ index f9db2ce..6cd460c 100644 |
3018 |
} |
3019 |
|
3020 |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c |
3021 |
-index 94e6888..1d08b6a 100644 |
3022 |
+index 94e6888..c5c3f55 100644 |
3023 |
--- a/drivers/net/macvlan.c |
3024 |
+++ b/drivers/net/macvlan.c |
3025 |
@@ -335,7 +335,7 @@ static void macvlan_broadcast_enqueue(struct macvlan_port *port, |
3026 |
@@ -61628,13 +62202,13 @@ index 94e6888..1d08b6a 100644 |
3027 |
- ops->get_size = macvlan_get_size; |
3028 |
- ops->fill_info = macvlan_fill_info; |
3029 |
+ pax_open_kernel(); |
3030 |
-+ *(size_t *)&ops->priv_size = sizeof(struct macvlan_dev); |
3031 |
-+ *(void **)&ops->validate = macvlan_validate; |
3032 |
-+ *(int *)&ops->maxtype = IFLA_MACVLAN_MAX; |
3033 |
-+ *(const void **)&ops->policy = macvlan_policy; |
3034 |
-+ *(void **)&ops->changelink = macvlan_changelink; |
3035 |
-+ *(void **)&ops->get_size = macvlan_get_size; |
3036 |
-+ *(void **)&ops->fill_info = macvlan_fill_info; |
3037 |
++ const_cast(ops->priv_size) = sizeof(struct macvlan_dev); |
3038 |
++ const_cast(ops->validate) = macvlan_validate; |
3039 |
++ const_cast(ops->maxtype) = IFLA_MACVLAN_MAX; |
3040 |
++ const_cast(ops->policy) = macvlan_policy; |
3041 |
++ const_cast(ops->changelink) = macvlan_changelink; |
3042 |
++ const_cast(ops->get_size) = macvlan_get_size; |
3043 |
++ const_cast(ops->fill_info) = macvlan_fill_info; |
3044 |
+ pax_close_kernel(); |
3045 |
|
3046 |
return rtnl_link_register(ops); |
3047 |
@@ -62585,7 +63159,7 @@ index 831a544..d846785 100644 |
3048 |
struct ath_nf_limits { |
3049 |
s16 max; |
3050 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c |
3051 |
-index c1b33fd..9f904b1 100644 |
3052 |
+index c1b33fd..d61f3b4 100644 |
3053 |
--- a/drivers/net/wireless/ath/ath9k/main.c |
3054 |
+++ b/drivers/net/wireless/ath/ath9k/main.c |
3055 |
@@ -2589,16 +2589,18 @@ void ath9k_fill_chanctx_ops(void) |
3056 |
@@ -62603,16 +63177,16 @@ index c1b33fd..9f904b1 100644 |
3057 |
- ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx; |
3058 |
- ath9k_ops.mgd_prepare_tx = ath9k_mgd_prepare_tx; |
3059 |
+ pax_open_kernel(); |
3060 |
-+ *(void **)&ath9k_ops.hw_scan = ath9k_hw_scan; |
3061 |
-+ *(void **)&ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan; |
3062 |
-+ *(void **)&ath9k_ops.remain_on_channel = ath9k_remain_on_channel; |
3063 |
-+ *(void **)&ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel; |
3064 |
-+ *(void **)&ath9k_ops.add_chanctx = ath9k_add_chanctx; |
3065 |
-+ *(void **)&ath9k_ops.remove_chanctx = ath9k_remove_chanctx; |
3066 |
-+ *(void **)&ath9k_ops.change_chanctx = ath9k_change_chanctx; |
3067 |
-+ *(void **)&ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx; |
3068 |
-+ *(void **)&ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx; |
3069 |
-+ *(void **)&ath9k_ops.mgd_prepare_tx = ath9k_mgd_prepare_tx; |
3070 |
++ const_cast(ath9k_ops.hw_scan) = ath9k_hw_scan; |
3071 |
++ const_cast(ath9k_ops.cancel_hw_scan) = ath9k_cancel_hw_scan; |
3072 |
++ const_cast(ath9k_ops.remain_on_channel) = ath9k_remain_on_channel; |
3073 |
++ const_cast(ath9k_ops.cancel_remain_on_channel) = ath9k_cancel_remain_on_channel; |
3074 |
++ const_cast(ath9k_ops.add_chanctx) = ath9k_add_chanctx; |
3075 |
++ const_cast(ath9k_ops.remove_chanctx) = ath9k_remove_chanctx; |
3076 |
++ const_cast(ath9k_ops.change_chanctx) = ath9k_change_chanctx; |
3077 |
++ const_cast(ath9k_ops.assign_vif_chanctx) = ath9k_assign_vif_chanctx; |
3078 |
++ const_cast(ath9k_ops.unassign_vif_chanctx) = ath9k_unassign_vif_chanctx; |
3079 |
++ const_cast(ath9k_ops.mgd_prepare_tx) = ath9k_mgd_prepare_tx; |
3080 |
+ pax_close_kernel(); |
3081 |
} |
3082 |
|
3083 |
@@ -63861,7 +64435,7 @@ index ed0adaf..4bb4f53 100644 |
3084 |
return ret; |
3085 |
} |
3086 |
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c |
3087 |
-index af1b3e6..9bc08d3 100644 |
3088 |
+index af1b3e6..c014779 100644 |
3089 |
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c |
3090 |
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c |
3091 |
@@ -1399,8 +1399,9 @@ il3945_dump_nic_error_log(struct il_priv *il) |
3092 |
@@ -63899,7 +64473,7 @@ index af1b3e6..9bc08d3 100644 |
3093 |
D_INFO("Disabling hw_scan\n"); |
3094 |
- il3945_mac_ops.hw_scan = NULL; |
3095 |
+ pax_open_kernel(); |
3096 |
-+ *(void **)&il3945_mac_ops.hw_scan = NULL; |
3097 |
++ const_cast(il3945_mac_ops.hw_scan) = NULL; |
3098 |
+ pax_close_kernel(); |
3099 |
} |
3100 |
|
3101 |
@@ -65682,7 +66256,7 @@ index 48e8a97..3499ec8 100644 |
3102 |
|
3103 |
const struct iw_handler_def prism54_handler_def = { |
3104 |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c |
3105 |
-index a28414c..26c8768 100644 |
3106 |
+index a28414c..ad61156 100644 |
3107 |
--- a/drivers/net/wireless/mac80211_hwsim.c |
3108 |
+++ b/drivers/net/wireless/mac80211_hwsim.c |
3109 |
@@ -3218,20 +3218,20 @@ static int __init init_mac80211_hwsim(void) |
3110 |
@@ -65705,17 +66279,17 @@ index a28414c..26c8768 100644 |
3111 |
- mac80211_hwsim_unassign_vif_chanctx; |
3112 |
+ pax_open_kernel(); |
3113 |
+ memcpy((void *)&mac80211_hwsim_mchan_ops, &mac80211_hwsim_ops, sizeof mac80211_hwsim_mchan_ops); |
3114 |
-+ *(void **)&mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan; |
3115 |
-+ *(void **)&mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan; |
3116 |
-+ *(void **)&mac80211_hwsim_mchan_ops.sw_scan_start = NULL; |
3117 |
-+ *(void **)&mac80211_hwsim_mchan_ops.sw_scan_complete = NULL; |
3118 |
-+ *(void **)&mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc; |
3119 |
-+ *(void **)&mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc; |
3120 |
-+ *(void **)&mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx; |
3121 |
-+ *(void **)&mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx; |
3122 |
-+ *(void **)&mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx; |
3123 |
-+ *(void **)&mac80211_hwsim_mchan_ops.assign_vif_chanctx = mac80211_hwsim_assign_vif_chanctx; |
3124 |
-+ *(void **)&mac80211_hwsim_mchan_ops.unassign_vif_chanctx = mac80211_hwsim_unassign_vif_chanctx; |
3125 |
++ const_cast(mac80211_hwsim_mchan_ops.hw_scan) = mac80211_hwsim_hw_scan; |
3126 |
++ const_cast(mac80211_hwsim_mchan_ops.cancel_hw_scan) = mac80211_hwsim_cancel_hw_scan; |
3127 |
++ const_cast(mac80211_hwsim_mchan_ops.sw_scan_start) = NULL; |
3128 |
++ const_cast(mac80211_hwsim_mchan_ops.sw_scan_complete) = NULL; |
3129 |
++ const_cast(mac80211_hwsim_mchan_ops.remain_on_channel) = mac80211_hwsim_roc; |
3130 |
++ const_cast(mac80211_hwsim_mchan_ops.cancel_remain_on_channel) = mac80211_hwsim_croc; |
3131 |
++ const_cast(mac80211_hwsim_mchan_ops.add_chanctx) = mac80211_hwsim_add_chanctx; |
3132 |
++ const_cast(mac80211_hwsim_mchan_ops.remove_chanctx) = mac80211_hwsim_remove_chanctx; |
3133 |
++ const_cast(mac80211_hwsim_mchan_ops.change_chanctx) = mac80211_hwsim_change_chanctx; |
3134 |
++ const_cast(mac80211_hwsim_mchan_ops.assign_vif_chanctx) = mac80211_hwsim_assign_vif_chanctx; |
3135 |
++ const_cast(mac80211_hwsim_mchan_ops.unassign_vif_chanctx) = mac80211_hwsim_unassign_vif_chanctx; |
3136 |
+ pax_close_kernel(); |
3137 |
|
3138 |
spin_lock_init(&hwsim_radio_lock); |
3139 |
@@ -66131,7 +66705,7 @@ index 29dfc51..8297755 100644 |
3140 |
void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); |
3141 |
void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state); |
3142 |
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c |
3143 |
-index b661f896..ddf7d2b 100644 |
3144 |
+index b661f896..ebea675 100644 |
3145 |
--- a/drivers/net/wireless/ti/wl1251/sdio.c |
3146 |
+++ b/drivers/net/wireless/ti/wl1251/sdio.c |
3147 |
@@ -282,13 +282,17 @@ static int wl1251_sdio_probe(struct sdio_func *func, |
3148 |
@@ -66141,8 +66715,8 @@ index b661f896..ddf7d2b 100644 |
3149 |
- wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; |
3150 |
- wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; |
3151 |
+ pax_open_kernel(); |
3152 |
-+ *(void **)&wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; |
3153 |
-+ *(void **)&wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; |
3154 |
++ const_cast(wl1251_sdio_ops.enable_irq) = wl1251_enable_line_irq; |
3155 |
++ const_cast(wl1251_sdio_ops.disable_irq) = wl1251_disable_line_irq; |
3156 |
+ pax_close_kernel(); |
3157 |
|
3158 |
wl1251_info("using dedicated interrupt line"); |
3159 |
@@ -66150,14 +66724,14 @@ index b661f896..ddf7d2b 100644 |
3160 |
- wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; |
3161 |
- wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; |
3162 |
+ pax_open_kernel(); |
3163 |
-+ *(void **)&wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; |
3164 |
-+ *(void **)&wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; |
3165 |
++ const_cast(wl1251_sdio_ops.enable_irq) = wl1251_sdio_enable_irq; |
3166 |
++ const_cast(wl1251_sdio_ops.disable_irq) = wl1251_sdio_disable_irq; |
3167 |
+ pax_close_kernel(); |
3168 |
|
3169 |
wl1251_info("using SDIO interrupt"); |
3170 |
} |
3171 |
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c |
3172 |
-index a0d6ccc..93d9ac5 100644 |
3173 |
+index a0d6ccc..36e1ae3 100644 |
3174 |
--- a/drivers/net/wireless/ti/wl12xx/main.c |
3175 |
+++ b/drivers/net/wireless/ti/wl12xx/main.c |
3176 |
@@ -656,7 +656,9 @@ static int wl12xx_identify_chip(struct wl1271 *wl) |
3177 |
@@ -66166,7 +66740,7 @@ index a0d6ccc..93d9ac5 100644 |
3178 |
/* read data preparation is only needed by wl127x */ |
3179 |
- wl->ops->prepare_read = wl127x_prepare_read; |
3180 |
+ pax_open_kernel(); |
3181 |
-+ *(void **)&wl->ops->prepare_read = wl127x_prepare_read; |
3182 |
++ const_cast(wl->ops->prepare_read) = wl127x_prepare_read; |
3183 |
+ pax_close_kernel(); |
3184 |
|
3185 |
wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, |
3186 |
@@ -66177,13 +66751,13 @@ index a0d6ccc..93d9ac5 100644 |
3187 |
/* read data preparation is only needed by wl127x */ |
3188 |
- wl->ops->prepare_read = wl127x_prepare_read; |
3189 |
+ pax_open_kernel(); |
3190 |
-+ *(void **)&wl->ops->prepare_read = wl127x_prepare_read; |
3191 |
++ const_cast(wl->ops->prepare_read) = wl127x_prepare_read; |
3192 |
+ pax_close_kernel(); |
3193 |
|
3194 |
wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, |
3195 |
WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER, |
3196 |
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c |
3197 |
-index 1bf26cc..3b15c02 100644 |
3198 |
+index 1bf26cc..7dd1267 100644 |
3199 |
--- a/drivers/net/wireless/ti/wl18xx/main.c |
3200 |
+++ b/drivers/net/wireless/ti/wl18xx/main.c |
3201 |
@@ -2018,8 +2018,10 @@ static int wl18xx_setup(struct wl1271 *wl) |
3202 |
@@ -66193,8 +66767,8 @@ index 1bf26cc..3b15c02 100644 |
3203 |
- wl18xx_ops.set_rx_csum = NULL; |
3204 |
- wl18xx_ops.init_vif = NULL; |
3205 |
+ pax_open_kernel(); |
3206 |
-+ *(void **)&wl18xx_ops.set_rx_csum = NULL; |
3207 |
-+ *(void **)&wl18xx_ops.init_vif = NULL; |
3208 |
++ const_cast(wl18xx_ops.set_rx_csum) = NULL; |
3209 |
++ const_cast(wl18xx_ops.init_vif) = NULL; |
3210 |
+ pax_close_kernel(); |
3211 |
} |
3212 |
|
3213 |
@@ -66687,7 +67261,7 @@ index 680f578..cf80097 100644 |
3214 |
struct nvme_dev *dev = pci_get_drvdata(pdev); |
3215 |
|
3216 |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c |
3217 |
-index 655f79d..509e3cd 100644 |
3218 |
+index 655f79d..c684ede 100644 |
3219 |
--- a/drivers/of/fdt.c |
3220 |
+++ b/drivers/of/fdt.c |
3221 |
@@ -1170,7 +1170,9 @@ static int __init of_fdt_raw_init(void) |
3222 |
@@ -66696,7 +67270,7 @@ index 655f79d..509e3cd 100644 |
3223 |
} |
3224 |
- of_fdt_raw_attr.size = fdt_totalsize(initial_boot_params); |
3225 |
+ pax_open_kernel(); |
3226 |
-+ *(size_t *)&of_fdt_raw_attr.size = fdt_totalsize(initial_boot_params); |
3227 |
++ const_cast(of_fdt_raw_attr.size) = fdt_totalsize(initial_boot_params); |
3228 |
+ pax_close_kernel(); |
3229 |
return sysfs_create_bin_file(firmware_kobj, &of_fdt_raw_attr); |
3230 |
} |
3231 |
@@ -66881,7 +67455,7 @@ index 1652bc7..4f999c4 100644 |
3232 |
struct gen_pci_cfg_windows { |
3233 |
struct resource res; |
3234 |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c |
3235 |
-index 2f6d3a1..5bc1bf1 100644 |
3236 |
+index 2f6d3a1..cb43cfc 100644 |
3237 |
--- a/drivers/pci/hotplug/acpiphp_ibm.c |
3238 |
+++ b/drivers/pci/hotplug/acpiphp_ibm.c |
3239 |
@@ -463,7 +463,9 @@ static int __init ibm_acpiphp_init(void) |
3240 |
@@ -66890,7 +67464,7 @@ index 2f6d3a1..5bc1bf1 100644 |
3241 |
|
3242 |
- ibm_apci_table_attr.size = ibm_get_table_from_acpi(NULL); |
3243 |
+ pax_open_kernel(); |
3244 |
-+ *(size_t *)&ibm_apci_table_attr.size = ibm_get_table_from_acpi(NULL); |
3245 |
++ const_cast(ibm_apci_table_attr.size) = ibm_get_table_from_acpi(NULL); |
3246 |
+ pax_close_kernel(); |
3247 |
retval = sysfs_create_bin_file(sysdir, &ibm_apci_table_attr); |
3248 |
|
3249 |
@@ -66927,7 +67501,7 @@ index 88a44a7..de358ce 100644 |
3250 |
|
3251 |
status = cpci_hp_register_controller(&generic_hpc); |
3252 |
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c |
3253 |
-index 5f49c3f..989cd41 100644 |
3254 |
+index 5f49c3f..438f019 100644 |
3255 |
--- a/drivers/pci/hotplug/cpcihp_zt5550.c |
3256 |
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c |
3257 |
@@ -59,7 +59,6 @@ |
3258 |
@@ -66964,9 +67538,9 @@ index 5f49c3f..989cd41 100644 |
3259 |
- zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq; |
3260 |
- zt5550_hpc_ops.check_irq = zt5550_hc_check_irq; |
3261 |
+ pax_open_kernel(); |
3262 |
-+ *(void **)&zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq; |
3263 |
-+ *(void **)&zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq; |
3264 |
-+ *(void **)&zt5550_hpc_ops.check_irq = zt5550_hc_check_irq; |
3265 |
++ const_cast(zt5550_hpc_ops.enable_irq) = zt5550_hc_enable_irq; |
3266 |
++ const_cast(zt5550_hpc_ops.disable_irq) = zt5550_hc_disable_irq; |
3267 |
++ const_cast(zt5550_hpc_ops.check_irq) = zt5550_hc_check_irq; |
3268 |
+ pax_open_kernel(); |
3269 |
} else { |
3270 |
info("using ENUM# polling mode"); |
3271 |
@@ -66987,7 +67561,7 @@ index c25fc90..b054774 100644 |
3272 |
dbg("int15 entry = %p\n", compaq_int15_entry_point); |
3273 |
|
3274 |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c |
3275 |
-index 9acd199..0645a09 100644 |
3276 |
+index 9acd199..1b19f5b 100644 |
3277 |
--- a/drivers/pci/hotplug/pci_hotplug_core.c |
3278 |
+++ b/drivers/pci/hotplug/pci_hotplug_core.c |
3279 |
@@ -434,8 +434,10 @@ int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, |
3280 |
@@ -66997,8 +67571,8 @@ index 9acd199..0645a09 100644 |
3281 |
- slot->ops->owner = owner; |
3282 |
- slot->ops->mod_name = mod_name; |
3283 |
+ pax_open_kernel(); |
3284 |
-+ *(struct module **)&slot->ops->owner = owner; |
3285 |
-+ *(const char **)&slot->ops->mod_name = mod_name; |
3286 |
++ const_cast(slot->ops->owner) = owner; |
3287 |
++ const_cast(slot->ops->mod_name) = mod_name; |
3288 |
+ pax_close_kernel(); |
3289 |
|
3290 |
mutex_lock(&pci_hp_mutex); |
3291 |
@@ -67017,7 +67591,7 @@ index ac531e6..716d058 100644 |
3292 |
int retval = -ENOMEM; |
3293 |
|
3294 |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c |
3295 |
-index a080f44..9ff42d9 100644 |
3296 |
+index a080f44..24ad26c 100644 |
3297 |
--- a/drivers/pci/msi.c |
3298 |
+++ b/drivers/pci/msi.c |
3299 |
@@ -474,8 +474,8 @@ static int populate_msi_sysfs(struct pci_dev *pdev) |
3300 |
@@ -67047,13 +67621,13 @@ index a080f44..9ff42d9 100644 |
3301 |
+ pax_open_kernel(); |
3302 |
if (ops->set_desc == NULL) |
3303 |
- ops->set_desc = pci_msi_domain_set_desc; |
3304 |
-+ *(void **)&ops->set_desc = pci_msi_domain_set_desc; |
3305 |
++ const_cast(ops->set_desc) = pci_msi_domain_set_desc; |
3306 |
if (ops->msi_check == NULL) |
3307 |
- ops->msi_check = pci_msi_domain_check_cap; |
3308 |
-+ *(void **)&ops->msi_check = pci_msi_domain_check_cap; |
3309 |
++ const_cast(ops->msi_check) = pci_msi_domain_check_cap; |
3310 |
if (ops->handle_error == NULL) |
3311 |
- ops->handle_error = pci_msi_domain_handle_error; |
3312 |
-+ *(void **)&ops->handle_error = pci_msi_domain_handle_error; |
3313 |
++ const_cast(ops->handle_error) = pci_msi_domain_handle_error; |
3314 |
+ pax_close_kernel(); |
3315 |
} |
3316 |
} |
3317 |
@@ -67065,13 +67639,13 @@ index a080f44..9ff42d9 100644 |
3318 |
+ pax_open_kernel(); |
3319 |
if (!chip->irq_write_msi_msg) |
3320 |
- chip->irq_write_msi_msg = pci_msi_domain_write_msg; |
3321 |
-+ *(void **)&chip->irq_write_msi_msg = pci_msi_domain_write_msg; |
3322 |
++ const_cast(chip->irq_write_msi_msg) = pci_msi_domain_write_msg; |
3323 |
if (!chip->irq_mask) |
3324 |
- chip->irq_mask = pci_msi_mask_irq; |
3325 |
-+ *(void **)&chip->irq_mask = pci_msi_mask_irq; |
3326 |
++ const_cast(chip->irq_mask) = pci_msi_mask_irq; |
3327 |
if (!chip->irq_unmask) |
3328 |
- chip->irq_unmask = pci_msi_unmask_irq; |
3329 |
-+ *(void **)&chip->irq_unmask = pci_msi_unmask_irq; |
3330 |
++ const_cast(chip->irq_unmask) = pci_msi_unmask_irq; |
3331 |
+ pax_close_kernel(); |
3332 |
} |
3333 |
|
3334 |
@@ -67238,7 +67812,7 @@ index c8969dd..4764267 100644 |
3335 |
bool supports_sleepmode; |
3336 |
int irq; |
3337 |
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c |
3338 |
-index 523b6b7..e9aa88d 100644 |
3339 |
+index 523b6b7..eb4c74d 100644 |
3340 |
--- a/drivers/pinctrl/pinctrl-at91.c |
3341 |
+++ b/drivers/pinctrl/pinctrl-at91.c |
3342 |
@@ -24,6 +24,7 @@ |
3343 |
@@ -67255,7 +67829,7 @@ index 523b6b7..e9aa88d 100644 |
3344 |
/* Setup proper .irq_set_type function */ |
3345 |
- gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type; |
3346 |
+ pax_open_kernel(); |
3347 |
-+ *(void **)&gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type; |
3348 |
++ const_cast(gpio_irqchip.irq_set_type) = at91_gpio->ops->irq_type; |
3349 |
+ pax_close_kernel(); |
3350 |
|
3351 |
/* Disable irqs of this PIO controller */ |
3352 |
@@ -67398,7 +67972,7 @@ index 6aa33c4..cfb5425 100644 |
3353 |
.ident = "OakTrail platform", |
3354 |
.matches = { |
3355 |
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c |
3356 |
-index 4231770..10a6caf 100644 |
3357 |
+index 4231770..cbf93a6 100644 |
3358 |
--- a/drivers/platform/x86/msi-laptop.c |
3359 |
+++ b/drivers/platform/x86/msi-laptop.c |
3360 |
@@ -605,7 +605,7 @@ static int dmi_check_cb(const struct dmi_system_id *dmi) |
3361 |
@@ -67421,12 +67995,12 @@ index 4231770..10a6caf 100644 |
3362 |
- dev_attr_wlan.attr.mode |= S_IWUSR; |
3363 |
- dev_attr_threeg.attr.mode |= S_IWUSR; |
3364 |
+ pax_open_kernel(); |
3365 |
-+ *(void **)&dev_attr_bluetooth.store = store_bluetooth; |
3366 |
-+ *(void **)&dev_attr_wlan.store = store_wlan; |
3367 |
-+ *(void **)&dev_attr_threeg.store = store_threeg; |
3368 |
-+ *(umode_t *)&dev_attr_bluetooth.attr.mode |= S_IWUSR; |
3369 |
-+ *(umode_t *)&dev_attr_wlan.attr.mode |= S_IWUSR; |
3370 |
-+ *(umode_t *)&dev_attr_threeg.attr.mode |= S_IWUSR; |
3371 |
++ const_cast(dev_attr_bluetooth.store) = store_bluetooth; |
3372 |
++ const_cast(dev_attr_wlan.store) = store_wlan; |
3373 |
++ const_cast(dev_attr_threeg.store) = store_threeg; |
3374 |
++ const_cast(dev_attr_bluetooth.attr.mode) |= S_IWUSR; |
3375 |
++ const_cast(dev_attr_wlan.attr.mode) |= S_IWUSR; |
3376 |
++ const_cast(dev_attr_threeg.attr.mode) |= S_IWUSR; |
3377 |
+ pax_close_kernel(); |
3378 |
} |
3379 |
|
3380 |
@@ -67756,7 +68330,7 @@ index ed2d7fd..266b28f 100644 |
3381 |
__power_supply_attrs[i] = &power_supply_attrs[i].attr; |
3382 |
} |
3383 |
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c |
3384 |
-index 1b5d450..3257054 100644 |
3385 |
+index 1b5d450..b6042f8 100644 |
3386 |
--- a/drivers/power/reset/at91-reset.c |
3387 |
+++ b/drivers/power/reset/at91-reset.c |
3388 |
@@ -17,6 +17,7 @@ |
3389 |
@@ -67773,13 +68347,13 @@ index 1b5d450..3257054 100644 |
3390 |
match = of_match_node(at91_reset_of_match, pdev->dev.of_node); |
3391 |
- at91_restart_nb.notifier_call = match->data; |
3392 |
+ pax_open_kernel(); |
3393 |
-+ *(void **)&at91_restart_nb.notifier_call = match->data; |
3394 |
++ const_cast(at91_restart_nb.notifier_call) = match->data; |
3395 |
+ pax_close_kernel(); |
3396 |
|
3397 |
sclk = devm_clk_get(&pdev->dev, NULL); |
3398 |
if (IS_ERR(sclk)) |
3399 |
diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c |
3400 |
-index 14bde0d..89f2669 100644 |
3401 |
+index 14bde0d..9391277 100644 |
3402 |
--- a/drivers/powercap/powercap_sys.c |
3403 |
+++ b/drivers/powercap/powercap_sys.c |
3404 |
@@ -154,8 +154,77 @@ struct powercap_constraint_attr { |
3405 |
@@ -67887,7 +68461,7 @@ index 14bde0d..89f2669 100644 |
3406 |
- dev_attr->store = store; |
3407 |
+ |
3408 |
+ pax_open_kernel(); |
3409 |
-+ *(const char **)&dev_attr->attr.name = name; |
3410 |
++ const_cast(dev_attr->attr.name) = name; |
3411 |
+ pax_close_kernel(); |
3412 |
|
3413 |
return 0; |
3414 |
@@ -67959,10 +68533,10 @@ index 14bde0d..89f2669 100644 |
3415 |
+ pax_open_kernel(); |
3416 |
if (power_zone->ops->reset_energy_uj) |
3417 |
- dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUGO; |
3418 |
-+ *(umode_t *)&dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUGO; |
3419 |
++ const_cast(dev_attr_energy_uj.attr.mode) = S_IWUSR | S_IRUGO; |
3420 |
else |
3421 |
- dev_attr_energy_uj.attr.mode = S_IRUGO; |
3422 |
-+ *(umode_t *)&dev_attr_energy_uj.attr.mode = S_IRUGO; |
3423 |
++ const_cast(dev_attr_energy_uj.attr.mode) = S_IRUGO; |
3424 |
+ pax_close_kernel(); |
3425 |
power_zone->zone_dev_attrs[count++] = |
3426 |
&dev_attr_energy_uj.attr; |
3427 |
@@ -68016,7 +68590,7 @@ index 744c988..a269ffb 100644 |
3428 |
if (ret != 0) { |
3429 |
put_device(&rdev->dev); |
3430 |
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c |
3431 |
-index b87f62d..345b9a1 100644 |
3432 |
+index b87f62d..34f1cdf 100644 |
3433 |
--- a/drivers/regulator/max8660.c |
3434 |
+++ b/drivers/regulator/max8660.c |
3435 |
@@ -423,8 +423,10 @@ static int max8660_probe(struct i2c_client *client, |
3436 |
@@ -68026,14 +68600,14 @@ index b87f62d..345b9a1 100644 |
3437 |
- max8660_dcdc_ops.enable = max8660_dcdc_enable; |
3438 |
- max8660_dcdc_ops.disable = max8660_dcdc_disable; |
3439 |
+ pax_open_kernel(); |
3440 |
-+ *(void **)&max8660_dcdc_ops.enable = max8660_dcdc_enable; |
3441 |
-+ *(void **)&max8660_dcdc_ops.disable = max8660_dcdc_disable; |
3442 |
++ const_cast(max8660_dcdc_ops.enable) = max8660_dcdc_enable; |
3443 |
++ const_cast(max8660_dcdc_ops.disable) = max8660_dcdc_disable; |
3444 |
+ pax_close_kernel(); |
3445 |
} |
3446 |
|
3447 |
/* |
3448 |
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c |
3449 |
-index 5b75b7c..142c226 100644 |
3450 |
+index 5b75b7c..8b1bb06 100644 |
3451 |
--- a/drivers/regulator/max8973-regulator.c |
3452 |
+++ b/drivers/regulator/max8973-regulator.c |
3453 |
@@ -658,9 +658,11 @@ static int max8973_probe(struct i2c_client *client, |
3454 |
@@ -68044,9 +68618,9 @@ index 5b75b7c..142c226 100644 |
3455 |
- max->ops.disable = regulator_disable_regmap; |
3456 |
- max->ops.is_enabled = regulator_is_enabled_regmap; |
3457 |
+ pax_open_kernel(); |
3458 |
-+ *(void **)&max->ops.enable = regulator_enable_regmap; |
3459 |
-+ *(void **)&max->ops.disable = regulator_disable_regmap; |
3460 |
-+ *(void **)&max->ops.is_enabled = regulator_is_enabled_regmap; |
3461 |
++ const_cast(max->ops.enable) = regulator_enable_regmap; |
3462 |
++ const_cast(max->ops.disable) = regulator_disable_regmap; |
3463 |
++ const_cast(max->ops.is_enabled) = regulator_is_enabled_regmap; |
3464 |
+ pax_close_kernel(); |
3465 |
break; |
3466 |
} |
3467 |
@@ -68059,15 +68633,15 @@ index 5b75b7c..142c226 100644 |
3468 |
- max->ops.disable = regulator_disable_regmap; |
3469 |
- max->ops.is_enabled = regulator_is_enabled_regmap; |
3470 |
+ pax_open_kernel(); |
3471 |
-+ *(void **)&max->ops.enable = regulator_enable_regmap; |
3472 |
-+ *(void **)&max->ops.disable = regulator_disable_regmap; |
3473 |
-+ *(void **)&max->ops.is_enabled = regulator_is_enabled_regmap; |
3474 |
++ const_cast(max->ops.enable) = regulator_enable_regmap; |
3475 |
++ const_cast(max->ops.disable) = regulator_disable_regmap; |
3476 |
++ const_cast(max->ops.is_enabled) = regulator_is_enabled_regmap; |
3477 |
+ pax_close_kernel(); |
3478 |
max->ops.set_current_limit = max8973_set_current_limit; |
3479 |
max->ops.get_current_limit = max8973_get_current_limit; |
3480 |
break; |
3481 |
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c |
3482 |
-index 0d17c92..a29f627 100644 |
3483 |
+index 0d17c92..ce5897e 100644 |
3484 |
--- a/drivers/regulator/mc13892-regulator.c |
3485 |
+++ b/drivers/regulator/mc13892-regulator.c |
3486 |
@@ -584,10 +584,12 @@ static int mc13892_regulator_probe(struct platform_device *pdev) |
3487 |
@@ -68080,8 +68654,8 @@ index 0d17c92..a29f627 100644 |
3488 |
sizeof(struct regulator_ops)); |
3489 |
- mc13892_vcam_ops.set_mode = mc13892_vcam_set_mode, |
3490 |
- mc13892_vcam_ops.get_mode = mc13892_vcam_get_mode, |
3491 |
-+ *(void **)&mc13892_vcam_ops.set_mode = mc13892_vcam_set_mode, |
3492 |
-+ *(void **)&mc13892_vcam_ops.get_mode = mc13892_vcam_get_mode, |
3493 |
++ const_cast(mc13892_vcam_ops.set_mode) = mc13892_vcam_set_mode, |
3494 |
++ const_cast(mc13892_vcam_ops.get_mode) = mc13892_vcam_get_mode, |
3495 |
+ pax_close_kernel(); |
3496 |
mc13892_regulators[MC13892_VCAM].desc.ops = &mc13892_vcam_ops; |
3497 |
|
3498 |
@@ -68177,7 +68751,7 @@ index 9e03d15..36e341c 100644 |
3499 |
|
3500 |
/* handle firmware resource entries before booting the remote processor */ |
3501 |
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c |
3502 |
-index 9a3f2a6..604f463 100644 |
3503 |
+index 9a3f2a6..c19b00a 100644 |
3504 |
--- a/drivers/rtc/rtc-armada38x.c |
3505 |
+++ b/drivers/rtc/rtc-armada38x.c |
3506 |
@@ -18,6 +18,7 @@ |
3507 |
@@ -68195,14 +68769,14 @@ index 9a3f2a6..604f463 100644 |
3508 |
- armada38x_rtc_ops.set_alarm = NULL; |
3509 |
- armada38x_rtc_ops.alarm_irq_enable = NULL; |
3510 |
+ pax_open_kernel(); |
3511 |
-+ *(void **)&armada38x_rtc_ops.set_alarm = NULL; |
3512 |
-+ *(void **)&armada38x_rtc_ops.alarm_irq_enable = NULL; |
3513 |
++ const_cast(armada38x_rtc_ops.set_alarm) = NULL; |
3514 |
++ const_cast(armada38x_rtc_ops.alarm_irq_enable) = NULL; |
3515 |
+ pax_close_kernel(); |
3516 |
} |
3517 |
platform_set_drvdata(pdev, rtc); |
3518 |
if (rtc->irq != -1) |
3519 |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c |
3520 |
-index 84fb541..fee0421a 100644 |
3521 |
+index 84fb541..a526dd0 100644 |
3522 |
--- a/drivers/rtc/rtc-cmos.c |
3523 |
+++ b/drivers/rtc/rtc-cmos.c |
3524 |
@@ -735,7 +735,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) |
3525 |
@@ -68211,7 +68785,7 @@ index 84fb541..fee0421a 100644 |
3526 |
/* export at least the first block of NVRAM */ |
3527 |
- nvram.size = address_space - NVRAM_OFFSET; |
3528 |
+ pax_open_kernel(); |
3529 |
-+ *(size_t *)&nvram.size = address_space - NVRAM_OFFSET; |
3530 |
++ const_cast(nvram.size) = address_space - NVRAM_OFFSET; |
3531 |
+ pax_close_kernel(); |
3532 |
retval = sysfs_create_bin_file(&dev->kobj, &nvram); |
3533 |
if (retval < 0) { |
3534 |
@@ -68251,7 +68825,7 @@ index cf685f6..2311b8f 100644 |
3535 |
unsigned long flags; |
3536 |
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */ |
3537 |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c |
3538 |
-index d99a705..f8ebd79 100644 |
3539 |
+index d99a705..99654e7 100644 |
3540 |
--- a/drivers/rtc/rtc-m48t59.c |
3541 |
+++ b/drivers/rtc/rtc-m48t59.c |
3542 |
@@ -485,7 +485,9 @@ static int m48t59_rtc_probe(struct platform_device *pdev) |
3543 |
@@ -68260,7 +68834,7 @@ index d99a705..f8ebd79 100644 |
3544 |
|
3545 |
- m48t59_nvram_attr.size = pdata->offset; |
3546 |
+ pax_open_kernel(); |
3547 |
-+ *(size_t *)&m48t59_nvram_attr.size = pdata->offset; |
3548 |
++ const_cast(m48t59_nvram_attr.size) = pdata->offset; |
3549 |
+ pax_close_kernel(); |
3550 |
|
3551 |
ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); |
3552 |
@@ -68303,7 +68877,7 @@ index 7155c08..10ba718 100644 |
3553 |
dev_err(&client->dev, "unable to register the class device\n"); |
3554 |
return PTR_ERR(rv8803->rtc); |
3555 |
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c |
3556 |
-index 772d221..60e31aa 100644 |
3557 |
+index 772d221..3a56e42 100644 |
3558 |
--- a/drivers/rtc/rtc-rx8010.c |
3559 |
+++ b/drivers/rtc/rtc-rx8010.c |
3560 |
@@ -489,9 +489,11 @@ static int rx8010_probe(struct i2c_client *client, |
3561 |
@@ -68314,15 +68888,15 @@ index 772d221..60e31aa 100644 |
3562 |
- rx8010_rtc_ops.set_alarm = rx8010_set_alarm; |
3563 |
- rx8010_rtc_ops.alarm_irq_enable = rx8010_alarm_irq_enable; |
3564 |
+ pax_open_kernel(); |
3565 |
-+ *(void **)&rx8010_rtc_ops.read_alarm = rx8010_read_alarm; |
3566 |
-+ *(void **)&rx8010_rtc_ops.set_alarm = rx8010_set_alarm; |
3567 |
-+ *(void **)&rx8010_rtc_ops.alarm_irq_enable = rx8010_alarm_irq_enable; |
3568 |
++ const_cast(rx8010_rtc_ops.read_alarm) = rx8010_read_alarm; |
3569 |
++ const_cast(rx8010_rtc_ops.set_alarm) = rx8010_set_alarm; |
3570 |
++ const_cast(rx8010_rtc_ops.alarm_irq_enable) = rx8010_alarm_irq_enable; |
3571 |
+ pax_close_kernel(); |
3572 |
} |
3573 |
} |
3574 |
|
3575 |
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c |
3576 |
-index 3a2da4c..e88493c 100644 |
3577 |
+index 3a2da4c..1d1d4b1 100644 |
3578 |
--- a/drivers/rtc/rtc-test.c |
3579 |
+++ b/drivers/rtc/rtc-test.c |
3580 |
@@ -112,8 +112,10 @@ static int test_probe(struct platform_device *plat_dev) |
3581 |
@@ -68332,34 +68906,16 @@ index 3a2da4c..e88493c 100644 |
3582 |
- test_rtc_ops.set_mmss64 = test_rtc_set_mmss64; |
3583 |
- test_rtc_ops.set_mmss = NULL; |
3584 |
+ pax_open_kernel(); |
3585 |
-+ *(void **)&test_rtc_ops.set_mmss64 = test_rtc_set_mmss64; |
3586 |
-+ *(void **)&test_rtc_ops.set_mmss = NULL; |
3587 |
++ const_cast(test_rtc_ops.set_mmss64) = test_rtc_set_mmss64; |
3588 |
++ const_cast(test_rtc_ops.set_mmss) = NULL; |
3589 |
+ pax_close_kernel(); |
3590 |
} |
3591 |
|
3592 |
rtc = devm_rtc_device_register(&plat_dev->dev, "test", |
3593 |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c |
3594 |
-index e4c2437..2297164 100644 |
3595 |
+index e4c2437..3b3cd62 100644 |
3596 |
--- a/drivers/scsi/aacraid/aachba.c |
3597 |
+++ b/drivers/scsi/aacraid/aachba.c |
3598 |
-@@ -647,7 +647,7 @@ static void _aac_probe_container2(void * context, struct fib * fibptr) |
3599 |
- } |
3600 |
- aac_fib_complete(fibptr); |
3601 |
- aac_fib_free(fibptr); |
3602 |
-- callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr); |
3603 |
-+ callback = scsicmd->SCp.ptr; |
3604 |
- scsicmd->SCp.ptr = NULL; |
3605 |
- (*callback)(scsicmd); |
3606 |
- return; |
3607 |
-@@ -726,7 +726,7 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru |
3608 |
- |
3609 |
- dinfo->count = cpu_to_le32(scmd_id(scsicmd)); |
3610 |
- dinfo->type = cpu_to_le32(FT_FILESYS); |
3611 |
-- scsicmd->SCp.ptr = (char *)callback; |
3612 |
-+ scsicmd->SCp.ptr = callback; |
3613 |
- |
3614 |
- status = aac_fib_send(ContainerCommand, |
3615 |
- fibptr, |
3616 |
@@ -775,6 +775,11 @@ static int aac_probe_container_callback1(struct scsi_cmnd * scsicmd) |
3617 |
return 0; |
3618 |
} |
3619 |
@@ -70641,7 +71197,7 @@ index 25aa9b9..d700a65 100644 |
3620 |
snprintf(name, sizeof(name), "discovery_trace"); |
3621 |
vport->debug_disc_trc = |
3622 |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c |
3623 |
-index f57d02c..ab7b70c 100644 |
3624 |
+index f57d02c..6ba534b 100644 |
3625 |
--- a/drivers/scsi/lpfc/lpfc_init.c |
3626 |
+++ b/drivers/scsi/lpfc/lpfc_init.c |
3627 |
@@ -11028,7 +11028,7 @@ lpfc_pci_resume_one(struct pci_dev *pdev) |
3628 |
@@ -70660,8 +71216,8 @@ index f57d02c..ab7b70c 100644 |
3629 |
- lpfc_transport_functions.vport_create = lpfc_vport_create; |
3630 |
- lpfc_transport_functions.vport_delete = lpfc_vport_delete; |
3631 |
+ pax_open_kernel(); |
3632 |
-+ *(void **)&lpfc_transport_functions.vport_create = lpfc_vport_create; |
3633 |
-+ *(void **)&lpfc_transport_functions.vport_delete = lpfc_vport_delete; |
3634 |
++ const_cast(lpfc_transport_functions.vport_create) = lpfc_vport_create; |
3635 |
++ const_cast(lpfc_transport_functions.vport_delete) = lpfc_vport_delete; |
3636 |
+ pax_close_kernel(); |
3637 |
} |
3638 |
lpfc_transport_template = |
3639 |
@@ -71004,7 +71560,7 @@ index 0103e46..6220a84 100644 |
3640 |
extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *, bool); |
3641 |
extern void qla2x00_init_host_attr(scsi_qla_host_t *); |
3642 |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c |
3643 |
-index f6c7ce3..2dd675b 100644 |
3644 |
+index f6c7ce3..dccd3d4 100644 |
3645 |
--- a/drivers/scsi/qla2xxx/qla_os.c |
3646 |
+++ b/drivers/scsi/qla2xxx/qla_os.c |
3647 |
@@ -291,12 +291,12 @@ struct scsi_transport_template *qla2xxx_transport_vport_template = NULL; |
3648 |
@@ -71029,8 +71585,8 @@ index f6c7ce3..2dd675b 100644 |
3649 |
- ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64; |
3650 |
- ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64; |
3651 |
+ pax_open_kernel(); |
3652 |
-+ *(void **)&ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64; |
3653 |
-+ *(void **)&ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64; |
3654 |
++ const_cast(ha->isp_ops->calc_req_entries) = qla2x00_calc_iocbs_64; |
3655 |
++ const_cast(ha->isp_ops->build_iocbs) = qla2x00_build_scsi_iocbs_64; |
3656 |
+ pax_close_kernel(); |
3657 |
return; |
3658 |
} |
3659 |
@@ -74424,7 +74980,7 @@ index 9a14074..3d02410 100644 |
3660 |
struct rtw_adapter *padapter = netdev_priv(pnetdev); |
3661 |
struct xmit_priv *pxmitpriv = &padapter->xmitpriv; |
3662 |
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c |
3663 |
-index c78421b..f75c4c4 100644 |
3664 |
+index c78421b..e1ba746 100644 |
3665 |
--- a/drivers/staging/sm750fb/sm750.c |
3666 |
+++ b/drivers/staging/sm750fb/sm750.c |
3667 |
@@ -720,6 +720,7 @@ static struct fb_ops lynxfb_ops = { |
3668 |
@@ -74449,7 +75005,7 @@ index c78421b..f75c4c4 100644 |
3669 |
if (!g_hwcursor) { |
3670 |
- lynxfb_ops.fb_cursor = NULL; |
3671 |
+ pax_open_kernel(); |
3672 |
-+ *(void **)&lynxfb_ops.fb_cursor = NULL; |
3673 |
++ const_cast(lynxfb_ops.fb_cursor) = NULL; |
3674 |
+ pax_close_kernel(); |
3675 |
hw_cursor_disable(&crtc->cursor); |
3676 |
} |
3677 |
@@ -74461,9 +75017,9 @@ index c78421b..f75c4c4 100644 |
3678 |
- lynxfb_ops.fb_copyarea = lynxfb_ops_copyarea; |
3679 |
- lynxfb_ops.fb_imageblit = lynxfb_ops_imageblit; |
3680 |
+ pax_open_kernel(); |
3681 |
-+ *(void **)&lynxfb_ops.fb_fillrect = lynxfb_ops_fillrect; |
3682 |
-+ *(void **)&lynxfb_ops.fb_copyarea = lynxfb_ops_copyarea; |
3683 |
-+ *(void **)&lynxfb_ops.fb_imageblit = lynxfb_ops_imageblit; |
3684 |
++ const_cast(lynxfb_ops.fb_fillrect) = lynxfb_ops_fillrect; |
3685 |
++ const_cast(lynxfb_ops.fb_copyarea) = lynxfb_ops_copyarea; |
3686 |
++ const_cast(lynxfb_ops.fb_imageblit) = lynxfb_ops_imageblit; |
3687 |
+ pax_close_kernel(); |
3688 |
} |
3689 |
info->fbops = &lynxfb_ops; |
3690 |
@@ -74589,7 +75145,7 @@ index 3072f1a..1071742 100644 |
3691 |
login->tgt_agt = sbp_target_agent_register(login); |
3692 |
if (IS_ERR(login->tgt_agt)) { |
3693 |
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c |
3694 |
-index 6ceac4f..b2ed52c 100644 |
3695 |
+index 6ceac4f..f8059ccd 100644 |
3696 |
--- a/drivers/thermal/cpu_cooling.c |
3697 |
+++ b/drivers/thermal/cpu_cooling.c |
3698 |
@@ -838,10 +838,11 @@ __cpufreq_cooling_register(struct device_node *np, |
3699 |
@@ -74601,9 +75157,9 @@ index 6ceac4f..b2ed52c 100644 |
3700 |
- cpufreq_cooling_ops.state2power = cpufreq_state2power; |
3701 |
- cpufreq_cooling_ops.power2state = cpufreq_power2state; |
3702 |
+ pax_open_kernel(); |
3703 |
-+ *(void **)&cpufreq_cooling_ops.get_requested_power = cpufreq_get_requested_power; |
3704 |
-+ *(void **)&cpufreq_cooling_ops.state2power = cpufreq_state2power; |
3705 |
-+ *(void **)&cpufreq_cooling_ops.power2state = cpufreq_power2state; |
3706 |
++ const_cast(cpufreq_cooling_ops.get_requested_power) = cpufreq_get_requested_power; |
3707 |
++ const_cast(cpufreq_cooling_ops.state2power) = cpufreq_state2power; |
3708 |
++ const_cast(cpufreq_cooling_ops.power2state) = cpufreq_power2state; |
3709 |
+ pax_close_kernel(); |
3710 |
cpufreq_dev->plat_get_static_power = plat_static_func; |
3711 |
|
3712 |
@@ -74655,7 +75211,7 @@ index 01f0015..aa56551 100644 |
3713 |
err = PTR_ERR(cdev); |
3714 |
dev_err(df->dev.parent, |
3715 |
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c |
3716 |
-index 5836e55..740ab89 100644 |
3717 |
+index 5836e55..708bbd6 100644 |
3718 |
--- a/drivers/thermal/int340x_thermal/int3400_thermal.c |
3719 |
+++ b/drivers/thermal/int340x_thermal/int3400_thermal.c |
3720 |
@@ -272,8 +272,10 @@ static int int3400_thermal_probe(struct platform_device *pdev) |
3721 |
@@ -74665,14 +75221,14 @@ index 5836e55..740ab89 100644 |
3722 |
- int3400_thermal_ops.get_mode = int3400_thermal_get_mode; |
3723 |
- int3400_thermal_ops.set_mode = int3400_thermal_set_mode; |
3724 |
+ pax_open_kernel(); |
3725 |
-+ *(void **)&int3400_thermal_ops.get_mode = int3400_thermal_get_mode; |
3726 |
-+ *(void **)&int3400_thermal_ops.set_mode = int3400_thermal_set_mode; |
3727 |
++ const_cast(int3400_thermal_ops.get_mode) = int3400_thermal_get_mode; |
3728 |
++ const_cast(int3400_thermal_ops.set_mode) = int3400_thermal_set_mode; |
3729 |
+ pax_close_kernel(); |
3730 |
} |
3731 |
priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0, |
3732 |
priv, &int3400_thermal_ops, |
3733 |
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c |
3734 |
-index 9043f8f..ab0f354 100644 |
3735 |
+index 9043f8f..1b53349 100644 |
3736 |
--- a/drivers/thermal/of-thermal.c |
3737 |
+++ b/drivers/thermal/of-thermal.c |
3738 |
@@ -31,6 +31,7 @@ |
3739 |
@@ -74691,9 +75247,9 @@ index 9043f8f..ab0f354 100644 |
3740 |
- tzd->ops->get_trend = of_thermal_get_trend; |
3741 |
- tzd->ops->set_emul_temp = of_thermal_set_emul_temp; |
3742 |
+ pax_open_kernel(); |
3743 |
-+ *(void **)&tzd->ops->get_temp = of_thermal_get_temp; |
3744 |
-+ *(void **)&tzd->ops->get_trend = of_thermal_get_trend; |
3745 |
-+ *(void **)&tzd->ops->set_emul_temp = of_thermal_set_emul_temp; |
3746 |
++ const_cast(tzd->ops->get_temp) = of_thermal_get_temp; |
3747 |
++ const_cast(tzd->ops->get_trend) = of_thermal_get_trend; |
3748 |
++ const_cast(tzd->ops->set_emul_temp) = of_thermal_set_emul_temp; |
3749 |
+ pax_close_kernel(); |
3750 |
mutex_unlock(&tzd->lock); |
3751 |
|
3752 |
@@ -74706,9 +75262,9 @@ index 9043f8f..ab0f354 100644 |
3753 |
- tzd->ops->get_trend = NULL; |
3754 |
- tzd->ops->set_emul_temp = NULL; |
3755 |
+ pax_open_kernel(); |
3756 |
-+ *(void **)&tzd->ops->get_temp = NULL; |
3757 |
-+ *(void **)&tzd->ops->get_trend = NULL; |
3758 |
-+ *(void **)&tzd->ops->set_emul_temp = NULL; |
3759 |
++ const_cast(tzd->ops->get_temp) = NULL; |
3760 |
++ const_cast(tzd->ops->get_trend) = NULL; |
3761 |
++ const_cast(tzd->ops->set_emul_temp) = NULL; |
3762 |
+ pax_close_kernel(); |
3763 |
|
3764 |
tz->ops = NULL; |
3765 |
@@ -75289,7 +75845,7 @@ index b280abaa..3ccd7d1 100644 |
3766 |
} |
3767 |
EXPORT_SYMBOL_GPL(n_tty_inherit_ops); |
3768 |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c |
3769 |
-index 2348fa6..14894f4 100644 |
3770 |
+index 2348fa6..490e407 100644 |
3771 |
--- a/drivers/tty/pty.c |
3772 |
+++ b/drivers/tty/pty.c |
3773 |
@@ -879,8 +879,10 @@ static void __init unix98_pty_init(void) |
3774 |
@@ -75299,7 +75855,7 @@ index 2348fa6..14894f4 100644 |
3775 |
+ pax_open_kernel(); |
3776 |
tty_default_fops(&ptmx_fops); |
3777 |
- ptmx_fops.open = ptmx_open; |
3778 |
-+ *(void **)&ptmx_fops.open = ptmx_open; |
3779 |
++ const_cast(ptmx_fops.open) = ptmx_open; |
3780 |
+ pax_close_kernel(); |
3781 |
|
3782 |
cdev_init(&ptmx_cdev, &ptmx_fops); |
3783 |
@@ -75336,7 +75892,7 @@ index 802eac7..f5dcf07 100644 |
3784 |
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); |
3785 |
spin_unlock_irqrestore(&info->port.lock, flags); |
3786 |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c |
3787 |
-index c9720a9..f6c9276 100644 |
3788 |
+index c9720a9..964f2d9 100644 |
3789 |
--- a/drivers/tty/serial/8250/8250_core.c |
3790 |
+++ b/drivers/tty/serial/8250/8250_core.c |
3791 |
@@ -488,9 +488,9 @@ static void univ8250_release_port(struct uart_port *port) |
3792 |
@@ -75346,9 +75902,9 @@ index c9720a9..f6c9276 100644 |
3793 |
- ops->config_port = univ8250_config_port; |
3794 |
- ops->request_port = univ8250_request_port; |
3795 |
- ops->release_port = univ8250_release_port; |
3796 |
-+ *(void **)&ops->config_port = univ8250_config_port; |
3797 |
-+ *(void **)&ops->request_port = univ8250_request_port; |
3798 |
-+ *(void **)&ops->release_port = univ8250_release_port; |
3799 |
++ const_cast(ops->config_port) = univ8250_config_port; |
3800 |
++ const_cast(ops->request_port) = univ8250_request_port; |
3801 |
++ const_cast(ops->release_port) = univ8250_release_port; |
3802 |
} |
3803 |
|
3804 |
#else |
3805 |
@@ -75435,7 +75991,7 @@ index a119f11..120444e 100644 |
3806 |
struct jsm_board *brd = pci_get_drvdata(pdev); |
3807 |
|
3808 |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c |
3809 |
-index 117df15..2f7dfcf 100644 |
3810 |
+index 117df15..8f7486f 100644 |
3811 |
--- a/drivers/tty/serial/kgdb_nmi.c |
3812 |
+++ b/drivers/tty/serial/kgdb_nmi.c |
3813 |
@@ -53,7 +53,9 @@ static int kgdb_nmi_console_setup(struct console *co, char *options) |
3814 |
@@ -75444,7 +76000,7 @@ index 117df15..2f7dfcf 100644 |
3815 |
*/ |
3816 |
- dbg_io_ops->is_console = true; |
3817 |
+ pax_open_kernel(); |
3818 |
-+ *(int *)&dbg_io_ops->is_console = true; |
3819 |
++ const_cast(dbg_io_ops->is_console) = true; |
3820 |
+ pax_close_kernel(); |
3821 |
|
3822 |
return 0; |
3823 |
@@ -76984,6 +77540,105 @@ index 48672fa..9245081 100644 |
3824 |
|
3825 |
/* Device for a quirk */ |
3826 |
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 |
3827 |
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c |
3828 |
+index a85a1c9..0f198bc 100644 |
3829 |
+--- a/drivers/usb/host/xhci-ring.c |
3830 |
++++ b/drivers/usb/host/xhci-ring.c |
3831 |
+@@ -1861,9 +1861,9 @@ td_cleanup: |
3832 |
+ * unsigned). Play it safe and say we didn't transfer anything. |
3833 |
+ */ |
3834 |
+ if (urb->actual_length > urb->transfer_buffer_length) { |
3835 |
+- xhci_warn(xhci, "URB transfer length is wrong, xHC issue? req. len = %u, act. len = %u\n", |
3836 |
++ xhci_warn(xhci, "URB transfer length is wrong, xHC issue? req. len = %u, trans. len = %u\n", |
3837 |
+ urb->transfer_buffer_length, |
3838 |
+- urb->actual_length); |
3839 |
++ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); |
3840 |
+ urb->actual_length = 0; |
3841 |
+ if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
3842 |
+ *status = -EREMOTEIO; |
3843 |
+@@ -1942,10 +1942,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, |
3844 |
+ return finish_td(xhci, td, event_trb, event, ep, status, false); |
3845 |
+ case COMP_STOP: |
3846 |
+ /* Did we stop at data stage? */ |
3847 |
+- if (event_trb != ep_ring->dequeue && event_trb != td->last_trb) |
3848 |
+- td->urb->actual_length = |
3849 |
+- td->urb->transfer_buffer_length - |
3850 |
+- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3851 |
++ if (event_trb != ep_ring->dequeue && event_trb != td->last_trb) { |
3852 |
++ if (td->urb->transfer_buffer_length >= EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))) |
3853 |
++ td->urb->actual_length = |
3854 |
++ td->urb->transfer_buffer_length - |
3855 |
++ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3856 |
++ else |
3857 |
++ td->urb->actual_length = |
3858 |
++ td->urb->transfer_buffer_length + 1; |
3859 |
++ } |
3860 |
+ /* fall through */ |
3861 |
+ case COMP_STOP_INVAL: |
3862 |
+ return finish_td(xhci, td, event_trb, event, ep, status, false); |
3863 |
+@@ -1959,12 +1964,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, |
3864 |
+ /* else fall through */ |
3865 |
+ case COMP_STALL: |
3866 |
+ /* Did we transfer part of the data (middle) phase? */ |
3867 |
+- if (event_trb != ep_ring->dequeue && |
3868 |
+- event_trb != td->last_trb) |
3869 |
+- td->urb->actual_length = |
3870 |
+- td->urb->transfer_buffer_length - |
3871 |
+- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3872 |
+- else if (!td->urb_length_set) |
3873 |
++ if (event_trb != ep_ring->dequeue && event_trb != td->last_trb) { |
3874 |
++ if (td->urb->transfer_buffer_length >= EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))) |
3875 |
++ td->urb->actual_length = |
3876 |
++ td->urb->transfer_buffer_length - |
3877 |
++ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3878 |
++ else |
3879 |
++ td->urb->actual_length = |
3880 |
++ td->urb->transfer_buffer_length + 1; |
3881 |
++ } else if (!td->urb_length_set) |
3882 |
+ td->urb->actual_length = 0; |
3883 |
+ |
3884 |
+ return finish_td(xhci, td, event_trb, event, ep, status, false); |
3885 |
+@@ -1997,9 +2005,12 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, |
3886 |
+ * the last TRB. |
3887 |
+ */ |
3888 |
+ td->urb_length_set = true; |
3889 |
+- td->urb->actual_length = |
3890 |
+- td->urb->transfer_buffer_length - |
3891 |
+- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3892 |
++ if (td->urb->transfer_buffer_length >= EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))) |
3893 |
++ td->urb->actual_length = |
3894 |
++ td->urb->transfer_buffer_length - |
3895 |
++ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3896 |
++ else |
3897 |
++ BUG(); |
3898 |
+ xhci_dbg(xhci, "Waiting for status " |
3899 |
+ "stage event\n"); |
3900 |
+ return 0; |
3901 |
+@@ -2194,11 +2205,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, |
3902 |
+ /* Fast path - was this the last TRB in the TD for this URB? */ |
3903 |
+ } else if (event_trb == td->last_trb) { |
3904 |
+ if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
3905 |
+- td->urb->actual_length = |
3906 |
+- td->urb->transfer_buffer_length - |
3907 |
+- EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3908 |
+- if (td->urb->transfer_buffer_length < |
3909 |
+- td->urb->actual_length) { |
3910 |
++ if (td->urb->transfer_buffer_length < EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))) { |
3911 |
+ xhci_warn(xhci, "HC gave bad length " |
3912 |
+ "of %d bytes left\n", |
3913 |
+ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); |
3914 |
+@@ -2207,7 +2214,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, |
3915 |
+ *status = -EREMOTEIO; |
3916 |
+ else |
3917 |
+ *status = 0; |
3918 |
+- } |
3919 |
++ } else |
3920 |
++ td->urb->actual_length = |
3921 |
++ td->urb->transfer_buffer_length - |
3922 |
++ EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
3923 |
+ /* Don't overwrite a previously set error code */ |
3924 |
+ if (*status == -EINPROGRESS) { |
3925 |
+ if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
3926 |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c |
3927 |
index 8e713cc..8c92a15 100644 |
3928 |
--- a/drivers/usb/host/xhci.c |
3929 |
@@ -77621,7 +78276,7 @@ index c42ce2f..4c8bc59 100644 |
3930 |
"PCI", |
3931 |
"PRO AGP", |
3932 |
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c |
3933 |
-index f34ed47f..026367f 100644 |
3934 |
+index f34ed47f..7283c9f 100644 |
3935 |
--- a/drivers/video/fbdev/aty/atyfb_base.c |
3936 |
+++ b/drivers/video/fbdev/aty/atyfb_base.c |
3937 |
@@ -1335,10 +1335,14 @@ static int atyfb_set_par(struct fb_info *info) |
3938 |
@@ -77630,13 +78285,13 @@ index f34ed47f..026367f 100644 |
3939 |
if (var->accel_flags) { |
3940 |
- info->fbops->fb_sync = atyfb_sync; |
3941 |
+ pax_open_kernel(); |
3942 |
-+ *(void **)&info->fbops->fb_sync = atyfb_sync; |
3943 |
++ const_cast(info->fbops->fb_sync) = atyfb_sync; |
3944 |
+ pax_close_kernel(); |
3945 |
info->flags &= ~FBINFO_HWACCEL_DISABLED; |
3946 |
} else { |
3947 |
- info->fbops->fb_sync = NULL; |
3948 |
+ pax_open_kernel(); |
3949 |
-+ *(void **)&info->fbops->fb_sync = NULL; |
3950 |
++ const_cast(info->fbops->fb_sync) = NULL; |
3951 |
+ pax_close_kernel(); |
3952 |
info->flags |= FBINFO_HWACCEL_DISABLED; |
3953 |
} |
3954 |
@@ -77663,7 +78318,7 @@ index 51f29d6..2c15339 100644 |
3955 |
|
3956 |
const struct aty_pll_ops aty_pll_ct = { |
3957 |
diff --git a/drivers/video/fbdev/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c |
3958 |
-index 2fa0317..4983f2a 100644 |
3959 |
+index 2fa0317..d687dab 100644 |
3960 |
--- a/drivers/video/fbdev/aty/mach64_cursor.c |
3961 |
+++ b/drivers/video/fbdev/aty/mach64_cursor.c |
3962 |
@@ -8,6 +8,7 @@ |
3963 |
@@ -77680,7 +78335,7 @@ index 2fa0317..4983f2a 100644 |
3964 |
|
3965 |
- info->fbops->fb_cursor = atyfb_cursor; |
3966 |
+ pax_open_kernel(); |
3967 |
-+ *(void **)&info->fbops->fb_cursor = atyfb_cursor; |
3968 |
++ const_cast(info->fbops->fb_cursor) = atyfb_cursor; |
3969 |
+ pax_close_kernel(); |
3970 |
|
3971 |
return 0; |
3972 |
@@ -77721,7 +78376,7 @@ index 10c988a..f7d9299 100644 |
3973 |
+ .set_pll = aty_set_pll, |
3974 |
}; |
3975 |
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c |
3976 |
-index 57721c7..55142ed 100644 |
3977 |
+index 57721c7..332b94b 100644 |
3978 |
--- a/drivers/video/fbdev/core/fb_defio.c |
3979 |
+++ b/drivers/video/fbdev/core/fb_defio.c |
3980 |
@@ -207,7 +207,9 @@ void fb_deferred_io_init(struct fb_info *info) |
3981 |
@@ -77730,17 +78385,19 @@ index 57721c7..55142ed 100644 |
3982 |
mutex_init(&fbdefio->lock); |
3983 |
- info->fbops->fb_mmap = fb_deferred_io_mmap; |
3984 |
+ pax_open_kernel(); |
3985 |
-+ *(void **)&info->fbops->fb_mmap = fb_deferred_io_mmap; |
3986 |
++ const_cast(info->fbops->fb_mmap) = fb_deferred_io_mmap; |
3987 |
+ pax_close_kernel(); |
3988 |
INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work); |
3989 |
INIT_LIST_HEAD(&fbdefio->pagelist); |
3990 |
if (fbdefio->delay == 0) /* set a default of 1 s */ |
3991 |
-@@ -238,7 +240,7 @@ void fb_deferred_io_cleanup(struct fb_info *info) |
3992 |
+@@ -238,7 +240,9 @@ void fb_deferred_io_cleanup(struct fb_info *info) |
3993 |
page->mapping = NULL; |
3994 |
} |
3995 |
|
3996 |
- info->fbops->fb_mmap = NULL; |
3997 |
-+ *(void **)&info->fbops->fb_mmap = NULL; |
3998 |
++ pax_open_kernel(); |
3999 |
++ const_cast(info->fbops->fb_mmap) = NULL; |
4000 |
++ pax_close_kernel(); |
4001 |
mutex_destroy(&fbdefio->lock); |
4002 |
} |
4003 |
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); |
4004 |
@@ -77872,7 +78529,7 @@ index 11eb094..622ee31 100644 |
4005 |
{ 640, 480, 48, 16, 33, 10, 96, 2, 60 }, |
4006 |
{ 800, 600, 144, 24, 28, 8, 112, 6, 60 }, |
4007 |
diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c |
4008 |
-index fe92eed..106e085 100644 |
4009 |
+index fe92eed..239e386 100644 |
4010 |
--- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c |
4011 |
+++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c |
4012 |
@@ -312,14 +312,18 @@ void mb862xxfb_init_accel(struct fb_info *info, int xres) |
4013 |
@@ -77883,9 +78540,9 @@ index fe92eed..106e085 100644 |
4014 |
- info->fbops->fb_copyarea = cfb_copyarea; |
4015 |
- info->fbops->fb_imageblit = cfb_imageblit; |
4016 |
+ pax_open_kernel(); |
4017 |
-+ *(void **)&info->fbops->fb_fillrect = cfb_fillrect; |
4018 |
-+ *(void **)&info->fbops->fb_copyarea = cfb_copyarea; |
4019 |
-+ *(void **)&info->fbops->fb_imageblit = cfb_imageblit; |
4020 |
++ const_cast(info->fbops->fb_fillrect) = cfb_fillrect; |
4021 |
++ const_cast(info->fbops->fb_copyarea) = cfb_copyarea; |
4022 |
++ const_cast(info->fbops->fb_imageblit) = cfb_imageblit; |
4023 |
+ pax_close_kernel(); |
4024 |
} else { |
4025 |
outreg(disp, GC_L0EM, 3); |
4026 |
@@ -77893,15 +78550,15 @@ index fe92eed..106e085 100644 |
4027 |
- info->fbops->fb_copyarea = mb86290fb_copyarea; |
4028 |
- info->fbops->fb_imageblit = mb86290fb_imageblit; |
4029 |
+ pax_open_kernel(); |
4030 |
-+ *(void **)&info->fbops->fb_fillrect = mb86290fb_fillrect; |
4031 |
-+ *(void **)&info->fbops->fb_copyarea = mb86290fb_copyarea; |
4032 |
-+ *(void **)&info->fbops->fb_imageblit = mb86290fb_imageblit; |
4033 |
++ const_cast(info->fbops->fb_fillrect) = mb86290fb_fillrect; |
4034 |
++ const_cast(info->fbops->fb_copyarea) = mb86290fb_copyarea; |
4035 |
++ const_cast(info->fbops->fb_imageblit) = mb86290fb_imageblit; |
4036 |
+ pax_close_kernel(); |
4037 |
} |
4038 |
outreg(draw, GDC_REG_DRAW_BASE, 0); |
4039 |
outreg(draw, GDC_REG_MODE_MISC, 0x8000); |
4040 |
diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c |
4041 |
-index ce7dab7..a87baf8 100644 |
4042 |
+index ce7dab7..89d6521 100644 |
4043 |
--- a/drivers/video/fbdev/nvidia/nvidia.c |
4044 |
+++ b/drivers/video/fbdev/nvidia/nvidia.c |
4045 |
@@ -660,19 +660,23 @@ static int nvidiafb_set_par(struct fb_info *info) |
4046 |
@@ -77913,10 +78570,10 @@ index ce7dab7..a87baf8 100644 |
4047 |
- info->fbops->fb_copyarea = nvidiafb_copyarea; |
4048 |
- info->fbops->fb_sync = nvidiafb_sync; |
4049 |
+ pax_open_kernel(); |
4050 |
-+ *(void **)&info->fbops->fb_imageblit = nvidiafb_imageblit; |
4051 |
-+ *(void **)&info->fbops->fb_fillrect = nvidiafb_fillrect; |
4052 |
-+ *(void **)&info->fbops->fb_copyarea = nvidiafb_copyarea; |
4053 |
-+ *(void **)&info->fbops->fb_sync = nvidiafb_sync; |
4054 |
++ const_cast(info->fbops->fb_imageblit) = nvidiafb_imageblit; |
4055 |
++ const_cast(info->fbops->fb_fillrect) = nvidiafb_fillrect; |
4056 |
++ const_cast(info->fbops->fb_copyarea) = nvidiafb_copyarea; |
4057 |
++ const_cast(info->fbops->fb_sync) = nvidiafb_sync; |
4058 |
+ pax_close_kernel(); |
4059 |
info->pixmap.scan_align = 4; |
4060 |
info->flags &= ~FBINFO_HWACCEL_DISABLED; |
4061 |
@@ -77928,10 +78585,10 @@ index ce7dab7..a87baf8 100644 |
4062 |
- info->fbops->fb_copyarea = cfb_copyarea; |
4063 |
- info->fbops->fb_sync = NULL; |
4064 |
+ pax_open_kernel(); |
4065 |
-+ *(void **)&info->fbops->fb_imageblit = cfb_imageblit; |
4066 |
-+ *(void **)&info->fbops->fb_fillrect = cfb_fillrect; |
4067 |
-+ *(void **)&info->fbops->fb_copyarea = cfb_copyarea; |
4068 |
-+ *(void **)&info->fbops->fb_sync = NULL; |
4069 |
++ const_cast(info->fbops->fb_imageblit) = cfb_imageblit; |
4070 |
++ const_cast(info->fbops->fb_fillrect) = cfb_fillrect; |
4071 |
++ const_cast(info->fbops->fb_copyarea) = cfb_copyarea; |
4072 |
++ const_cast(info->fbops->fb_sync) = NULL; |
4073 |
+ pax_close_kernel(); |
4074 |
info->pixmap.scan_align = 1; |
4075 |
info->flags |= FBINFO_HWACCEL_DISABLED; |
4076 |
@@ -77944,14 +78601,14 @@ index ce7dab7..a87baf8 100644 |
4077 |
- info->fbops->fb_cursor = NULL; |
4078 |
+ if (!hwcur) { |
4079 |
+ pax_open_kernel(); |
4080 |
-+ *(void **)&info->fbops->fb_cursor = NULL; |
4081 |
++ const_cast(info->fbops->fb_cursor) = NULL; |
4082 |
+ pax_close_kernel(); |
4083 |
+ } |
4084 |
|
4085 |
info->var.accel_flags = (!noaccel); |
4086 |
|
4087 |
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/display.c b/drivers/video/fbdev/omap2/omapfb/dss/display.c |
4088 |
-index ef5b902..47cf7f5 100644 |
4089 |
+index ef5b902..2ae011b 100644 |
4090 |
--- a/drivers/video/fbdev/omap2/omapfb/dss/display.c |
4091 |
+++ b/drivers/video/fbdev/omap2/omapfb/dss/display.c |
4092 |
@@ -161,12 +161,14 @@ int omapdss_register_display(struct omap_dss_device *dssdev) |
4093 |
@@ -77961,19 +78618,19 @@ index ef5b902..47cf7f5 100644 |
4094 |
+ pax_open_kernel(); |
4095 |
if (drv && drv->get_resolution == NULL) |
4096 |
- drv->get_resolution = omapdss_default_get_resolution; |
4097 |
-+ *(void **)&drv->get_resolution = omapdss_default_get_resolution; |
4098 |
++ const_cast(drv->get_resolution) = omapdss_default_get_resolution; |
4099 |
if (drv && drv->get_recommended_bpp == NULL) |
4100 |
- drv->get_recommended_bpp = omapdss_default_get_recommended_bpp; |
4101 |
-+ *(void **)&drv->get_recommended_bpp = omapdss_default_get_recommended_bpp; |
4102 |
++ const_cast(drv->get_recommended_bpp) = omapdss_default_get_recommended_bpp; |
4103 |
if (drv && drv->get_timings == NULL) |
4104 |
- drv->get_timings = omapdss_default_get_timings; |
4105 |
-+ *(void **)&drv->get_timings = omapdss_default_get_timings; |
4106 |
++ const_cast(drv->get_timings) = omapdss_default_get_timings; |
4107 |
+ pax_close_kernel(); |
4108 |
|
4109 |
mutex_lock(&panel_list_mutex); |
4110 |
list_add_tail(&dssdev->panel_list, &panel_list); |
4111 |
diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c |
4112 |
-index 96aa46d..c67c213 100644 |
4113 |
+index 96aa46d..65e2554 100644 |
4114 |
--- a/drivers/video/fbdev/s1d13xxxfb.c |
4115 |
+++ b/drivers/video/fbdev/s1d13xxxfb.c |
4116 |
@@ -880,8 +880,10 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) |
4117 |
@@ -77983,8 +78640,8 @@ index 96aa46d..c67c213 100644 |
4118 |
- s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; |
4119 |
- s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; |
4120 |
+ pax_open_kernel(); |
4121 |
-+ *(void **)&s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; |
4122 |
-+ *(void **)&s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; |
4123 |
++ const_cast(s1d13xxxfb_fbops.fb_fillrect) = s1d13xxxfb_bitblt_solidfill; |
4124 |
++ const_cast(s1d13xxxfb_fbops.fb_copyarea) = s1d13xxxfb_bitblt_copyarea; |
4125 |
+ pax_close_kernel(); |
4126 |
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | |
4127 |
FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; |
4128 |
@@ -78020,7 +78677,7 @@ index 32e23c2..7b73082 100644 |
4129 |
extern void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo); |
4130 |
extern unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, |
4131 |
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c |
4132 |
-index 9279e5f..d5f5276 100644 |
4133 |
+index 9279e5f..d9fb0bd 100644 |
4134 |
--- a/drivers/video/fbdev/smscufx.c |
4135 |
+++ b/drivers/video/fbdev/smscufx.c |
4136 |
@@ -1174,7 +1174,9 @@ static int ufx_ops_release(struct fb_info *info, int user) |
4137 |
@@ -78029,13 +78686,13 @@ index 9279e5f..d5f5276 100644 |
4138 |
info->fbdefio = NULL; |
4139 |
- info->fbops->fb_mmap = ufx_ops_mmap; |
4140 |
+ pax_open_kernel(); |
4141 |
-+ *(void **)&info->fbops->fb_mmap = ufx_ops_mmap; |
4142 |
++ const_cast(info->fbops->fb_mmap) = ufx_ops_mmap; |
4143 |
+ pax_close_kernel(); |
4144 |
} |
4145 |
|
4146 |
pr_debug("released /dev/fb%d user=%d count=%d", |
4147 |
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c |
4148 |
-index e9c2f7b..8df1264 100644 |
4149 |
+index e9c2f7b..87506f4 100644 |
4150 |
--- a/drivers/video/fbdev/udlfb.c |
4151 |
+++ b/drivers/video/fbdev/udlfb.c |
4152 |
@@ -623,11 +623,11 @@ static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y, |
4153 |
@@ -78076,7 +78733,7 @@ index e9c2f7b..8df1264 100644 |
4154 |
info->fbdefio = NULL; |
4155 |
- info->fbops->fb_mmap = dlfb_ops_mmap; |
4156 |
+ pax_open_kernel(); |
4157 |
-+ *(void **)&info->fbops->fb_mmap = dlfb_ops_mmap; |
4158 |
++ const_cast(info->fbops->fb_mmap) = dlfb_ops_mmap; |
4159 |
+ pax_close_kernel(); |
4160 |
} |
4161 |
|
4162 |
@@ -78133,7 +78790,7 @@ index e9c2f7b..8df1264 100644 |
4163 |
return count; |
4164 |
} |
4165 |
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c |
4166 |
-index 178ae93..624b2eb 100644 |
4167 |
+index 178ae93..043ddca 100644 |
4168 |
--- a/drivers/video/fbdev/uvesafb.c |
4169 |
+++ b/drivers/video/fbdev/uvesafb.c |
4170 |
@@ -19,6 +19,7 @@ |
4171 |
@@ -78202,7 +78859,7 @@ index 178ae93..624b2eb 100644 |
4172 |
- info->fbops->fb_blank = NULL; |
4173 |
+ if (!blank) { |
4174 |
+ pax_open_kernel(); |
4175 |
-+ *(void **)&info->fbops->fb_blank = NULL; |
4176 |
++ const_cast(info->fbops->fb_blank) = NULL; |
4177 |
+ pax_close_kernel(); |
4178 |
+ } |
4179 |
|
4180 |
@@ -78216,7 +78873,7 @@ index 178ae93..624b2eb 100644 |
4181 |
- info->fbops->fb_pan_display = NULL; |
4182 |
+ if (!par->ypan) { |
4183 |
+ pax_open_kernel(); |
4184 |
-+ *(void **)&info->fbops->fb_pan_display = NULL; |
4185 |
++ const_cast(info->fbops->fb_pan_display) = NULL; |
4186 |
+ pax_close_kernel(); |
4187 |
+ } |
4188 |
} |
4189 |
@@ -78247,7 +78904,7 @@ index 178ae93..624b2eb 100644 |
4190 |
} |
4191 |
return 0; |
4192 |
diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c |
4193 |
-index 528fe91..6fd29fe 100644 |
4194 |
+index 528fe91..475d9e6 100644 |
4195 |
--- a/drivers/video/fbdev/vesafb.c |
4196 |
+++ b/drivers/video/fbdev/vesafb.c |
4197 |
@@ -9,6 +9,7 @@ |
4198 |
@@ -78348,7 +79005,7 @@ index 528fe91..6fd29fe 100644 |
4199 |
- info->fbops->fb_pan_display = NULL; |
4200 |
+ if (!ypan) { |
4201 |
+ pax_open_kernel(); |
4202 |
-+ *(void **)&info->fbops->fb_pan_display = NULL; |
4203 |
++ const_cast(info->fbops->fb_pan_display) = NULL; |
4204 |
+ pax_close_kernel(); |
4205 |
+ } |
4206 |
|
4207 |
@@ -99826,7 +100483,7 @@ index 7cfa0aa..d5ef97b7 100644 |
4208 |
seq_printf(m, "CacheOp: alo=%d luo=%d luc=%d gro=%d\n", |
4209 |
atomic_read(&fscache_n_cop_alloc_object), |
4210 |
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c |
4211 |
-index c5b6b71..3949af6 100644 |
4212 |
+index c5b6b71..527e347 100644 |
4213 |
--- a/fs/fuse/cuse.c |
4214 |
+++ b/fs/fuse/cuse.c |
4215 |
@@ -611,10 +611,12 @@ static int __init cuse_init(void) |
4216 |
@@ -99839,9 +100496,9 @@ index c5b6b71..3949af6 100644 |
4217 |
- cuse_channel_fops.release = cuse_channel_release; |
4218 |
+ pax_open_kernel(); |
4219 |
+ memcpy((void *)&cuse_channel_fops, &fuse_dev_operations, sizeof(fuse_dev_operations)); |
4220 |
-+ *(void **)&cuse_channel_fops.owner = THIS_MODULE; |
4221 |
-+ *(void **)&cuse_channel_fops.open = cuse_channel_open; |
4222 |
-+ *(void **)&cuse_channel_fops.release = cuse_channel_release; |
4223 |
++ const_cast(cuse_channel_fops.owner) = THIS_MODULE; |
4224 |
++ const_cast(cuse_channel_fops.open) = cuse_channel_open; |
4225 |
++ const_cast(cuse_channel_fops.release) = cuse_channel_release; |
4226 |
+ pax_close_kernel(); |
4227 |
|
4228 |
cuse_class = class_create(THIS_MODULE, "cuse"); |
4229 |
@@ -100191,7 +100848,7 @@ index 4a6cf28..d3a29d3 100644 |
4230 |
|
4231 |
jffs2_prealloc_raw_node_refs(c, jeb, 1); |
4232 |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c |
4233 |
-index cad86ba..a0bfc33 100644 |
4234 |
+index cad86ba..7de4d99 100644 |
4235 |
--- a/fs/jffs2/file.c |
4236 |
+++ b/fs/jffs2/file.c |
4237 |
@@ -111,8 +111,9 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) |
4238 |
@@ -100205,6 +100862,15 @@ index cad86ba..a0bfc33 100644 |
4239 |
int ret = jffs2_do_readpage_nolock(inode, pg); |
4240 |
unlock_page(pg); |
4241 |
return ret; |
4242 |
+@@ -125,7 +126,7 @@ static int jffs2_readpage (struct file *filp, struct page *pg) |
4243 |
+ int ret; |
4244 |
+ |
4245 |
+ mutex_lock(&f->sem); |
4246 |
+- ret = jffs2_do_readpage_unlock(pg->mapping->host, pg); |
4247 |
++ ret = jffs2_do_readpage_unlock((struct file *)pg->mapping->host, pg); |
4248 |
+ mutex_unlock(&f->sem); |
4249 |
+ return ret; |
4250 |
+ } |
4251 |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c |
4252 |
index bead25a..5186b1c 100644 |
4253 |
--- a/fs/jffs2/fs.c |
4254 |
@@ -110271,7 +110937,7 @@ index d955481..a985dc41 100644 |
4255 |
|
4256 |
#endif |
4257 |
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c |
4258 |
-index 52ccd34..7a6b202 100644 |
4259 |
+index 52ccd34..a166501 100644 |
4260 |
--- a/fs/nls/nls_base.c |
4261 |
+++ b/fs/nls/nls_base.c |
4262 |
@@ -234,21 +234,25 @@ EXPORT_SYMBOL(utf16s_to_utf8s); |
4263 |
@@ -110286,7 +110952,7 @@ index 52ccd34..7a6b202 100644 |
4264 |
|
4265 |
- nls->owner = owner; |
4266 |
+ pax_open_kernel(); |
4267 |
-+ *(void **)&nls->owner = owner; |
4268 |
++ const_cast(nls->owner) = owner; |
4269 |
+ pax_close_kernel(); |
4270 |
spin_lock(&nls_lock); |
4271 |
- while (*tmp) { |
4272 |
@@ -110301,7 +110967,7 @@ index 52ccd34..7a6b202 100644 |
4273 |
} |
4274 |
- nls->next = tables; |
4275 |
+ pax_open_kernel(); |
4276 |
-+ *(struct nls_table **)&nls->next = tables; |
4277 |
++ const_cast(nls->next) = tables; |
4278 |
+ pax_close_kernel(); |
4279 |
tables = nls; |
4280 |
spin_unlock(&nls_lock); |
4281 |
@@ -110394,7 +111060,7 @@ index 8e14187..d9cec2f 100644 |
4282 |
{ |
4283 |
const unsigned char *uni2charset; |
4284 |
diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c |
4285 |
-index 162b3f1..2cb932a 100644 |
4286 |
+index 162b3f1..b9121f8 100644 |
4287 |
--- a/fs/nls/nls_euc-jp.c |
4288 |
+++ b/fs/nls/nls_euc-jp.c |
4289 |
@@ -406,7 +406,7 @@ static inline int sjisnec2sjisibm(unsigned char *sjisibm, |
4290 |
@@ -110413,14 +111079,14 @@ index 162b3f1..2cb932a 100644 |
4291 |
- table.charset2upper = p_nls->charset2upper; |
4292 |
- table.charset2lower = p_nls->charset2lower; |
4293 |
+ pax_open_kernel(); |
4294 |
-+ *(const unsigned char **)&table.charset2upper = p_nls->charset2upper; |
4295 |
-+ *(const unsigned char **)&table.charset2lower = p_nls->charset2lower; |
4296 |
++ const_cast(table.charset2upper) = p_nls->charset2upper; |
4297 |
++ const_cast(table.charset2lower) = p_nls->charset2lower; |
4298 |
+ pax_close_kernel(); |
4299 |
return register_nls(&table); |
4300 |
} |
4301 |
|
4302 |
diff --git a/fs/nls/nls_koi8-ru.c b/fs/nls/nls_koi8-ru.c |
4303 |
-index a80a741..13030f7 100644 |
4304 |
+index a80a741..f28c9c9 100644 |
4305 |
--- a/fs/nls/nls_koi8-ru.c |
4306 |
+++ b/fs/nls/nls_koi8-ru.c |
4307 |
@@ -13,7 +13,7 @@ |
4308 |
@@ -110439,8 +111105,8 @@ index a80a741..13030f7 100644 |
4309 |
- table.charset2upper = p_nls->charset2upper; |
4310 |
- table.charset2lower = p_nls->charset2lower; |
4311 |
+ pax_open_kernel(); |
4312 |
-+ *(const unsigned char **)&table.charset2upper = p_nls->charset2upper; |
4313 |
-+ *(const unsigned char **)&table.charset2lower = p_nls->charset2lower; |
4314 |
++ const_cast(table.charset2upper) = p_nls->charset2upper; |
4315 |
++ const_cast(table.charset2lower) = p_nls->charset2lower; |
4316 |
+ pax_close_kernel(); |
4317 |
return register_nls(&table); |
4318 |
} |
4319 |
@@ -112482,7 +113148,7 @@ index 350984a..0fb02a9 100644 |
4320 |
net = get_proc_net(inode); |
4321 |
if (net == NULL) |
4322 |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c |
4323 |
-index fe5b6e6..e5f3883 100644 |
4324 |
+index fe5b6e6..cd2913c 100644 |
4325 |
--- a/fs/proc/proc_sysctl.c |
4326 |
+++ b/fs/proc/proc_sysctl.c |
4327 |
@@ -11,13 +11,21 @@ |
4328 |
@@ -112515,7 +113181,7 @@ index fe5b6e6..e5f3883 100644 |
4329 |
{ |
4330 |
- dir->header.ctl_table[0].child = sysctl_mount_point; |
4331 |
+ pax_open_kernel(); |
4332 |
-+ *(const void **)&dir->header.ctl_table[0].child = sysctl_mount_point; |
4333 |
++ const_cast(dir->header.ctl_table[0].child) = sysctl_mount_point; |
4334 |
+ pax_close_kernel(); |
4335 |
} |
4336 |
|
4337 |
@@ -112524,7 +113190,7 @@ index fe5b6e6..e5f3883 100644 |
4338 |
{ |
4339 |
- dir->header.ctl_table[0].child = NULL; |
4340 |
+ pax_open_kernel(); |
4341 |
-+ *(void **)&dir->header.ctl_table[0].child = NULL; |
4342 |
++ const_cast(dir->header.ctl_table[0].child) = NULL; |
4343 |
+ pax_close_kernel(); |
4344 |
} |
4345 |
|
4346 |
@@ -112565,7 +113231,7 @@ index fe5b6e6..e5f3883 100644 |
4347 |
+ if (gr_handle_chroot_sysctl(op)) |
4348 |
+ goto out; |
4349 |
+ dget(filp->f_path.dentry); |
4350 |
-+ if (gr_handle_sysctl_mod(filp->f_path.dentry->d_parent->d_name.name, table->procname, op)) { |
4351 |
++ if (gr_handle_sysctl_mod((const char *)filp->f_path.dentry->d_parent->d_name.name, table->procname, op)) { |
4352 |
+ dput(filp->f_path.dentry); |
4353 |
+ goto out; |
4354 |
+ } |
4355 |
@@ -113941,7 +114607,7 @@ index 6c21228..9afd5fe 100644 |
4356 |
if (sbi->s_bytesex == BYTESEX_PDP) |
4357 |
return PDP_swab((__force __u32)n); |
4358 |
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c |
4359 |
-index 4a0e48f..ca5b016 100644 |
4360 |
+index 4a0e48f..d3e1fbf 100644 |
4361 |
--- a/fs/tracefs/inode.c |
4362 |
+++ b/fs/tracefs/inode.c |
4363 |
@@ -53,7 +53,7 @@ static const struct file_operations tracefs_file_operations = { |
4364 |
@@ -113960,8 +114626,8 @@ index 4a0e48f..ca5b016 100644 |
4365 |
- tracefs_ops.mkdir = mkdir; |
4366 |
- tracefs_ops.rmdir = rmdir; |
4367 |
+ pax_open_kernel(); |
4368 |
-+ *(void **)&tracefs_ops.mkdir = mkdir; |
4369 |
-+ *(void **)&tracefs_ops.rmdir = rmdir; |
4370 |
++ const_cast(tracefs_ops.mkdir) = mkdir; |
4371 |
++ const_cast(tracefs_ops.rmdir) = rmdir; |
4372 |
+ pax_close_kernel(); |
4373 |
|
4374 |
return dentry; |
4375 |
@@ -115665,7 +116331,7 @@ index 0000000..e136e5f |
4376 |
+endif |
4377 |
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c |
4378 |
new file mode 100644 |
4379 |
-index 0000000..7ad630a |
4380 |
+index 0000000..3c66319 |
4381 |
--- /dev/null |
4382 |
+++ b/grsecurity/gracl.c |
4383 |
@@ -0,0 +1,2757 @@ |
4384 |
@@ -115867,7 +116533,7 @@ index 0000000..7ad630a |
4385 |
+ |
4386 |
+static int prepend_name(char **buffer, int *buflen, struct qstr *name) |
4387 |
+{ |
4388 |
-+ return prepend(buffer, buflen, name->name, name->len); |
4389 |
++ return prepend(buffer, buflen, (const char *)name->name, name->len); |
4390 |
+} |
4391 |
+ |
4392 |
+static int prepend_path(const struct path *path, struct path *root, |
4393 |
@@ -116231,7 +116897,7 @@ index 0000000..7ad630a |
4394 |
+__lookup_name_entry(const struct gr_policy_state *state, const char *name) |
4395 |
+{ |
4396 |
+ unsigned int len = strlen(name); |
4397 |
-+ unsigned int key = full_name_hash(name, len); |
4398 |
++ unsigned int key = full_name_hash((const unsigned char *)name, len); |
4399 |
+ unsigned int index = key % state->name_set.n_size; |
4400 |
+ struct name_entry *match; |
4401 |
+ |
4402 |
@@ -116253,7 +116919,7 @@ index 0000000..7ad630a |
4403 |
+lookup_name_entry_create(const char *name) |
4404 |
+{ |
4405 |
+ unsigned int len = strlen(name); |
4406 |
-+ unsigned int key = full_name_hash(name, len); |
4407 |
++ unsigned int key = full_name_hash((const unsigned char *)name, len); |
4408 |
+ unsigned int index = key % running_polstate.name_set.n_size; |
4409 |
+ struct name_entry *match; |
4410 |
+ |
4411 |
@@ -120006,7 +120672,7 @@ index 0000000..25f54ef |
4412 |
+}; |
4413 |
diff --git a/grsecurity/gracl_policy.c b/grsecurity/gracl_policy.c |
4414 |
new file mode 100644 |
4415 |
-index 0000000..302bda8 |
4416 |
+index 0000000..2fc92ec |
4417 |
--- /dev/null |
4418 |
+++ b/grsecurity/gracl_policy.c |
4419 |
@@ -0,0 +1,1784 @@ |
4420 |
@@ -120362,7 +121028,7 @@ index 0000000..302bda8 |
4421 |
+ struct name_entry **curr, *nentry; |
4422 |
+ struct inodev_entry *ientry; |
4423 |
+ unsigned int len = strlen(name); |
4424 |
-+ unsigned int key = full_name_hash(name, len); |
4425 |
++ unsigned int key = full_name_hash((const unsigned char *)name, len); |
4426 |
+ unsigned int index = key % polstate->name_set.n_size; |
4427 |
+ |
4428 |
+ curr = &polstate->name_set.n_hash[index]; |
4429 |
@@ -121387,7 +122053,7 @@ index 0000000..302bda8 |
4430 |
+ FOR_EACH_ROLE_END(r) |
4431 |
+ |
4432 |
+ for (i = 0; i < polstate->num_sprole_pws; i++) { |
4433 |
-+ if (!strcmp(rolename, polstate->acl_special_roles[i]->rolename)) { |
4434 |
++ if (!strcmp(rolename, (const char *)polstate->acl_special_roles[i]->rolename)) { |
4435 |
+ *salt = polstate->acl_special_roles[i]->salt; |
4436 |
+ *sum = polstate->acl_special_roles[i]->sum; |
4437 |
+ return 1; |
4438 |
@@ -121674,11 +122340,11 @@ index 0000000..302bda8 |
4439 |
+ } |
4440 |
+ |
4441 |
+ if (lookup_special_role_auth |
4442 |
-+ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum) |
4443 |
++ (gr_usermode->mode, (const char *)gr_usermode->sp_role, &sprole_salt, &sprole_sum) |
4444 |
+ && ((!sprole_salt && !sprole_sum) |
4445 |
+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) { |
4446 |
+ char *p = ""; |
4447 |
-+ assign_special_role(gr_usermode->sp_role); |
4448 |
++ assign_special_role((const char *)gr_usermode->sp_role); |
4449 |
+ read_lock(&tasklist_lock); |
4450 |
+ if (current->real_parent) |
4451 |
+ p = current->real_parent->role->rolename; |
4452 |
@@ -125636,7 +126302,7 @@ index 0000000..ae02d8e |
4453 |
+EXPORT_SYMBOL_GPL(gr_handle_new_usb); |
4454 |
diff --git a/grsecurity/grsum.c b/grsecurity/grsum.c |
4455 |
new file mode 100644 |
4456 |
-index 0000000..4fb2ce6 |
4457 |
+index 0000000..aef6b92 |
4458 |
--- /dev/null |
4459 |
+++ b/grsecurity/grsum.c |
4460 |
@@ -0,0 +1,54 @@ |
4461 |
@@ -125674,12 +126340,12 @@ index 0000000..4fb2ce6 |
4462 |
+ |
4463 |
+ sg_init_table(sg, 2); |
4464 |
+ sg_set_buf(&sg[0], salt, GR_SALT_LEN); |
4465 |
-+ sg_set_buf(&sg[1], entry->pw, strlen(entry->pw)); |
4466 |
++ sg_set_buf(&sg[1], entry->pw, strlen((const char *)entry->pw)); |
4467 |
+ |
4468 |
+ desc.tfm = tfm; |
4469 |
+ desc.flags = 0; |
4470 |
+ |
4471 |
-+ cryptres = crypto_hash_digest(&desc, sg, GR_SALT_LEN + strlen(entry->pw), |
4472 |
++ cryptres = crypto_hash_digest(&desc, sg, GR_SALT_LEN + strlen((const char *)entry->pw), |
4473 |
+ temp_sum); |
4474 |
+ |
4475 |
+ memset(entry->pw, 0, GR_PW_LEN); |
4476 |
@@ -127062,7 +127728,7 @@ index a76c917..75d6aeb 100644 |
4477 |
asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t); |
4478 |
/* |
4479 |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h |
4480 |
-index eeae401..a2a9f48 100644 |
4481 |
+index eeae401..c108d27 100644 |
4482 |
--- a/include/linux/compiler-gcc.h |
4483 |
+++ b/include/linux/compiler-gcc.h |
4484 |
@@ -116,9 +116,9 @@ |
4485 |
@@ -127078,7 +127744,7 @@ index eeae401..a2a9f48 100644 |
4486 |
#define __maybe_unused __attribute__((unused)) |
4487 |
#define __always_unused __attribute__((unused)) |
4488 |
|
4489 |
-@@ -184,9 +184,38 @@ |
4490 |
+@@ -184,9 +184,39 @@ |
4491 |
# define __compiletime_warning(message) __attribute__((warning(message))) |
4492 |
# define __compiletime_error(message) __attribute__((error(message))) |
4493 |
#endif /* __CHECKER__ */ |
4494 |
@@ -127099,6 +127765,7 @@ index eeae401..a2a9f48 100644 |
4495 |
+#ifdef CONSTIFY_PLUGIN |
4496 |
+#define __no_const __attribute__((no_const)) |
4497 |
+#define __do_const __attribute__((do_const)) |
4498 |
++#define const_cast(x) (*(typeof((typeof(x))0) *)&(x)) |
4499 |
+#endif |
4500 |
+ |
4501 |
+#ifdef SIZE_OVERFLOW_PLUGIN |
4502 |
@@ -127118,7 +127785,7 @@ index eeae401..a2a9f48 100644 |
4503 |
* Mark a position in code as unreachable. This can be used to |
4504 |
* suppress control flow warnings after asm blocks that transfer |
4505 |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h |
4506 |
-index 48f5aab..2d1c52f 100644 |
4507 |
+index 48f5aab..4206700 100644 |
4508 |
--- a/include/linux/compiler.h |
4509 |
+++ b/include/linux/compiler.h |
4510 |
@@ -5,11 +5,14 @@ |
4511 |
@@ -127340,7 +128007,7 @@ index 48f5aab..2d1c52f 100644 |
4512 |
}) |
4513 |
|
4514 |
/** |
4515 |
-@@ -416,6 +432,38 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4516 |
+@@ -416,6 +432,42 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4517 |
# define __attribute_const__ /* unimplemented */ |
4518 |
#endif |
4519 |
|
4520 |
@@ -127376,10 +128043,14 @@ index 48f5aab..2d1c52f 100644 |
4521 |
+# define __nocapture(...) |
4522 |
+#endif |
4523 |
+ |
4524 |
++#ifndef const_cast |
4525 |
++# define const_cast(x) (x) |
4526 |
++#endif |
4527 |
++ |
4528 |
/* |
4529 |
* Tell gcc if a function is cold. The compiler will assume any path |
4530 |
* directly leading to the call is unlikely. |
4531 |
-@@ -425,6 +473,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4532 |
+@@ -425,6 +477,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4533 |
#define __cold |
4534 |
#endif |
4535 |
|
4536 |
@@ -127402,7 +128073,7 @@ index 48f5aab..2d1c52f 100644 |
4537 |
/* Simple shorthand for a section definition */ |
4538 |
#ifndef __section |
4539 |
# define __section(S) __attribute__ ((__section__(#S))) |
4540 |
-@@ -447,6 +511,8 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4541 |
+@@ -447,6 +515,8 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4542 |
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) |
4543 |
#endif |
4544 |
|
4545 |
@@ -127411,7 +128082,7 @@ index 48f5aab..2d1c52f 100644 |
4546 |
/* Is this type a native word size -- useful for atomic operations */ |
4547 |
#ifndef __native_word |
4548 |
# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) |
4549 |
-@@ -526,8 +592,9 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4550 |
+@@ -526,8 +596,9 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s |
4551 |
*/ |
4552 |
#define __ACCESS_ONCE(x) ({ \ |
4553 |
__maybe_unused typeof(x) __var = (__force typeof(x)) 0; \ |
4554 |
@@ -131980,7 +132651,7 @@ index 556ec1e..38c19c9 100644 |
4555 |
|
4556 |
/* |
4557 |
diff --git a/include/linux/sched.h b/include/linux/sched.h |
4558 |
-index a10494a..2facd6d 100644 |
4559 |
+index a10494a..9f25fd6 100644 |
4560 |
--- a/include/linux/sched.h |
4561 |
+++ b/include/linux/sched.h |
4562 |
@@ -7,7 +7,7 @@ |
4563 |
@@ -132253,7 +132924,7 @@ index a10494a..2facd6d 100644 |
4564 |
{ |
4565 |
return tsk->pid; |
4566 |
} |
4567 |
-@@ -2289,6 +2397,25 @@ extern u64 sched_clock_cpu(int cpu); |
4568 |
+@@ -2289,6 +2397,26 @@ extern u64 sched_clock_cpu(int cpu); |
4569 |
|
4570 |
extern void sched_clock_init(void); |
4571 |
|
4572 |
@@ -132267,6 +132938,7 @@ index a10494a..2facd6d 100644 |
4573 |
+ |
4574 |
+ while (ptr < end) { |
4575 |
+ c = *(volatile int *)ptr; |
4576 |
++ (void)c; |
4577 |
+ ptr += PAGE_SIZE/sizeof(int); |
4578 |
+ } |
4579 |
+} |
4580 |
@@ -132279,7 +132951,7 @@ index a10494a..2facd6d 100644 |
4581 |
#ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK |
4582 |
static inline void sched_clock_tick(void) |
4583 |
{ |
4584 |
-@@ -2417,7 +2544,9 @@ extern void set_curr_task(int cpu, struct task_struct *p); |
4585 |
+@@ -2417,7 +2545,9 @@ extern void set_curr_task(int cpu, struct task_struct *p); |
4586 |
void yield(void); |
4587 |
|
4588 |
union thread_union { |
4589 |
@@ -132289,7 +132961,7 @@ index a10494a..2facd6d 100644 |
4590 |
unsigned long stack[THREAD_SIZE/sizeof(long)]; |
4591 |
}; |
4592 |
|
4593 |
-@@ -2450,6 +2579,7 @@ extern struct pid_namespace init_pid_ns; |
4594 |
+@@ -2450,6 +2580,7 @@ extern struct pid_namespace init_pid_ns; |
4595 |
*/ |
4596 |
|
4597 |
extern struct task_struct *find_task_by_vpid(pid_t nr); |
4598 |
@@ -132297,7 +132969,7 @@ index a10494a..2facd6d 100644 |
4599 |
extern struct task_struct *find_task_by_pid_ns(pid_t nr, |
4600 |
struct pid_namespace *ns); |
4601 |
|
4602 |
-@@ -2481,7 +2611,7 @@ extern void proc_caches_init(void); |
4603 |
+@@ -2481,7 +2612,7 @@ extern void proc_caches_init(void); |
4604 |
extern void flush_signals(struct task_struct *); |
4605 |
extern void ignore_signals(struct task_struct *); |
4606 |
extern void flush_signal_handlers(struct task_struct *, int force_default); |
4607 |
@@ -132306,7 +132978,7 @@ index a10494a..2facd6d 100644 |
4608 |
|
4609 |
static inline int kernel_dequeue_signal(siginfo_t *info) |
4610 |
{ |
4611 |
-@@ -2635,7 +2765,7 @@ extern void __cleanup_sighand(struct sighand_struct *); |
4612 |
+@@ -2635,7 +2766,7 @@ extern void __cleanup_sighand(struct sighand_struct *); |
4613 |
extern void exit_itimers(struct signal_struct *); |
4614 |
extern void flush_itimer_signals(void); |
4615 |
|
4616 |
@@ -132315,7 +132987,7 @@ index a10494a..2facd6d 100644 |
4617 |
|
4618 |
extern int do_execve(struct filename *, |
4619 |
const char __user * const __user *, |
4620 |
-@@ -2750,11 +2880,13 @@ static inline int thread_group_empty(struct task_struct *p) |
4621 |
+@@ -2750,11 +2881,13 @@ static inline int thread_group_empty(struct task_struct *p) |
4622 |
* It must not be nested with write_lock_irq(&tasklist_lock), |
4623 |
* neither inside nor outside. |
4624 |
*/ |
4625 |
@@ -132329,7 +133001,7 @@ index a10494a..2facd6d 100644 |
4626 |
static inline void task_unlock(struct task_struct *p) |
4627 |
{ |
4628 |
spin_unlock(&p->alloc_lock); |
4629 |
-@@ -2840,9 +2972,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) |
4630 |
+@@ -2840,9 +2973,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) |
4631 |
#define task_stack_end_corrupted(task) \ |
4632 |
(*(end_of_stack(task)) != STACK_END_MAGIC) |
4633 |
|
4634 |
@@ -132404,6 +133076,19 @@ index dc368b8..e895209 100644 |
4635 |
extern int __must_check down_killable(struct semaphore *sem); |
4636 |
extern int __must_check down_trylock(struct semaphore *sem); |
4637 |
extern int __must_check down_timeout(struct semaphore *sem, long jiffies); |
4638 |
+diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h |
4639 |
+index fb7eb9c..1b493dc 100644 |
4640 |
+--- a/include/linux/seq_buf.h |
4641 |
++++ b/include/linux/seq_buf.h |
4642 |
+@@ -16,7 +16,7 @@ |
4643 |
+ * @readpos: The next position to read in the buffer. |
4644 |
+ */ |
4645 |
+ struct seq_buf { |
4646 |
+- char *buffer; |
4647 |
++ unsigned char *buffer; |
4648 |
+ size_t size; |
4649 |
+ size_t len; |
4650 |
+ loff_t readpos; |
4651 |
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h |
4652 |
index dde00de..202bfd3 100644 |
4653 |
--- a/include/linux/seq_file.h |
4654 |
@@ -133368,7 +134053,7 @@ index fa7bc29..0d96561 100644 |
4655 |
struct ctl_node { |
4656 |
struct rb_node node; |
4657 |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h |
4658 |
-index c6f0f0d..a34ab2d 100644 |
4659 |
+index c6f0f0d..e663567 100644 |
4660 |
--- a/include/linux/sysfs.h |
4661 |
+++ b/include/linux/sysfs.h |
4662 |
@@ -34,7 +34,8 @@ struct attribute { |
4663 |
@@ -133401,6 +134086,15 @@ index c6f0f0d..a34ab2d 100644 |
4664 |
|
4665 |
/** |
4666 |
* sysfs_bin_attr_init - initialize a dynamically allocated bin_attribute |
4667 |
+@@ -512,7 +515,7 @@ static inline void sysfs_notify_dirent(struct kernfs_node *kn) |
4668 |
+ } |
4669 |
+ |
4670 |
+ static inline struct kernfs_node *sysfs_get_dirent(struct kernfs_node *parent, |
4671 |
+- const unsigned char *name) |
4672 |
++ const char *name) |
4673 |
+ { |
4674 |
+ return kernfs_find_and_get(parent, name); |
4675 |
+ } |
4676 |
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h |
4677 |
index 387fa7d..3fcde6b 100644 |
4678 |
--- a/include/linux/sysrq.h |
4679 |
@@ -136761,7 +137455,7 @@ index 45432b5..988f1e4 100644 |
4680 |
+} |
4681 |
+EXPORT_SYMBOL(capable_wrt_inode_uidgid_nolog); |
4682 |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c |
4683 |
-index 355cd5f..6273802 100644 |
4684 |
+index 355cd5f..93e1510 100644 |
4685 |
--- a/kernel/cgroup.c |
4686 |
+++ b/kernel/cgroup.c |
4687 |
@@ -3333,7 +3333,7 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp, |
4688 |
@@ -136781,12 +137475,12 @@ index 355cd5f..6273802 100644 |
4689 |
- cft->ss = NULL; |
4690 |
+ |
4691 |
+ pax_open_kernel(); |
4692 |
-+ *(void **)&cft->kf_ops = NULL; |
4693 |
-+ *(void **)&cft->ss = NULL; |
4694 |
++ const_cast(cft->kf_ops) = NULL; |
4695 |
++ const_cast(cft->ss) = NULL; |
4696 |
|
4697 |
/* revert flags set by cgroup core while adding @cfts */ |
4698 |
- cft->flags &= ~(__CFTYPE_ONLY_ON_DFL | __CFTYPE_NOT_ON_DFL); |
4699 |
-+ *(unsigned int *)&cft->flags &= ~(__CFTYPE_ONLY_ON_DFL | __CFTYPE_NOT_ON_DFL); |
4700 |
++ const_cast(cft->flags) &= ~(__CFTYPE_ONLY_ON_DFL | __CFTYPE_NOT_ON_DFL); |
4701 |
+ pax_close_kernel(); |
4702 |
} |
4703 |
} |
4704 |
@@ -136798,8 +137492,8 @@ index 355cd5f..6273802 100644 |
4705 |
- cft->kf_ops = kf_ops; |
4706 |
- cft->ss = ss; |
4707 |
+ pax_open_kernel(); |
4708 |
-+ *(void **)&cft->kf_ops = kf_ops; |
4709 |
-+ *(void **)&cft->ss = ss; |
4710 |
++ const_cast(cft->kf_ops) = kf_ops; |
4711 |
++ const_cast(cft->ss) = ss; |
4712 |
+ pax_close_kernel(); |
4713 |
} |
4714 |
|
4715 |
@@ -136829,7 +137523,7 @@ index 355cd5f..6273802 100644 |
4716 |
+ pax_open_kernel(); |
4717 |
for (cft = cfts; cft && cft->name[0] != '\0'; cft++) |
4718 |
- cft->flags |= __CFTYPE_ONLY_ON_DFL; |
4719 |
-+ *(unsigned int *)&cft->flags |= __CFTYPE_ONLY_ON_DFL; |
4720 |
++ const_cast(cft->flags) |= __CFTYPE_ONLY_ON_DFL; |
4721 |
+ pax_close_kernel(); |
4722 |
return cgroup_add_cftypes(ss, cfts); |
4723 |
} |
4724 |
@@ -136841,7 +137535,7 @@ index 355cd5f..6273802 100644 |
4725 |
+ pax_open_kernel(); |
4726 |
for (cft = cfts; cft && cft->name[0] != '\0'; cft++) |
4727 |
- cft->flags |= __CFTYPE_NOT_ON_DFL; |
4728 |
-+ *(unsigned int *)&cft->flags |= __CFTYPE_NOT_ON_DFL; |
4729 |
++ const_cast(cft->flags) |= __CFTYPE_NOT_ON_DFL; |
4730 |
+ pax_close_kernel(); |
4731 |
return cgroup_add_cftypes(ss, cfts); |
4732 |
} |
4733 |
@@ -138224,7 +138918,7 @@ index 84118723..317f7a5 100644 |
4734 |
irq_wake_secondary(desc, action); |
4735 |
|
4736 |
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c |
4737 |
-index 38e89ce..58960ac 100644 |
4738 |
+index 38e89ce..8b7a537 100644 |
4739 |
--- a/kernel/irq/msi.c |
4740 |
+++ b/kernel/irq/msi.c |
4741 |
@@ -214,16 +214,18 @@ static void msi_domain_update_dom_ops(struct msi_domain_info *info) |
4742 |
@@ -138234,19 +138928,19 @@ index 38e89ce..58960ac 100644 |
4743 |
+ pax_open_kernel(); |
4744 |
if (ops->get_hwirq == NULL) |
4745 |
- ops->get_hwirq = msi_domain_ops_default.get_hwirq; |
4746 |
-+ *(void **)&ops->get_hwirq = msi_domain_ops_default.get_hwirq; |
4747 |
++ const_cast(ops->get_hwirq) = msi_domain_ops_default.get_hwirq; |
4748 |
if (ops->msi_init == NULL) |
4749 |
- ops->msi_init = msi_domain_ops_default.msi_init; |
4750 |
-+ *(void **)&ops->msi_init = msi_domain_ops_default.msi_init; |
4751 |
++ const_cast(ops->msi_init) = msi_domain_ops_default.msi_init; |
4752 |
if (ops->msi_check == NULL) |
4753 |
- ops->msi_check = msi_domain_ops_default.msi_check; |
4754 |
-+ *(void **)&ops->msi_check = msi_domain_ops_default.msi_check; |
4755 |
++ const_cast(ops->msi_check) = msi_domain_ops_default.msi_check; |
4756 |
if (ops->msi_prepare == NULL) |
4757 |
- ops->msi_prepare = msi_domain_ops_default.msi_prepare; |
4758 |
-+ *(void **)&ops->msi_prepare = msi_domain_ops_default.msi_prepare; |
4759 |
++ const_cast(ops->msi_prepare) = msi_domain_ops_default.msi_prepare; |
4760 |
if (ops->set_desc == NULL) |
4761 |
- ops->set_desc = msi_domain_ops_default.set_desc; |
4762 |
-+ *(void **)&ops->set_desc = msi_domain_ops_default.set_desc; |
4763 |
++ const_cast(ops->set_desc) = msi_domain_ops_default.set_desc; |
4764 |
+ pax_close_kernel(); |
4765 |
} |
4766 |
|
4767 |
@@ -138259,7 +138953,7 @@ index 38e89ce..58960ac 100644 |
4768 |
- chip->irq_set_affinity = msi_domain_set_affinity; |
4769 |
+ if (!chip->irq_set_affinity) { |
4770 |
+ pax_open_kernel(); |
4771 |
-+ *(void **)&chip->irq_set_affinity = msi_domain_set_affinity; |
4772 |
++ const_cast(chip->irq_set_affinity) = msi_domain_set_affinity; |
4773 |
+ pax_close_kernel(); |
4774 |
+ } |
4775 |
} |
4776 |
@@ -139888,7 +140582,7 @@ index 794ebe8..f81f123 100644 |
4777 |
} |
4778 |
return mod; |
4779 |
diff --git a/kernel/notifier.c b/kernel/notifier.c |
4780 |
-index fd2c9ac..95e58f6 100644 |
4781 |
+index fd2c9ac..6263e05 100644 |
4782 |
--- a/kernel/notifier.c |
4783 |
+++ b/kernel/notifier.c |
4784 |
@@ -5,6 +5,7 @@ |
4785 |
@@ -139908,7 +140602,7 @@ index fd2c9ac..95e58f6 100644 |
4786 |
} |
4787 |
- n->next = *nl; |
4788 |
+ pax_open_kernel(); |
4789 |
-+ *(const void **)&n->next = *nl; |
4790 |
++ const_cast(n->next) = *nl; |
4791 |
rcu_assign_pointer(*nl, n); |
4792 |
+ pax_close_kernel(); |
4793 |
return 0; |
4794 |
@@ -139923,7 +140617,7 @@ index fd2c9ac..95e58f6 100644 |
4795 |
} |
4796 |
- n->next = *nl; |
4797 |
+ pax_open_kernel(); |
4798 |
-+ *(const void **)&n->next = *nl; |
4799 |
++ const_cast(n->next) = *nl; |
4800 |
rcu_assign_pointer(*nl, n); |
4801 |
+ pax_close_kernel(); |
4802 |
return 0; |
4803 |
@@ -140025,7 +140719,7 @@ index d96469d..81d6d28 100644 |
4804 |
} |
4805 |
EXPORT_SYMBOL(__stack_chk_fail); |
4806 |
diff --git a/kernel/pid.c b/kernel/pid.c |
4807 |
-index 4d73a83..4712357 100644 |
4808 |
+index 4d73a83..9df1950 100644 |
4809 |
--- a/kernel/pid.c |
4810 |
+++ b/kernel/pid.c |
4811 |
@@ -33,6 +33,7 @@ |
4812 |
@@ -140078,15 +140772,18 @@ index 4d73a83..4712357 100644 |
4813 |
struct pid *get_task_pid(struct task_struct *task, enum pid_type type) |
4814 |
{ |
4815 |
struct pid *pid; |
4816 |
-@@ -497,7 +513,7 @@ struct pid *find_get_pid(pid_t nr) |
4817 |
+@@ -497,9 +513,9 @@ struct pid *find_get_pid(pid_t nr) |
4818 |
} |
4819 |
EXPORT_SYMBOL_GPL(find_get_pid); |
4820 |
|
4821 |
-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) |
4822 |
+pid_t pid_nr_ns(const struct pid *pid, const struct pid_namespace *ns) |
4823 |
{ |
4824 |
- struct upid *upid; |
4825 |
+- struct upid *upid; |
4826 |
++ const struct upid *upid; |
4827 |
pid_t nr = 0; |
4828 |
+ |
4829 |
+ if (pid && ns->level <= pid->level) { |
4830 |
@@ -511,7 +527,7 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) |
4831 |
} |
4832 |
EXPORT_SYMBOL_GPL(pid_nr_ns); |
4833 |
@@ -143248,7 +143945,7 @@ index 2be8c4f..444ecfb 100644 |
4834 |
} |
4835 |
entry = ring_buffer_event_data(event); |
4836 |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c |
4837 |
-index 2829821..a290dc89 100644 |
4838 |
+index 2829821..cd4ea77 100644 |
4839 |
--- a/kernel/trace/trace_output.c |
4840 |
+++ b/kernel/trace/trace_output.c |
4841 |
@@ -713,14 +713,16 @@ int register_trace_event(struct trace_event *event) |
4842 |
@@ -143258,16 +143955,16 @@ index 2829821..a290dc89 100644 |
4843 |
+ pax_open_kernel(); |
4844 |
if (event->funcs->trace == NULL) |
4845 |
- event->funcs->trace = trace_nop_print; |
4846 |
-+ *(void **)&event->funcs->trace = trace_nop_print; |
4847 |
++ const_cast(event->funcs->trace) = trace_nop_print; |
4848 |
if (event->funcs->raw == NULL) |
4849 |
- event->funcs->raw = trace_nop_print; |
4850 |
-+ *(void **)&event->funcs->raw = trace_nop_print; |
4851 |
++ const_cast(event->funcs->raw) = trace_nop_print; |
4852 |
if (event->funcs->hex == NULL) |
4853 |
- event->funcs->hex = trace_nop_print; |
4854 |
-+ *(void **)&event->funcs->hex = trace_nop_print; |
4855 |
++ const_cast(event->funcs->hex) = trace_nop_print; |
4856 |
if (event->funcs->binary == NULL) |
4857 |
- event->funcs->binary = trace_nop_print; |
4858 |
-+ *(void **)&event->funcs->binary = trace_nop_print; |
4859 |
++ const_cast(event->funcs->binary) = trace_nop_print; |
4860 |
+ pax_close_kernel(); |
4861 |
|
4862 |
key = event->type & (EVENT_HASHSIZE - 1); |
4863 |
@@ -151655,7 +152352,7 @@ index 1474cfd..961bc9f 100644 |
4864 |
pr_warn("cannot create /proc/net/%s\n", PG_PROC_DIR); |
4865 |
return -ENODEV; |
4866 |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
4867 |
-index 482c371..b02a761 100644 |
4868 |
+index 482c371..150e1ee 100644 |
4869 |
--- a/net/core/rtnetlink.c |
4870 |
+++ b/net/core/rtnetlink.c |
4871 |
@@ -61,7 +61,7 @@ struct rtnl_link { |
4872 |
@@ -151675,7 +152372,7 @@ index 482c371..b02a761 100644 |
4873 |
- ops->dellink = unregister_netdevice_queue; |
4874 |
+ if (ops->setup && !ops->dellink) { |
4875 |
+ pax_open_kernel(); |
4876 |
-+ *(void **)&ops->dellink = unregister_netdevice_queue; |
4877 |
++ const_cast(ops->dellink) = unregister_netdevice_queue; |
4878 |
+ pax_close_kernel(); |
4879 |
+ } |
4880 |
|
4881 |
@@ -160008,7 +160705,7 @@ index b5e665b..3030b1d 100644 |
4882 |
} |
4883 |
|
4884 |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c |
4885 |
-index 9895a8c..705c302 100644 |
4886 |
+index 9895a8c..e7c5936 100644 |
4887 |
--- a/net/xfrm/xfrm_state.c |
4888 |
+++ b/net/xfrm/xfrm_state.c |
4889 |
@@ -166,12 +166,14 @@ int xfrm_register_type(const struct xfrm_type *type, unsigned short family) |
4890 |
@@ -160082,7 +160779,7 @@ index 9895a8c..705c302 100644 |
4891 |
|
4892 |
- mode->afinfo = afinfo; |
4893 |
+ pax_open_kernel(); |
4894 |
-+ *(const void **)&mode->afinfo = afinfo; |
4895 |
++ const_cast(mode->afinfo) = afinfo; |
4896 |
modemap[mode->encap] = mode; |
4897 |
+ pax_close_kernel(); |
4898 |
err = 0; |
4899 |
@@ -160172,6 +160869,18 @@ index 1db6d73..0819042 100644 |
4900 |
|
4901 |
# ld-option |
4902 |
# Usage: LDFLAGS += $(call ld-option, -X) |
4903 |
+diff --git a/scripts/Makefile b/scripts/Makefile |
4904 |
+index fd0d53d..1471190 100644 |
4905 |
+--- a/scripts/Makefile |
4906 |
++++ b/scripts/Makefile |
4907 |
+@@ -44,6 +44,7 @@ subdir-y += mod |
4908 |
+ subdir-$(CONFIG_SECURITY_SELINUX) += selinux |
4909 |
+ subdir-$(CONFIG_DTC) += dtc |
4910 |
+ subdir-$(CONFIG_GDB_SCRIPTS) += gdb |
4911 |
++subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins |
4912 |
+ |
4913 |
+ # Let clean descend into subdirs |
4914 |
+ subdir- += basic kconfig package |
4915 |
diff --git a/scripts/Makefile.build b/scripts/Makefile.build |
4916 |
index 2c47f9c..9d46008 100644 |
4917 |
--- a/scripts/Makefile.build |
4918 |
@@ -160216,81 +160925,83 @@ index f9e47a7..b72022a 100644 |
4919 |
warning-2 += -Wdisabled-optimization |
4920 |
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins |
4921 |
new file mode 100644 |
4922 |
-index 0000000..02fd848 |
4923 |
+index 0000000..08d4e22 |
4924 |
--- /dev/null |
4925 |
+++ b/scripts/Makefile.gcc-plugins |
4926 |
-@@ -0,0 +1,69 @@ |
4927 |
-+__PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) |
4928 |
-+PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") |
4929 |
-+ifneq ($(PLUGINCC),) |
4930 |
-+ifdef CONFIG_PAX_CONSTIFY_PLUGIN |
4931 |
-+CONSTIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/constify_plugin.so -DCONSTIFY_PLUGIN |
4932 |
-+endif |
4933 |
-+ifdef CONFIG_PAX_MEMORY_STACKLEAK |
4934 |
-+STACKLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/stackleak_plugin.so -DSTACKLEAK_PLUGIN |
4935 |
-+STACKLEAK_PLUGIN_CFLAGS += -fplugin-arg-stackleak_plugin-track-lowest-sp=100 |
4936 |
-+endif |
4937 |
-+ifdef CONFIG_KALLOCSTAT_PLUGIN |
4938 |
-+KALLOCSTAT_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/kallocstat_plugin.so |
4939 |
-+endif |
4940 |
-+ifdef CONFIG_PAX_KERNEXEC_PLUGIN |
4941 |
-+KERNEXEC_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/kernexec_plugin.so |
4942 |
-+KERNEXEC_PLUGIN_CFLAGS += -fplugin-arg-kernexec_plugin-method=$(CONFIG_PAX_KERNEXEC_PLUGIN_METHOD) -DKERNEXEC_PLUGIN |
4943 |
-+KERNEXEC_PLUGIN_AFLAGS := -DKERNEXEC_PLUGIN |
4944 |
-+endif |
4945 |
-+ifdef CONFIG_CHECKER_PLUGIN |
4946 |
-+ifeq ($(call cc-ifversion, -ge, 0406, y), y) |
4947 |
-+CHECKER_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/checker_plugin.so -DCHECKER_PLUGIN |
4948 |
-+ifdef CONFIG_CHECKER_PLUGIN_USER |
4949 |
-+CHECKER_PLUGIN_CFLAGS += -fplugin-arg-checker_plugin-user -DCHECKER_PLUGIN_USER |
4950 |
-+endif |
4951 |
-+ifdef CONFIG_CHECKER_PLUGIN_CONTEXT |
4952 |
-+CHECKER_PLUGIN_CFLAGS += -fplugin-arg-checker_plugin-context -DCHECKER_PLUGIN_CONTEXT |
4953 |
-+endif |
4954 |
-+endif |
4955 |
-+endif |
4956 |
-+COLORIZE_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/colorize_plugin.so |
4957 |
-+ifdef CONFIG_PAX_SIZE_OVERFLOW |
4958 |
-+SIZE_OVERFLOW_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/size_overflow_plugin/size_overflow_plugin.so -DSIZE_OVERFLOW_PLUGIN |
4959 |
-+endif |
4960 |
-+ifdef CONFIG_PAX_LATENT_ENTROPY |
4961 |
-+LATENT_ENTROPY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/latent_entropy_plugin.so -DLATENT_ENTROPY_PLUGIN |
4962 |
-+endif |
4963 |
-+ifdef CONFIG_PAX_MEMORY_STRUCTLEAK |
4964 |
-+STRUCTLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/structleak_plugin.so -DSTRUCTLEAK_PLUGIN |
4965 |
-+endif |
4966 |
-+INITIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/initify_plugin.so -DINITIFY_PLUGIN |
4967 |
-+ifdef CONFIG_PAX_RAP |
4968 |
-+RAP_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/rap_plugin/rap_plugin.so -fplugin-arg-rap_plugin-check=call -DRAP_PLUGIN |
4969 |
-+#RAP_PLUGIN_CFLAGS += -fplugin-arg-rap_plugin-report=func,fptr,abs |
4970 |
-+RAP_PLUGIN_ABS_CFLAGS := -fplugin-arg-rap_plugin-hash=abs-finish |
4971 |
-+RAP_PLUGIN_AFLAGS := -DRAP_PLUGIN |
4972 |
-+endif |
4973 |
-+GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS) |
4974 |
-+GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS) |
4975 |
-+GCC_PLUGINS_CFLAGS += $(SIZE_OVERFLOW_PLUGIN_CFLAGS) $(LATENT_ENTROPY_PLUGIN_CFLAGS) $(STRUCTLEAK_PLUGIN_CFLAGS) |
4976 |
-+GCC_PLUGINS_CFLAGS += $(INITIFY_PLUGIN_CFLAGS) |
4977 |
-+GCC_PLUGINS_CFLAGS += $(RAP_PLUGIN_CFLAGS) $(RAP_PLUGIN_ABS_CFLAGS) |
4978 |
-+GCC_PLUGINS_AFLAGS := $(KERNEXEC_PLUGIN_AFLAGS) $(RAP_PLUGIN_AFLAGS) |
4979 |
-+export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS CONSTIFY_PLUGIN LATENT_ENTROPY_PLUGIN_CFLAGS RAP_PLUGIN_CFLAGS RAP_PLUGIN_ABS_CFLAGS |
4980 |
-+ifeq ($(KBUILD_EXTMOD),) |
4981 |
-+gcc-plugins: |
4982 |
-+ $(Q)$(MAKE) $(build)=tools/gcc |
4983 |
-+else |
4984 |
-+gcc-plugins: ; |
4985 |
-+endif |
4986 |
-+else |
4987 |
-+gcc-plugins: |
4988 |
-+ifeq ($(call cc-ifversion, -ge, 0405, y), y) |
4989 |
-+ $(warning warning, your gcc installation does not support plugins, perhaps the necessary headers are missing?) |
4990 |
-+ $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" |
4991 |
-+else |
4992 |
-+ $(warning warning, your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least) |
4993 |
-+endif |
4994 |
-+ $(warning PAX_MEMORY_STACKLEAK and other features will be less secure) |
4995 |
+@@ -0,0 +1,71 @@ |
4996 |
++ifdef CONFIG_GCC_PLUGINS |
4997 |
++ __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) |
4998 |
++ PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") |
4999 |
++ |
5000 |
++ gcc-plugin-$(CONFIG_PAX_CONSTIFY_PLUGIN) += constify_plugin.so |
5001 |
++ gcc-plugin-cflags-$(CONFIG_PAX_CONSTIFY_PLUGIN) += -DCONSTIFY_PLUGIN |
5002 |
++ |
5003 |
++ gcc-plugin-$(CONFIG_PAX_MEMORY_STACKLEAK) += stackleak_plugin.so |
5004 |
++ gcc-plugin-cflags-$(CONFIG_PAX_MEMORY_STACKLEAK) += -DSTACKLEAK_PLUGIN -fplugin-arg-stackleak_plugin-track-lowest-sp=100 |
5005 |
++ |
5006 |
++ gcc-plugin-$(CONFIG_KALLOCSTAT_PLUGIN) += kallocstat_plugin.so |
5007 |
++ |
5008 |
++ gcc-plugin-$(CONFIG_PAX_KERNEXEC_PLUGIN) += kernexec_plugin.so |
5009 |
++ gcc-plugin-cflags-$(CONFIG_PAX_KERNEXEC_PLUGIN) += -DKERNEXEC_PLUGIN -fplugin-arg-kernexec_plugin-method=$(CONFIG_PAX_KERNEXEC_PLUGIN_METHOD) |
5010 |
++ gcc-plugin-aflags-$(CONFIG_PAX_KERNEXEC_PLUGIN) += -DKERNEXEC_PLUGIN |
5011 |
++ |
5012 |
++ ifdef CONFIG_CHECKER_PLUGIN |
5013 |
++ ifeq ($(call cc-ifversion, -ge, 0406, y), y) |
5014 |
++ gcc-plugin-$(CONFIG_CHECKER_PLUGIN) += checker_plugin.so |
5015 |
++ gcc-plugin-cflags-$(CONFIG_CHECKER_PLUGIN) += -DCHECKER_PLUGIN |
5016 |
++ gcc-plugin-cflags-$(CONFIG_CHECKER_PLUGIN_USER) += -DCHECKER_PLUGIN_USER -fplugin-arg-checker_plugin-user |
5017 |
++ gcc-plugin-cflags-$(CONFIG_CHECKER_PLUGIN_CONTEXT)+= -DCHECKER_PLUGIN_CONTEXT -fplugin-arg-checker_plugin-context |
5018 |
++ endif |
5019 |
++ endif |
5020 |
++ |
5021 |
++ gcc-plugin-y += colorize_plugin.so |
5022 |
++ |
5023 |
++ gcc-plugin-$(CONFIG_PAX_SIZE_OVERFLOW) += size_overflow_plugin/size_overflow_plugin.so |
5024 |
++ gcc-plugin-cflags-$(CONFIG_PAX_SIZE_OVERFLOW) += -DSIZE_OVERFLOW_PLUGIN |
5025 |
++ |
5026 |
++ gcc-plugin-$(CONFIG_PAX_LATENT_ENTROPY) += latent_entropy_plugin.so |
5027 |
++ gcc-plugin-cflags-$(CONFIG_PAX_LATENT_ENTROPY) += -DLATENT_ENTROPY_PLUGIN |
5028 |
++ ifdef CONFIG_PAX_LATENT_ENTROPY |
5029 |
++ DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable |
5030 |
++ endif |
5031 |
++ |
5032 |
++ gcc-plugin-$(CONFIG_PAX_MEMORY_STRUCTLEAK) += structleak_plugin.so |
5033 |
++ gcc-plugin-cflags-$(CONFIG_PAX_MEMORY_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN |
5034 |
++ |
5035 |
++ gcc-plugin-y += initify_plugin.so |
5036 |
++ gcc-plugin-cflags-y += -DINITIFY_PLUGIN |
5037 |
++ |
5038 |
++ gcc-plugin-$(CONFIG_PAX_RAP) += rap_plugin/rap_plugin.so |
5039 |
++ gcc-plugin-cflags-$(CONFIG_PAX_RAP) += -DRAP_PLUGIN -fplugin-arg-rap_plugin-check=call |
5040 |
++# gcc-plugin-cflags-$(CONFIG_PAX_RAP) += -fplugin-arg-rap_plugin-report=func,fptr,abs |
5041 |
++ gcc-plugin-aflags-$(CONFIG_PAX_RAP) += -DRAP_PLUGIN |
5042 |
++ ifdef CONFIG_PAX_RAP |
5043 |
++ RAP_PLUGIN_ABS_CFLAGS := -fplugin-arg-rap_plugin-hash=abs-finish |
5044 |
++ endif |
5045 |
++ gcc-plugin-cflags-$(CONFIG_PAX_RAP) += $(RAP_PLUGIN_ABS_CFLAGS) |
5046 |
++ |
5047 |
++ GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) |
5048 |
++ GCC_PLUGINS_AFLAGS := $(gcc-plugin-aflags-y) |
5049 |
++ |
5050 |
++ export DISABLE_LATENT_ENTROPY_PLUGIN RAP_PLUGIN_ABS_CFLAGS |
5051 |
++ |
5052 |
++ ifeq ($(PLUGINCC),) |
5053 |
++ ifneq ($(GCC_PLUGINS_CFLAGS),) |
5054 |
++ ifeq ($(call cc-ifversion, -ge, 0405, y), y) |
5055 |
++ PLUGINCC := $(shell $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") |
5056 |
++ $(warning warning, your gcc installation does not support plugins, perhaps the necessary headers are missing?) |
5057 |
++ else |
5058 |
++ $(warning warning, your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least) |
5059 |
++ endif |
5060 |
++ $(warning PAX_MEMORY_STACKLEAK and other features will be less secure) |
5061 |
++ endif |
5062 |
++ endif |
5063 |
++ |
5064 |
++ KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) |
5065 |
++ KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS) |
5066 |
+endif |
5067 |
diff --git a/scripts/Makefile.host b/scripts/Makefile.host |
5068 |
-index 133edfa..3cc6af2 100644 |
5069 |
+index 133edfa..3439bd8 100644 |
5070 |
--- a/scripts/Makefile.host |
5071 |
+++ b/scripts/Makefile.host |
5072 |
@@ -20,7 +20,25 @@ |
5073 |
@@ -160349,7 +161060,7 @@ index 133edfa..3cc6af2 100644 |
5074 |
host-objdirs := $(addprefix $(obj)/,$(host-objdirs)) |
5075 |
|
5076 |
obj-dirs += $(host-objdirs) |
5077 |
-@@ -124,5 +158,37 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ |
5078 |
+@@ -124,5 +158,39 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ |
5079 |
$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE |
5080 |
$(call if_changed_dep,host-cxxobjs) |
5081 |
|
5082 |
@@ -160373,8 +161084,9 @@ index 133edfa..3cc6af2 100644 |
5083 |
+ cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \ |
5084 |
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \ |
5085 |
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) |
5086 |
-+$(host-cshlib): $(obj)/%: $(host-cshobjs) FORCE |
5087 |
++$(host-cshlib): FORCE |
5088 |
+ $(call if_changed,host-cshlib) |
5089 |
++$(call multi_depend, $(host-cshlib), .so, -objs -cshobjs) |
5090 |
+ |
5091 |
+# Link a shared library, based on position independent .o files |
5092 |
+# *.o -> .so shared library (host-cxxshlib) |
5093 |
@@ -160382,8 +161094,9 @@ index 133edfa..3cc6af2 100644 |
5094 |
+ cmd_host-cxxshlib = $(HOSTCXX) $(HOSTLDFLAGS) -shared -o $@ \ |
5095 |
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \ |
5096 |
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) |
5097 |
-+$(host-cxxshlib): $(obj)/%: $(host-cxxshobjs) FORCE |
5098 |
++$(host-cxxshlib): FORCE |
5099 |
+ $(call if_changed,host-cxxshlib) |
5100 |
++$(call multi_depend, $(host-cxxshlib), .so, -objs -cxxshobjs) |
5101 |
+ |
5102 |
targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\ |
5103 |
- $(host-cxxmulti) $(host-cxxobjs) |
5104 |
@@ -160592,14 +161305,14 @@ index e229b84..7141e8e 100644 |
5105 |
while (get_node_by_phandle(root, phandle)) |
5106 |
diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh |
5107 |
new file mode 100644 |
5108 |
-index 0000000..eaa4fce |
5109 |
+index 0000000..fb92075 |
5110 |
--- /dev/null |
5111 |
+++ b/scripts/gcc-plugin.sh |
5112 |
@@ -0,0 +1,51 @@ |
5113 |
+#!/bin/sh |
5114 |
+srctree=$(dirname "$0") |
5115 |
+gccplugins_dir=$($3 -print-file-name=plugin) |
5116 |
-+plugincc=$($1 -E -x c++ - -o /dev/null -I"${srctree}"/../tools/gcc -I"${gccplugins_dir}"/include 2>&1 <<EOF |
5117 |
++plugincc=$($1 -E -x c++ - -o /dev/null -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF |
5118 |
+#include "gcc-common.h" |
5119 |
+#if BUILDING_GCC_VERSION >= 4008 || defined(ENABLE_BUILD_WITH_CXX) |
5120 |
+#warning $2 CXX |
5121 |
@@ -160630,7 +161343,7 @@ index 0000000..eaa4fce |
5122 |
+esac |
5123 |
+ |
5124 |
+# we need a c++ compiler that supports the designated initializer GNU extension |
5125 |
-+plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I"${srctree}"/../tools/gcc -I"${gccplugins_dir}"/include 2>&1 <<EOF |
5126 |
++plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF |
5127 |
+#include "gcc-common.h" |
5128 |
+class test { |
5129 |
+public: |
5130 |
@@ -160647,4765 +161360,1324 @@ index 0000000..eaa4fce |
5131 |
+ exit 0 |
5132 |
+fi |
5133 |
+exit 1 |
5134 |
-diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh |
5135 |
-index fdebd66..a349e33 100755 |
5136 |
---- a/scripts/headers_install.sh |
5137 |
-+++ b/scripts/headers_install.sh |
5138 |
-@@ -32,6 +32,7 @@ do |
5139 |
- FILE="$(basename "$i")" |
5140 |
- sed -r \ |
5141 |
- -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \ |
5142 |
-+ -e 's/__intentional_overflow\([- \t,0-9]*\)//g' \ |
5143 |
- -e 's/__attribute_const__([ \t]|$)/\1/g' \ |
5144 |
- -e 's@^#include <linux/compiler.h>@@' \ |
5145 |
- -e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \ |
5146 |
-diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c |
5147 |
-index 8fa81e8..a9ac144 100644 |
5148 |
---- a/scripts/kallsyms.c |
5149 |
-+++ b/scripts/kallsyms.c |
5150 |
-@@ -89,7 +89,7 @@ static inline int is_arm_mapping_symbol(const char *str) |
5151 |
- } |
5152 |
- |
5153 |
- static int check_symbol_range(const char *sym, unsigned long long addr, |
5154 |
-- struct addr_range *ranges, int entries) |
5155 |
-+ struct addr_range *ranges, size_t entries) |
5156 |
- { |
5157 |
- size_t i; |
5158 |
- struct addr_range *ar; |
5159 |
-@@ -178,7 +178,7 @@ static int read_symbol(FILE *in, struct sym_entry *s) |
5160 |
- } |
5161 |
- |
5162 |
- static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges, |
5163 |
-- int entries) |
5164 |
-+ size_t entries) |
5165 |
- { |
5166 |
- size_t i; |
5167 |
- struct addr_range *ar; |
5168 |
-diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h |
5169 |
-index 91ca126..5f7cad6 100644 |
5170 |
---- a/scripts/kconfig/lkc.h |
5171 |
-+++ b/scripts/kconfig/lkc.h |
5172 |
-@@ -108,7 +108,8 @@ void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); |
5173 |
- void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); |
5174 |
- void menu_add_option(int token, char *arg); |
5175 |
- void menu_finalize(struct menu *parent); |
5176 |
--void menu_set_type(int type); |
5177 |
-+enum symbol_type; |
5178 |
-+void menu_set_type(enum symbol_type type); |
5179 |
- |
5180 |
- /* util.c */ |
5181 |
- struct file *file_lookup(const char *name); |
5182 |
-@@ -123,7 +124,7 @@ struct gstr { |
5183 |
- * when max_width is not zero long lines in string s (if any) get |
5184 |
- * wrapped not to exceed the max_width value |
5185 |
- */ |
5186 |
-- int max_width; |
5187 |
-+ size_t max_width; |
5188 |
- }; |
5189 |
- struct gstr str_new(void); |
5190 |
- void str_free(struct gstr *gs); |
5191 |
-diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c |
5192 |
-index aed678e..1a703de 100644 |
5193 |
---- a/scripts/kconfig/menu.c |
5194 |
-+++ b/scripts/kconfig/menu.c |
5195 |
-@@ -109,7 +109,7 @@ void menu_add_dep(struct expr *dep) |
5196 |
- current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); |
5197 |
- } |
5198 |
- |
5199 |
--void menu_set_type(int type) |
5200 |
-+void menu_set_type(enum symbol_type type) |
5201 |
- { |
5202 |
- struct symbol *sym = current_entry->sym; |
5203 |
- |
5204 |
-diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c |
5205 |
-index 25cf0c2..eb178ce 100644 |
5206 |
---- a/scripts/kconfig/symbol.c |
5207 |
-+++ b/scripts/kconfig/symbol.c |
5208 |
-@@ -956,7 +956,7 @@ const char *sym_escape_string_value(const char *in) |
5209 |
- |
5210 |
- struct sym_match { |
5211 |
- struct symbol *sym; |
5212 |
-- off_t so, eo; |
5213 |
-+ regoff_t so, eo; |
5214 |
- }; |
5215 |
- |
5216 |
- /* Compare matched symbols as thus: |
5217 |
-@@ -978,8 +978,8 @@ static int sym_rel_comp(const void *sym1, const void *sym2) |
5218 |
- * exactly; if this is the case, we can't decide which comes first, |
5219 |
- * and we fallback to sorting alphabetically. |
5220 |
- */ |
5221 |
-- exact1 = (s1->eo - s1->so) == strlen(s1->sym->name); |
5222 |
-- exact2 = (s2->eo - s2->so) == strlen(s2->sym->name); |
5223 |
-+ exact1 = (s1->eo - s1->so) == (long)strlen(s1->sym->name); |
5224 |
-+ exact2 = (s2->eo - s2->so) == (long)strlen(s2->sym->name); |
5225 |
- if (exact1 && !exact2) |
5226 |
- return -1; |
5227 |
- if (!exact1 && exact2) |
5228 |
-diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh |
5229 |
-index ba6c34e..ea10bce 100755 |
5230 |
---- a/scripts/link-vmlinux.sh |
5231 |
-+++ b/scripts/link-vmlinux.sh |
5232 |
-@@ -179,7 +179,7 @@ else |
5233 |
- fi; |
5234 |
- |
5235 |
- # final build of init/ |
5236 |
--${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init |
5237 |
-+${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}" GCC_PLUGINS_AFLAGS="${GCC_PLUGINS_AFLAGS}" |
5238 |
- |
5239 |
- kallsymso="" |
5240 |
- kallsyms_vmlinux="" |
5241 |
-diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c |
5242 |
-index a915507..27c1b41 100644 |
5243 |
---- a/scripts/mod/file2alias.c |
5244 |
-+++ b/scripts/mod/file2alias.c |
5245 |
-@@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id, |
5246 |
- unsigned long size, unsigned long id_size, |
5247 |
- void *symval) |
5248 |
- { |
5249 |
-- int i; |
5250 |
-+ unsigned int i; |
5251 |
- |
5252 |
- if (size % id_size || size < id_size) { |
5253 |
- fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " |
5254 |
-@@ -185,7 +185,7 @@ static void device_id_check(const char *modname, const char *device_id, |
5255 |
- /* USB is special because the bcdDevice can be matched against a numeric range */ |
5256 |
- /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ |
5257 |
- static void do_usb_entry(void *symval, |
5258 |
-- unsigned int bcdDevice_initial, int bcdDevice_initial_digits, |
5259 |
-+ unsigned int bcdDevice_initial, unsigned int bcdDevice_initial_digits, |
5260 |
- unsigned char range_lo, unsigned char range_hi, |
5261 |
- unsigned char max, struct module *mod) |
5262 |
- { |
5263 |
-@@ -295,7 +295,7 @@ static void do_usb_entry_multi(void *symval, struct module *mod) |
5264 |
- { |
5265 |
- unsigned int devlo, devhi; |
5266 |
- unsigned char chi, clo, max; |
5267 |
-- int ndigits; |
5268 |
-+ unsigned int ndigits; |
5269 |
- |
5270 |
- DEF_FIELD(symval, usb_device_id, match_flags); |
5271 |
- DEF_FIELD(symval, usb_device_id, idVendor); |
5272 |
-@@ -619,7 +619,7 @@ static void do_pnp_device_entry(void *symval, unsigned long size, |
5273 |
- for (i = 0; i < count; i++) { |
5274 |
- DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); |
5275 |
- char acpi_id[sizeof(*id)]; |
5276 |
-- int j; |
5277 |
-+ unsigned int j; |
5278 |
- |
5279 |
- buf_printf(&mod->dev_table_buf, |
5280 |
- "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); |
5281 |
-@@ -648,7 +648,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size, |
5282 |
- |
5283 |
- for (j = 0; j < PNP_MAX_DEVICES; j++) { |
5284 |
- const char *id = (char *)(*devs)[j].id; |
5285 |
-- int i2, j2; |
5286 |
-+ unsigned int i2, j2; |
5287 |
- int dup = 0; |
5288 |
- |
5289 |
- if (!id[0]) |
5290 |
-@@ -674,7 +674,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size, |
5291 |
- /* add an individual alias for every device entry */ |
5292 |
- if (!dup) { |
5293 |
- char acpi_id[PNP_ID_LEN]; |
5294 |
-- int k; |
5295 |
-+ unsigned int k; |
5296 |
- |
5297 |
- buf_printf(&mod->dev_table_buf, |
5298 |
- "MODULE_ALIAS(\"pnp:d%s*\");\n", id); |
5299 |
-@@ -999,7 +999,7 @@ static void dmi_ascii_filter(char *d, const char *s) |
5300 |
- static int do_dmi_entry(const char *filename, void *symval, |
5301 |
- char *alias) |
5302 |
- { |
5303 |
-- int i, j; |
5304 |
-+ unsigned int i, j; |
5305 |
- DEF_FIELD_ADDR(symval, dmi_system_id, matches); |
5306 |
- sprintf(alias, "dmi*"); |
5307 |
- |
5308 |
-diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c |
5309 |
-index 48958d3..d5ccb52 100644 |
5310 |
---- a/scripts/mod/modpost.c |
5311 |
-+++ b/scripts/mod/modpost.c |
5312 |
-@@ -37,6 +37,7 @@ static int vmlinux_section_warnings = 1; |
5313 |
- static int warn_unresolved = 0; |
5314 |
- /* How a symbol is exported */ |
5315 |
- static int sec_mismatch_count = 0; |
5316 |
-+static int writable_fptr_count = 0; |
5317 |
- static int sec_mismatch_verbose = 1; |
5318 |
- static int sec_mismatch_fatal = 0; |
5319 |
- /* ignore missing files */ |
5320 |
-@@ -947,6 +948,7 @@ enum mismatch { |
5321 |
- ANY_EXIT_TO_ANY_INIT, |
5322 |
- EXPORT_TO_INIT_EXIT, |
5323 |
- EXTABLE_TO_NON_TEXT, |
5324 |
-+ DATA_TO_TEXT |
5325 |
- }; |
5326 |
- |
5327 |
- /** |
5328 |
-@@ -1073,6 +1075,12 @@ static const struct sectioncheck sectioncheck[] = { |
5329 |
- .good_tosec = {ALL_TEXT_SECTIONS , NULL}, |
5330 |
- .mismatch = EXTABLE_TO_NON_TEXT, |
5331 |
- .handler = extable_mismatch_handler, |
5332 |
-+}, |
5333 |
-+/* Do not reference code from writable data */ |
5334 |
-+{ |
5335 |
-+ .fromsec = { DATA_SECTIONS, NULL }, |
5336 |
-+ .bad_tosec = { ALL_TEXT_SECTIONS, NULL }, |
5337 |
-+ .mismatch = DATA_TO_TEXT |
5338 |
- } |
5339 |
- }; |
5340 |
- |
5341 |
-@@ -1222,10 +1230,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, |
5342 |
- continue; |
5343 |
- if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) |
5344 |
- continue; |
5345 |
-- if (sym->st_value == addr) |
5346 |
-- return sym; |
5347 |
- /* Find a symbol nearby - addr are maybe negative */ |
5348 |
- d = sym->st_value - addr; |
5349 |
-+ if (d == 0) |
5350 |
-+ return sym; |
5351 |
- if (d < 0) |
5352 |
- d = addr - sym->st_value; |
5353 |
- if (d < distance) { |
5354 |
-@@ -1384,7 +1392,11 @@ static void report_sec_mismatch(const char *modname, |
5355 |
- char *prl_from; |
5356 |
- char *prl_to; |
5357 |
- |
5358 |
-- sec_mismatch_count++; |
5359 |
-+ if (mismatch->mismatch == DATA_TO_TEXT) |
5360 |
-+ writable_fptr_count++; |
5361 |
-+ else |
5362 |
-+ sec_mismatch_count++; |
5363 |
-+ |
5364 |
- if (!sec_mismatch_verbose) |
5365 |
- return; |
5366 |
- |
5367 |
-@@ -1508,6 +1520,14 @@ static void report_sec_mismatch(const char *modname, |
5368 |
- fatal("There's a special handler for this mismatch type, " |
5369 |
- "we should never get here."); |
5370 |
- break; |
5371 |
-+ case DATA_TO_TEXT: |
5372 |
-+#if 0 |
5373 |
-+ fprintf(stderr, |
5374 |
-+ "The %s %s:%s references\n" |
5375 |
-+ "the %s %s:%s%s\n", |
5376 |
-+ from, fromsec, fromsym, to, tosec, tosym, to_p); |
5377 |
-+#endif |
5378 |
-+ break; |
5379 |
- } |
5380 |
- fprintf(stderr, "\n"); |
5381 |
- } |
5382 |
-@@ -1897,7 +1917,7 @@ static void section_rel(const char *modname, struct elf_info *elf, |
5383 |
- static void check_sec_ref(struct module *mod, const char *modname, |
5384 |
- struct elf_info *elf) |
5385 |
- { |
5386 |
-- int i; |
5387 |
-+ unsigned int i; |
5388 |
- Elf_Shdr *sechdrs = elf->sechdrs; |
5389 |
- |
5390 |
- /* Walk through all sections */ |
5391 |
-@@ -2028,7 +2048,7 @@ void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, |
5392 |
- va_end(ap); |
5393 |
- } |
5394 |
- |
5395 |
--void buf_write(struct buffer *buf, const char *s, int len) |
5396 |
-+void buf_write(struct buffer *buf, const char *s, unsigned int len) |
5397 |
- { |
5398 |
- if (buf->size - buf->pos < len) { |
5399 |
- buf->size += len + SZ; |
5400 |
-@@ -2258,7 +2278,7 @@ static void write_if_changed(struct buffer *b, const char *fname) |
5401 |
- if (fstat(fileno(file), &st) < 0) |
5402 |
- goto close_write; |
5403 |
- |
5404 |
-- if (st.st_size != b->pos) |
5405 |
-+ if (st.st_size != (off_t)b->pos) |
5406 |
- goto close_write; |
5407 |
- |
5408 |
- tmp = NOFAIL(malloc(b->pos)); |
5409 |
-@@ -2496,6 +2516,14 @@ int main(int argc, char **argv) |
5410 |
- "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); |
5411 |
- } |
5412 |
- } |
5413 |
-+ if (writable_fptr_count) { |
5414 |
-+ if (!sec_mismatch_verbose) { |
5415 |
-+ warn("modpost: Found %d writable function pointer(s).\n" |
5416 |
-+ "To see full details build your kernel with:\n" |
5417 |
-+ "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", |
5418 |
-+ writable_fptr_count); |
5419 |
-+ } |
5420 |
-+ } |
5421 |
- |
5422 |
- return err; |
5423 |
- } |
5424 |
-diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h |
5425 |
-index 6a5e151..f2fbaf5 100644 |
5426 |
---- a/scripts/mod/modpost.h |
5427 |
-+++ b/scripts/mod/modpost.h |
5428 |
-@@ -98,15 +98,15 @@ void *do_nofail(void *ptr, const char *expr); |
5429 |
- |
5430 |
- struct buffer { |
5431 |
- char *p; |
5432 |
-- int pos; |
5433 |
-- int size; |
5434 |
-+ unsigned int pos; |
5435 |
-+ unsigned int size; |
5436 |
- }; |
5437 |
- |
5438 |
- void __attribute__((format(printf, 2, 3))) |
5439 |
- buf_printf(struct buffer *buf, const char *fmt, ...); |
5440 |
- |
5441 |
- void |
5442 |
--buf_write(struct buffer *buf, const char *s, int len); |
5443 |
-+buf_write(struct buffer *buf, const char *s, unsigned int len); |
5444 |
- |
5445 |
- struct module { |
5446 |
- struct module *next; |
5447 |
-diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c |
5448 |
-index 944418d..15291e4 100644 |
5449 |
---- a/scripts/mod/sumversion.c |
5450 |
-+++ b/scripts/mod/sumversion.c |
5451 |
-@@ -470,7 +470,7 @@ static void write_version(const char *filename, const char *sum, |
5452 |
- goto out; |
5453 |
- } |
5454 |
- |
5455 |
-- if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { |
5456 |
-+ if (write(fd, sum, strlen(sum)+1) != (ssize_t)strlen(sum)+1) { |
5457 |
- warn("writing sum in %s failed: %s\n", |
5458 |
- filename, strerror(errno)); |
5459 |
- goto out; |
5460 |
-diff --git a/scripts/module-common.lds b/scripts/module-common.lds |
5461 |
-index 73a2c7d..df11b31 100644 |
5462 |
---- a/scripts/module-common.lds |
5463 |
-+++ b/scripts/module-common.lds |
5464 |
-@@ -6,6 +6,10 @@ |
5465 |
- SECTIONS { |
5466 |
- /DISCARD/ : { *(.discard) } |
5467 |
- |
5468 |
-+ .rodata 0: { |
5469 |
-+ *(.rodata) *(.rodata.*) |
5470 |
-+ *(.data..read_only) |
5471 |
-+ } |
5472 |
- __ksymtab 0 : { *(SORT(___ksymtab+*)) } |
5473 |
- __ksymtab_gpl 0 : { *(SORT(___ksymtab_gpl+*)) } |
5474 |
- __ksymtab_unused 0 : { *(SORT(___ksymtab_unused+*)) } |
5475 |
-diff --git a/scripts/package/Makefile b/scripts/package/Makefile |
5476 |
-index c2c7389..81b8117 100644 |
5477 |
---- a/scripts/package/Makefile |
5478 |
-+++ b/scripts/package/Makefile |
5479 |
-@@ -40,7 +40,7 @@ if test "$(objtree)" != "$(srctree)"; then \ |
5480 |
- fi ; \ |
5481 |
- $(srctree)/scripts/setlocalversion --save-scmversion; \ |
5482 |
- ln -sf $(srctree) $(2); \ |
5483 |
--tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ |
5484 |
-+tar --owner=root --group=root -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ |
5485 |
- $(addprefix $(2)/,$(TAR_CONTENT) $(3)); \ |
5486 |
- rm -f $(2) $(objtree)/.scmversion |
5487 |
- |
5488 |
-diff --git a/scripts/package/builddeb b/scripts/package/builddeb |
5489 |
-index 6c3b038..54e0b5e 100755 |
5490 |
---- a/scripts/package/builddeb |
5491 |
-+++ b/scripts/package/builddeb |
5492 |
-@@ -326,6 +326,7 @@ fi |
5493 |
- (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" |
5494 |
- (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" |
5495 |
- (cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles" |
5496 |
-+(cd $objtree; find tools/gcc -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles" |
5497 |
- destdir=$kernel_headers_dir/usr/src/linux-headers-$version |
5498 |
- mkdir -p "$destdir" |
5499 |
- (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) |
5500 |
-diff --git a/scripts/package/mkspec b/scripts/package/mkspec |
5501 |
-index fe44d68..3874acb 100755 |
5502 |
---- a/scripts/package/mkspec |
5503 |
-+++ b/scripts/package/mkspec |
5504 |
-@@ -120,29 +120,40 @@ echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/{build,source}" |
5505 |
- echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE" |
5506 |
- echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude=firmware --exclude .config.old --exclude .missing-syscalls.d\"" |
5507 |
- echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)" |
5508 |
--echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE" |
5509 |
--echo "ln -sf /usr/src/kernels/$KERNELRELEASE build" |
5510 |
--echo "ln -sf /usr/src/kernels/$KERNELRELEASE source" |
5511 |
- fi |
5512 |
- |
5513 |
- echo "" |
5514 |
- echo "%clean" |
5515 |
- echo 'rm -rf $RPM_BUILD_ROOT' |
5516 |
- echo "" |
5517 |
-+echo "%pre" |
5518 |
-+echo 'chmod -f 0500 /boot' |
5519 |
-+echo 'if [ -d /lib/modules ]; then' |
5520 |
-+echo 'chmod -f 0500 /lib/modules' |
5521 |
-+echo 'fi' |
5522 |
-+echo 'if [ -d /lib32/modules ]; then' |
5523 |
-+echo 'chmod -f 0500 /lib32/modules' |
5524 |
-+echo 'fi' |
5525 |
-+echo 'if [ -d /lib64/modules ]; then' |
5526 |
-+echo 'chmod -f 0500 /lib64/modules' |
5527 |
-+echo 'fi' |
5528 |
-+echo "" |
5529 |
-+echo "%post devel" |
5530 |
-+echo "ln -sf /usr/src/kernels/$KERNELRELEASE /lib/modules/$KERNELRELEASE/build" |
5531 |
-+echo "ln -sf /usr/src/kernels/$KERNELRELEASE /lib/modules/$KERNELRELEASE/source" |
5532 |
-+echo "" |
5533 |
- echo "%post" |
5534 |
--echo "if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then" |
5535 |
--echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm" |
5536 |
--echo "cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm" |
5537 |
--echo "rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE" |
5538 |
--echo "/sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm" |
5539 |
--echo "rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm" |
5540 |
-+echo "if [ -x /sbin/dracut ]; then" |
5541 |
-+echo '/sbin/new-kernel-pkg --dracut --mkinitrd --depmod --install --make-default '"$KERNELRELEASE"' || exit $?' |
5542 |
-+echo "else" |
5543 |
-+echo '/sbin/new-kernel-pkg --mkinitrd --depmod --install --make-default '"$KERNELRELEASE"' || exit $?' |
5544 |
- echo "fi" |
5545 |
- echo "" |
5546 |
- echo "%files" |
5547 |
--echo '%defattr (-, root, root)' |
5548 |
--echo "/lib/modules/$KERNELRELEASE" |
5549 |
-+echo '%defattr (400, root, root, 500)' |
5550 |
- echo "%exclude /lib/modules/$KERNELRELEASE/build" |
5551 |
- echo "%exclude /lib/modules/$KERNELRELEASE/source" |
5552 |
-+echo "/lib/modules/$KERNELRELEASE" |
5553 |
- echo "/lib/firmware/$KERNELRELEASE" |
5554 |
- echo "/boot/*" |
5555 |
- echo "" |
5556 |
-@@ -152,9 +163,11 @@ echo "/usr/include" |
5557 |
- echo "" |
5558 |
- if ! $PREBUILT; then |
5559 |
- echo "%files devel" |
5560 |
--echo '%defattr (-, root, root)' |
5561 |
-+echo '%defattr (400, root, root, 500)' |
5562 |
-+echo "%dir /lib/modules/$KERNELRELEASE" |
5563 |
- echo "/usr/src/kernels/$KERNELRELEASE" |
5564 |
--echo "/lib/modules/$KERNELRELEASE/build" |
5565 |
--echo "/lib/modules/$KERNELRELEASE/source" |
5566 |
-+echo "%attr (500, root, root) /usr/src/kernels/$KERNELRELEASE/scripts/recordmcount" |
5567 |
-+echo "%attr (500, root, root) /usr/src/kernels/$KERNELRELEASE/scripts/basic/fixdep" |
5568 |
-+echo "%attr (500, root, root) /usr/src/kernels/$KERNELRELEASE/scripts/mod/modpost" |
5569 |
- echo "" |
5570 |
- fi |
5571 |
-diff --git a/scripts/pnmtologo.c b/scripts/pnmtologo.c |
5572 |
-index 4718d78..9220d58 100644 |
5573 |
---- a/scripts/pnmtologo.c |
5574 |
-+++ b/scripts/pnmtologo.c |
5575 |
-@@ -244,14 +244,14 @@ static void write_header(void) |
5576 |
- fprintf(out, " * Linux logo %s\n", logoname); |
5577 |
- fputs(" */\n\n", out); |
5578 |
- fputs("#include <linux/linux_logo.h>\n\n", out); |
5579 |
-- fprintf(out, "static unsigned char %s_data[] __initdata = {\n", |
5580 |
-+ fprintf(out, "static unsigned char %s_data[] = {\n", |
5581 |
- logoname); |
5582 |
- } |
5583 |
- |
5584 |
- static void write_footer(void) |
5585 |
- { |
5586 |
- fputs("\n};\n\n", out); |
5587 |
-- fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); |
5588 |
-+ fprintf(out, "const struct linux_logo %s = {\n", logoname); |
5589 |
- fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); |
5590 |
- fprintf(out, "\t.width\t\t= %d,\n", logo_width); |
5591 |
- fprintf(out, "\t.height\t\t= %d,\n", logo_height); |
5592 |
-@@ -381,7 +381,7 @@ static void write_logo_clut224(void) |
5593 |
- fputs("\n};\n\n", out); |
5594 |
- |
5595 |
- /* write logo clut */ |
5596 |
-- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", |
5597 |
-+ fprintf(out, "static unsigned char %s_clut[] = {\n", |
5598 |
- logoname); |
5599 |
- write_hex_cnt = 0; |
5600 |
- for (i = 0; i < logo_clutsize; i++) { |
5601 |
-diff --git a/scripts/sortextable.h b/scripts/sortextable.h |
5602 |
-index ba87004..3f4852c 100644 |
5603 |
---- a/scripts/sortextable.h |
5604 |
-+++ b/scripts/sortextable.h |
5605 |
-@@ -108,9 +108,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) |
5606 |
- const char *secstrtab; |
5607 |
- const char *strtab; |
5608 |
- char *extab_image; |
5609 |
-- int extab_index = 0; |
5610 |
-- int i; |
5611 |
-- int idx; |
5612 |
-+ unsigned int extab_index = 0; |
5613 |
-+ unsigned int i; |
5614 |
-+ unsigned int idx; |
5615 |
- unsigned int num_sections; |
5616 |
- unsigned int secindex_strings; |
5617 |
- |
5618 |
-diff --git a/scripts/tags.sh b/scripts/tags.sh |
5619 |
-index 23ba1c6..cad2484 100755 |
5620 |
---- a/scripts/tags.sh |
5621 |
-+++ b/scripts/tags.sh |
5622 |
-@@ -26,7 +26,7 @@ else |
5623 |
- fi |
5624 |
- |
5625 |
- # ignore userspace tools |
5626 |
--ignore="$ignore ( -path ${tree}tools ) -prune -o" |
5627 |
-+ignore="$ignore ( -path \"${tree}tools/[^g]*\" ) -prune -o" |
5628 |
- |
5629 |
- # Find all available archs |
5630 |
- find_all_archs() |
5631 |
-diff --git a/security/Kconfig b/security/Kconfig |
5632 |
-index e452378..4388a35 100644 |
5633 |
---- a/security/Kconfig |
5634 |
-+++ b/security/Kconfig |
5635 |
-@@ -4,6 +4,989 @@ |
5636 |
- |
5637 |
- menu "Security options" |
5638 |
- |
5639 |
-+menu "Grsecurity" |
5640 |
+diff --git a/scripts/gcc-plugins/.gitignore b/scripts/gcc-plugins/.gitignore |
5641 |
+new file mode 100644 |
5642 |
+index 0000000..de92ed9 |
5643 |
+--- /dev/null |
5644 |
++++ b/scripts/gcc-plugins/.gitignore |
5645 |
+@@ -0,0 +1 @@ |
5646 |
++randomize_layout_seed.h |
5647 |
+diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile |
5648 |
+new file mode 100644 |
5649 |
+index 0000000..ad7ca02 |
5650 |
+--- /dev/null |
5651 |
++++ b/scripts/gcc-plugins/Makefile |
5652 |
+@@ -0,0 +1,57 @@ |
5653 |
++#CC := gcc |
5654 |
++#PLUGIN_SOURCE_FILES := pax_plugin.c |
5655 |
++#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES)) |
5656 |
++GCCPLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) |
5657 |
++#CFLAGS += -I$(GCCPLUGINS_DIR)/include -fPIC -O2 -Wall -W -std=gnu99 |
5658 |
+ |
5659 |
-+ config ARCH_TRACK_EXEC_LIMIT |
5660 |
-+ bool |
5661 |
++ifeq ($(PLUGINCC),$(HOSTCC)) |
5662 |
++HOSTLIBS := hostlibs |
5663 |
++HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(src) -std=gnu99 -ggdb -Wall -W |
5664 |
++export HOST_EXTRACFLAGS |
5665 |
++else |
5666 |
++HOSTLIBS := hostcxxlibs |
5667 |
++HOST_EXTRACXXFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti -fno-exceptions -fasynchronous-unwind-tables -ggdb -Wall -W -Wno-unused-parameter -Wno-narrowing -Wno-unused-variable |
5668 |
++export HOST_EXTRACXXFLAGS |
5669 |
++endif |
5670 |
+ |
5671 |
-+ config PAX_KERNEXEC_PLUGIN |
5672 |
-+ bool |
5673 |
++export GCCPLUGINS_DIR HOSTLIBS |
5674 |
+ |
5675 |
-+ config PAX_PER_CPU_PGD |
5676 |
-+ bool |
5677 |
++$(HOSTLIBS)-$(CONFIG_PAX_CONSTIFY_PLUGIN) := constify_plugin.so |
5678 |
++$(HOSTLIBS)-$(CONFIG_PAX_MEMORY_STACKLEAK) += stackleak_plugin.so |
5679 |
++$(HOSTLIBS)-$(CONFIG_KALLOCSTAT_PLUGIN) += kallocstat_plugin.so |
5680 |
++$(HOSTLIBS)-$(CONFIG_PAX_KERNEXEC_PLUGIN) += kernexec_plugin.so |
5681 |
++$(HOSTLIBS)-$(CONFIG_CHECKER_PLUGIN) += checker_plugin.so |
5682 |
++$(HOSTLIBS)-y += colorize_plugin.so |
5683 |
++$(HOSTLIBS)-$(CONFIG_PAX_LATENT_ENTROPY) += latent_entropy_plugin.so |
5684 |
++$(HOSTLIBS)-$(CONFIG_PAX_MEMORY_STRUCTLEAK) += structleak_plugin.so |
5685 |
++$(HOSTLIBS)-y += initify_plugin.so |
5686 |
++$(HOSTLIBS)-$(CONFIG_GRKERNSEC_RANDSTRUCT) += randomize_layout_plugin.so |
5687 |
+ |
5688 |
-+ config TASK_SIZE_MAX_SHIFT |
5689 |
-+ int |
5690 |
-+ depends on X86_64 |
5691 |
-+ default 47 if !PAX_PER_CPU_PGD |
5692 |
-+ default 42 if PAX_PER_CPU_PGD |
5693 |
++subdir-$(CONFIG_PAX_SIZE_OVERFLOW) := size_overflow_plugin |
5694 |
++subdir- += size_overflow_plugin |
5695 |
+ |
5696 |
-+ config PAX_ENABLE_PAE |
5697 |
-+ bool |
5698 |
-+ default y if (X86_32 && (MPENTIUM4 || MK8 || MPSC || MCORE2 || MATOM)) |
5699 |
-+ |
5700 |
-+ config PAX_USERCOPY_SLABS |
5701 |
-+ bool |
5702 |
++subdir-$(CONFIG_PAX_RAP) += rap_plugin |
5703 |
++subdir- += rap_plugin |
5704 |
+ |
5705 |
-+config GRKERNSEC |
5706 |
-+ bool "Grsecurity" |
5707 |
-+ select CRYPTO |
5708 |
-+ select CRYPTO_SHA256 |
5709 |
-+ select PROC_FS |
5710 |
-+ select STOP_MACHINE |
5711 |
-+ select TTY |
5712 |
-+ select DEBUG_KERNEL |
5713 |
-+ select DEBUG_LIST |
5714 |
-+ select MULTIUSER |
5715 |
-+ help |
5716 |
-+ If you say Y here, you will be able to configure many features |
5717 |
-+ that will enhance the security of your system. It is highly |
5718 |
-+ recommended that you say Y here and read through the help |
5719 |
-+ for each option so that you fully understand the features and |
5720 |
-+ can evaluate their usefulness for your machine. |
5721 |
++always := $($(HOSTLIBS)-y) |
5722 |
+ |
5723 |
-+choice |
5724 |
-+ prompt "Configuration Method" |
5725 |
-+ depends on GRKERNSEC |
5726 |
-+ default GRKERNSEC_CONFIG_CUSTOM |
5727 |
-+ help |
5728 |
++constify_plugin-objs := constify_plugin.o |
5729 |
++stackleak_plugin-objs := stackleak_plugin.o |
5730 |
++kallocstat_plugin-objs := kallocstat_plugin.o |
5731 |
++kernexec_plugin-objs := kernexec_plugin.o |
5732 |
++checker_plugin-objs := checker_plugin.o |
5733 |
++colorize_plugin-objs := colorize_plugin.o |
5734 |
++latent_entropy_plugin-objs := latent_entropy_plugin.o |
5735 |
++structleak_plugin-objs := structleak_plugin.o |
5736 |
++initify_plugin-objs := initify_plugin.o |
5737 |
++randomize_layout_plugin-objs := randomize_layout_plugin.o |
5738 |
+ |
5739 |
-+config GRKERNSEC_CONFIG_AUTO |
5740 |
-+ bool "Automatic" |
5741 |
-+ help |
5742 |
-+ If you choose this configuration method, you'll be able to answer a small |
5743 |
-+ number of simple questions about how you plan to use this kernel. |
5744 |
-+ The settings of grsecurity and PaX will be automatically configured for |
5745 |
-+ the highest commonly-used settings within the provided constraints. |
5746 |
++$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h |
5747 |
+ |
5748 |
-+ If you require additional configuration, custom changes can still be made |
5749 |
-+ from the "custom configuration" menu. |
5750 |
++quiet_cmd_create_randomize_layout_seed = GENSEED $@ |
5751 |
++ cmd_create_randomize_layout_seed = \ |
5752 |
++ $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h |
5753 |
++$(objtree)/$(obj)/randomize_layout_seed.h: FORCE |
5754 |
++ $(call if_changed,create_randomize_layout_seed) |
5755 |
+ |
5756 |
-+config GRKERNSEC_CONFIG_CUSTOM |
5757 |
-+ bool "Custom" |
5758 |
-+ help |
5759 |
-+ If you choose this configuration method, you'll be able to configure all |
5760 |
-+ grsecurity and PaX settings manually. Via this method, no options are |
5761 |
-+ automatically enabled. |
5762 |
++targets += randomize_layout_seed.h randomize_layout_hash.h |
5763 |
+diff --git a/scripts/gcc-plugins/checker_plugin.c b/scripts/gcc-plugins/checker_plugin.c |
5764 |
+new file mode 100644 |
5765 |
+index 0000000..efaf576 |
5766 |
+--- /dev/null |
5767 |
++++ b/scripts/gcc-plugins/checker_plugin.c |
5768 |
+@@ -0,0 +1,496 @@ |
5769 |
++/* |
5770 |
++ * Copyright 2011-2016 by the PaX Team <pageexec@××××××××.hu> |
5771 |
++ * Licensed under the GPL v2 |
5772 |
++ * |
5773 |
++ * Note: the choice of the license means that the compilation process is |
5774 |
++ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
5775 |
++ * but for the kernel it doesn't matter since it doesn't link against |
5776 |
++ * any of the gcc libraries |
5777 |
++ * |
5778 |
++ * gcc plugin to implement various sparse (source code checker) features |
5779 |
++ * |
5780 |
++ * TODO: |
5781 |
++ * - define separate __iomem, __percpu and __rcu address spaces (lots of code to patch) |
5782 |
++ * |
5783 |
++ * BUGS: |
5784 |
++ * - none known |
5785 |
++ */ |
5786 |
+ |
5787 |
-+ Take note that if menuconfig is exited with this configuration method |
5788 |
-+ chosen, you will not be able to use the automatic configuration methods |
5789 |
-+ without starting again with a kernel configuration with no grsecurity |
5790 |
-+ or PaX options specified inside. |
5791 |
++#include "gcc-common.h" |
5792 |
+ |
5793 |
-+endchoice |
5794 |
++extern void c_register_addr_space (const char *str, addr_space_t as); |
5795 |
++extern enum machine_mode default_addr_space_pointer_mode (addr_space_t); |
5796 |
++extern enum machine_mode default_addr_space_address_mode (addr_space_t); |
5797 |
++extern bool default_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as); |
5798 |
++extern bool default_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as); |
5799 |
++extern rtx default_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as); |
5800 |
+ |
5801 |
-+choice |
5802 |
-+ prompt "Usage Type" |
5803 |
-+ depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO) |
5804 |
-+ default GRKERNSEC_CONFIG_SERVER |
5805 |
-+ help |
5806 |
++int plugin_is_GPL_compatible; |
5807 |
+ |
5808 |
-+config GRKERNSEC_CONFIG_SERVER |
5809 |
-+ bool "Server" |
5810 |
-+ help |
5811 |
-+ Choose this option if you plan to use this kernel on a server. |
5812 |
++static struct plugin_info checker_plugin_info = { |
5813 |
++ .version = "201602181345", |
5814 |
++ .help = "user\tturn on user/kernel address space checking\n" |
5815 |
++ "context\tturn on locking context checking\n" |
5816 |
++}; |
5817 |
+ |
5818 |
-+config GRKERNSEC_CONFIG_DESKTOP |
5819 |
-+ bool "Desktop" |
5820 |
-+ help |
5821 |
-+ Choose this option if you plan to use this kernel on a desktop. |
5822 |
++#define ADDR_SPACE_KERNEL 0 |
5823 |
++#define ADDR_SPACE_FORCE_KERNEL 1 |
5824 |
++#define ADDR_SPACE_USER 2 |
5825 |
++#define ADDR_SPACE_FORCE_USER 3 |
5826 |
++#define ADDR_SPACE_IOMEM 0 |
5827 |
++#define ADDR_SPACE_FORCE_IOMEM 0 |
5828 |
++#define ADDR_SPACE_PERCPU 0 |
5829 |
++#define ADDR_SPACE_FORCE_PERCPU 0 |
5830 |
++#define ADDR_SPACE_RCU 0 |
5831 |
++#define ADDR_SPACE_FORCE_RCU 0 |
5832 |
+ |
5833 |
-+endchoice |
5834 |
++static enum machine_mode checker_addr_space_pointer_mode(addr_space_t addrspace) |
5835 |
++{ |
5836 |
++ return default_addr_space_pointer_mode(ADDR_SPACE_GENERIC); |
5837 |
++} |
5838 |
+ |
5839 |
-+choice |
5840 |
-+ prompt "Virtualization Type" |
5841 |
-+ depends on (GRKERNSEC && X86 && GRKERNSEC_CONFIG_AUTO) |
5842 |
-+ default GRKERNSEC_CONFIG_VIRT_NONE |
5843 |
-+ help |
5844 |
++static enum machine_mode checker_addr_space_address_mode(addr_space_t addrspace) |
5845 |
++{ |
5846 |
++ return default_addr_space_address_mode(ADDR_SPACE_GENERIC); |
5847 |
++} |
5848 |
+ |
5849 |
-+config GRKERNSEC_CONFIG_VIRT_NONE |
5850 |
-+ bool "None" |
5851 |
-+ help |
5852 |
-+ Choose this option if this kernel will be run on bare metal. |
5853 |
++static bool checker_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as) |
5854 |
++{ |
5855 |
++ return default_addr_space_valid_pointer_mode(mode, as); |
5856 |
++} |
5857 |
+ |
5858 |
-+config GRKERNSEC_CONFIG_VIRT_GUEST |
5859 |
-+ bool "Guest" |
5860 |
-+ help |
5861 |
-+ Choose this option if this kernel will be run as a VM guest. |
5862 |
++static bool checker_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as) |
5863 |
++{ |
5864 |
++ return default_addr_space_legitimate_address_p(mode, mem, strict, ADDR_SPACE_GENERIC); |
5865 |
++} |
5866 |
+ |
5867 |
-+config GRKERNSEC_CONFIG_VIRT_HOST |
5868 |
-+ bool "Host" |
5869 |
-+ help |
5870 |
-+ Choose this option if this kernel will be run as a VM host. |
5871 |
++static rtx checker_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as) |
5872 |
++{ |
5873 |
++ return default_addr_space_legitimize_address(x, oldx, mode, as); |
5874 |
++} |
5875 |
+ |
5876 |
-+endchoice |
5877 |
++static bool checker_addr_space_subset_p(addr_space_t subset, addr_space_t superset) |
5878 |
++{ |
5879 |
++ if (subset == ADDR_SPACE_FORCE_KERNEL && superset == ADDR_SPACE_KERNEL) |
5880 |
++ return true; |
5881 |
+ |
5882 |
-+choice |
5883 |
-+ prompt "Virtualization Hardware" |
5884 |
-+ depends on (GRKERNSEC && X86 && GRKERNSEC_CONFIG_AUTO && (GRKERNSEC_CONFIG_VIRT_GUEST || GRKERNSEC_CONFIG_VIRT_HOST)) |
5885 |
-+ help |
5886 |
++ if (subset == ADDR_SPACE_FORCE_USER && superset == ADDR_SPACE_USER) |
5887 |
++ return true; |
5888 |
+ |
5889 |
-+config GRKERNSEC_CONFIG_VIRT_EPT |
5890 |
-+ bool "EPT/RVI Processor Support" |
5891 |
-+ depends on X86 |
5892 |
-+ help |
5893 |
-+ Choose this option if your CPU supports the EPT or RVI features of 2nd-gen |
5894 |
-+ hardware virtualization. This allows for additional kernel hardening protections |
5895 |
-+ to operate without additional performance impact. |
5896 |
++ if (subset == ADDR_SPACE_FORCE_IOMEM && superset == ADDR_SPACE_IOMEM) |
5897 |
++ return true; |
5898 |
+ |
5899 |
-+ To see if your Intel processor supports EPT, see: |
5900 |
-+ http://ark.intel.com/Products/VirtualizationTechnology |
5901 |
-+ (Most Core i3/5/7 support EPT) |
5902 |
++ if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_USER) |
5903 |
++ return true; |
5904 |
+ |
5905 |
-+ To see if your AMD processor supports RVI, see: |
5906 |
-+ http://support.amd.com/us/kbarticles/Pages/GPU120AMDRVICPUsHyperVWin8.aspx |
5907 |
++ if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_IOMEM) |
5908 |
++ return true; |
5909 |
+ |
5910 |
-+config GRKERNSEC_CONFIG_VIRT_SOFT |
5911 |
-+ bool "First-gen/No Hardware Virtualization" |
5912 |
-+ help |
5913 |
-+ Choose this option if you use an Atom/Pentium/Core 2 processor that either doesn't |
5914 |
-+ support hardware virtualization or doesn't support the EPT/RVI extensions. |
5915 |
++ if (subset == ADDR_SPACE_USER && superset == ADDR_SPACE_FORCE_KERNEL) |
5916 |
++ return true; |
5917 |
+ |
5918 |
-+endchoice |
5919 |
++ if (subset == ADDR_SPACE_IOMEM && superset == ADDR_SPACE_FORCE_KERNEL) |
5920 |
++ return true; |
5921 |
+ |
5922 |
-+choice |
5923 |
-+ prompt "Virtualization Software" |
5924 |
-+ depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO && (GRKERNSEC_CONFIG_VIRT_GUEST || GRKERNSEC_CONFIG_VIRT_HOST)) |
5925 |
-+ help |
5926 |
++ return subset == superset; |
5927 |
++} |
5928 |
+ |
5929 |
-+config GRKERNSEC_CONFIG_VIRT_XEN |
5930 |
-+ bool "Xen" |
5931 |
-+ help |
5932 |
-+ Choose this option if this kernel is running as a Xen guest or host. |
5933 |
++static rtx checker_addr_space_convert(rtx op, tree from_type, tree to_type) |
5934 |
++{ |
5935 |
++// addr_space_t from_as = TYPE_ADDR_SPACE(TREE_TYPE(from_type)); |
5936 |
++// addr_space_t to_as = TYPE_ADDR_SPACE(TREE_TYPE(to_type)); |
5937 |
+ |
5938 |
-+config GRKERNSEC_CONFIG_VIRT_VMWARE |
5939 |
-+ bool "VMWare" |
5940 |
-+ help |
5941 |
-+ Choose this option if this kernel is running as a VMWare guest or host. |
5942 |
++ return op; |
5943 |
++} |
5944 |
+ |
5945 |
-+config GRKERNSEC_CONFIG_VIRT_KVM |
5946 |
-+ bool "KVM" |
5947 |
-+ help |
5948 |
-+ Choose this option if this kernel is running as a KVM guest or host. |
5949 |
++static void register_checker_address_spaces(void *event_data, void *data) |
5950 |
++{ |
5951 |
++ c_register_addr_space("__kernel", ADDR_SPACE_KERNEL); |
5952 |
++ c_register_addr_space("__force_kernel", ADDR_SPACE_FORCE_KERNEL); |
5953 |
++ c_register_addr_space("__user", ADDR_SPACE_USER); |
5954 |
++ c_register_addr_space("__force_user", ADDR_SPACE_FORCE_USER); |
5955 |
++// c_register_addr_space("__iomem", ADDR_SPACE_IOMEM); |
5956 |
++// c_register_addr_space("__force_iomem", ADDR_SPACE_FORCE_IOMEM); |
5957 |
++// c_register_addr_space("__percpu", ADDR_SPACE_PERCPU); |
5958 |
++// c_register_addr_space("__force_percpu", ADDR_SPACE_FORCE_PERCPU); |
5959 |
++// c_register_addr_space("__rcu", ADDR_SPACE_RCU); |
5960 |
++// c_register_addr_space("__force_rcu", ADDR_SPACE_FORCE_RCU); |
5961 |
+ |
5962 |
-+config GRKERNSEC_CONFIG_VIRT_VIRTUALBOX |
5963 |
-+ bool "VirtualBox" |
5964 |
-+ help |
5965 |
-+ Choose this option if this kernel is running as a VirtualBox guest or host. |
5966 |
++ targetm.addr_space.pointer_mode = checker_addr_space_pointer_mode; |
5967 |
++ targetm.addr_space.address_mode = checker_addr_space_address_mode; |
5968 |
++ targetm.addr_space.valid_pointer_mode = checker_addr_space_valid_pointer_mode; |
5969 |
++ targetm.addr_space.legitimate_address_p = checker_addr_space_legitimate_address_p; |
5970 |
++// targetm.addr_space.legitimize_address = checker_addr_space_legitimize_address; |
5971 |
++ targetm.addr_space.subset_p = checker_addr_space_subset_p; |
5972 |
++ targetm.addr_space.convert = checker_addr_space_convert; |
5973 |
++} |
5974 |
+ |
5975 |
-+config GRKERNSEC_CONFIG_VIRT_HYPERV |
5976 |
-+ bool "Hyper-V" |
5977 |
-+ help |
5978 |
-+ Choose this option if this kernel is running as a Hyper-V guest. |
5979 |
++static bool split_context_attribute(tree args, tree *lock, tree *in, tree *out) |
5980 |
++{ |
5981 |
++ *in = TREE_VALUE(args); |
5982 |
+ |
5983 |
-+endchoice |
5984 |
++ if (TREE_CODE(*in) != INTEGER_CST) { |
5985 |
++ *lock = *in; |
5986 |
++ args = TREE_CHAIN(args); |
5987 |
++ *in = TREE_VALUE(args); |
5988 |
++ } else |
5989 |
++ *lock = NULL_TREE; |
5990 |
+ |
5991 |
-+choice |
5992 |
-+ prompt "Required Priorities" |
5993 |
-+ depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO) |
5994 |
-+ default GRKERNSEC_CONFIG_PRIORITY_PERF |
5995 |
-+ help |
5996 |
++ args = TREE_CHAIN(args); |
5997 |
++ if (*lock && !args) |
5998 |
++ return false; |
5999 |
+ |
6000 |
-+config GRKERNSEC_CONFIG_PRIORITY_PERF |
6001 |
-+ bool "Performance" |
6002 |
-+ help |
6003 |
-+ Choose this option if performance is of highest priority for this deployment |
6004 |
-+ of grsecurity. Features like UDEREF on a 64bit kernel, kernel stack clearing, |
6005 |
-+ clearing of structures intended for userland, and freed memory sanitizing will |
6006 |
-+ be disabled. |
6007 |
++ *out = TREE_VALUE(args); |
6008 |
++ return true; |
6009 |
++} |
6010 |
+ |
6011 |
-+config GRKERNSEC_CONFIG_PRIORITY_SECURITY |
6012 |
-+ bool "Security" |
6013 |
-+ help |
6014 |
-+ Choose this option if security is of highest priority for this deployment of |
6015 |
-+ grsecurity. UDEREF, kernel stack clearing, clearing of structures intended |
6016 |
-+ for userland, and freed memory sanitizing will be enabled for this kernel. |
6017 |
-+ In a worst-case scenario, these features can introduce a 20% performance hit |
6018 |
-+ (UDEREF on x64 contributing half of this hit). |
6019 |
++static tree handle_context_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
6020 |
++{ |
6021 |
++ *no_add_attrs = true; |
6022 |
++ tree lock, in, out; |
6023 |
+ |
6024 |
-+endchoice |
6025 |
++ if (TREE_CODE(*node) != FUNCTION_DECL) { |
6026 |
++ error("%qE attribute applies to functions only (%qD)", name, *node); |
6027 |
++ return NULL_TREE; |
6028 |
++ } |
6029 |
+ |
6030 |
-+menu "Default Special Groups" |
6031 |
-+depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO) |
6032 |
++ if (!split_context_attribute(args, &lock, &in, &out)) { |
6033 |
++ error("%qE attribute needs two integers after the lock expression", name); |
6034 |
++ return NULL_TREE; |
6035 |
++ } |
6036 |
+ |
6037 |
-+config GRKERNSEC_PROC_GID |
6038 |
-+ int "GID exempted from /proc restrictions" |
6039 |
-+ default 1001 |
6040 |
-+ help |
6041 |
-+ Setting this GID determines which group will be exempted from |
6042 |
-+ grsecurity's /proc restrictions, allowing users of the specified |
6043 |
-+ group to view network statistics and the existence of other users' |
6044 |
-+ processes on the system. This GID may also be chosen at boot time |
6045 |
-+ via "grsec_proc_gid=" on the kernel commandline. |
6046 |
++ if (TREE_CODE(in) != INTEGER_CST) { |
6047 |
++ error("the 'in' argument of the %qE attribute must be an integer (%qE)", name, in); |
6048 |
++ return NULL_TREE; |
6049 |
++ } |
6050 |
+ |
6051 |
-+config GRKERNSEC_TPE_UNTRUSTED_GID |
6052 |
-+ int "GID for TPE-untrusted users" |
6053 |
-+ depends on GRKERNSEC_CONFIG_SERVER && GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT |
6054 |
-+ default 1005 |
6055 |
-+ help |
6056 |
-+ Setting this GID determines which group untrusted users should |
6057 |
-+ be added to. These users will be placed under grsecurity's Trusted Path |
6058 |
-+ Execution mechanism, preventing them from executing their own binaries. |
6059 |
-+ The users will only be able to execute binaries in directories owned and |
6060 |
-+ writable only by the root user. If the sysctl option is enabled, a sysctl |
6061 |
-+ option with name "tpe_gid" is created. |
6062 |
++ if (TREE_CODE(out) != INTEGER_CST) { |
6063 |
++ error("the 'out' argument of the %qE attribute must be an integer (%qE)", name, out); |
6064 |
++ return NULL_TREE; |
6065 |
++ } |
6066 |
+ |
6067 |
-+config GRKERNSEC_TPE_TRUSTED_GID |
6068 |
-+ int "GID for TPE-trusted users" |
6069 |
-+ depends on GRKERNSEC_CONFIG_SERVER && GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT |
6070 |
-+ default 1005 |
6071 |
-+ help |
6072 |
-+ Setting this GID determines what group TPE restrictions will be |
6073 |
-+ *disabled* for. If the sysctl option is enabled, a sysctl option |
6074 |
-+ with name "tpe_gid" is created. |
6075 |
++ *no_add_attrs = false; |
6076 |
++ return NULL_TREE; |
6077 |
++} |
6078 |
+ |
6079 |
-+config GRKERNSEC_SYMLINKOWN_GID |
6080 |
-+ int "GID for users with kernel-enforced SymlinksIfOwnerMatch" |
6081 |
-+ depends on GRKERNSEC_CONFIG_SERVER |
6082 |
-+ default 1006 |
6083 |
-+ help |
6084 |
-+ Setting this GID determines what group kernel-enforced |
6085 |
-+ SymlinksIfOwnerMatch will be enabled for. If the sysctl option |
6086 |
-+ is enabled, a sysctl option with name "symlinkown_gid" is created. |
6087 |
++static struct attribute_spec context_attr = { |
6088 |
++ .name = "context", |
6089 |
++ .min_length = 2, |
6090 |
++ .max_length = 3, |
6091 |
++ .decl_required = true, |
6092 |
++ .type_required = false, |
6093 |
++ .function_type_required = false, |
6094 |
++ .handler = handle_context_attribute, |
6095 |
++#if BUILDING_GCC_VERSION >= 4007 |
6096 |
++ .affects_type_identity = true |
6097 |
++#endif |
6098 |
++}; |
6099 |
+ |
6100 |
++static void register_attributes(void *event_data, void *data) |
6101 |
++{ |
6102 |
++ register_attribute(&context_attr); |
6103 |
++} |
6104 |
+ |
6105 |
-+endmenu |
6106 |
++static const char context_function[] = "__context__"; |
6107 |
++static GTY(()) tree context_function_decl; |
6108 |
+ |
6109 |
-+menu "Customize Configuration" |
6110 |
-+depends on GRKERNSEC |
6111 |
++static const char context_error[] = "__context_error__"; |
6112 |
++static GTY(()) tree context_error_decl; |
6113 |
+ |
6114 |
-+menu "PaX" |
6115 |
++static void context_start_unit(void __unused *gcc_data, void __unused *user_data) |
6116 |
++{ |
6117 |
++ tree fntype, attr; |
6118 |
+ |
6119 |
-+config PAX |
6120 |
-+ bool "Enable various PaX features" |
6121 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6122 |
-+ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS || PARISC || PPC || SPARC || X86) |
6123 |
-+ help |
6124 |
-+ This allows you to enable various PaX features. PaX adds |
6125 |
-+ intrusion prevention mechanisms to the kernel that reduce |
6126 |
-+ the risks posed by exploitable memory corruption bugs. |
6127 |
++ // void __context__(void *, int); |
6128 |
++ fntype = build_function_type_list(void_type_node, ptr_type_node, integer_type_node, NULL_TREE); |
6129 |
++ context_function_decl = build_fn_decl(context_function, fntype); |
6130 |
+ |
6131 |
-+menu "PaX Control" |
6132 |
-+ depends on PAX |
6133 |
++ TREE_PUBLIC(context_function_decl) = 1; |
6134 |
++ TREE_USED(context_function_decl) = 1; |
6135 |
++ DECL_EXTERNAL(context_function_decl) = 1; |
6136 |
++ DECL_ARTIFICIAL(context_function_decl) = 1; |
6137 |
++ DECL_PRESERVE_P(context_function_decl) = 1; |
6138 |
++// TREE_NOTHROW(context_function_decl) = 1; |
6139 |
++// DECL_UNINLINABLE(context_function_decl) = 1; |
6140 |
++ DECL_ASSEMBLER_NAME(context_function_decl); // for LTO |
6141 |
++ lang_hooks.decls.pushdecl(context_function_decl); |
6142 |
+ |
6143 |
-+config PAX_SOFTMODE |
6144 |
-+ bool 'Support soft mode' |
6145 |
-+ help |
6146 |
-+ Enabling this option will allow you to run PaX in soft mode, that |
6147 |
-+ is, PaX features will not be enforced by default, only on executables |
6148 |
-+ marked explicitly. You must also enable PT_PAX_FLAGS or XATTR_PAX_FLAGS |
6149 |
-+ support as they are the only way to mark executables for soft mode use. |
6150 |
++ // void __context_error__(const void *, int) __attribute__((error("context error"))); |
6151 |
++ fntype = build_function_type_list(void_type_node, const_ptr_type_node, integer_type_node, NULL_TREE); |
6152 |
++ context_error_decl = build_fn_decl(context_error, fntype); |
6153 |
+ |
6154 |
-+ Soft mode can be activated by using the "pax_softmode=1" kernel command |
6155 |
-+ line option on boot. Furthermore you can control various PaX features |
6156 |
-+ at runtime via the entries in /proc/sys/kernel/pax. |
6157 |
++ TREE_PUBLIC(context_error_decl) = 1; |
6158 |
++ TREE_USED(context_error_decl) = 1; |
6159 |
++ DECL_EXTERNAL(context_error_decl) = 1; |
6160 |
++ DECL_ARTIFICIAL(context_error_decl) = 1; |
6161 |
++ DECL_PRESERVE_P(context_error_decl) = 1; |
6162 |
++// TREE_NOTHROW(context_error_decl) = 1; |
6163 |
++// DECL_UNINLINABLE(context_error_decl) = 1; |
6164 |
++ TREE_THIS_VOLATILE(context_error_decl) = 1; |
6165 |
++ DECL_ASSEMBLER_NAME(context_error_decl); |
6166 |
+ |
6167 |
-+config PAX_EI_PAX |
6168 |
-+ bool 'Use legacy ELF header marking' |
6169 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6170 |
-+ help |
6171 |
-+ Enabling this option will allow you to control PaX features on |
6172 |
-+ a per executable basis via the 'chpax' utility available at |
6173 |
-+ http://pax.grsecurity.net/. The control flags will be read from |
6174 |
-+ an otherwise reserved part of the ELF header. This marking has |
6175 |
-+ numerous drawbacks (no support for soft-mode, toolchain does not |
6176 |
-+ know about the non-standard use of the ELF header) therefore it |
6177 |
-+ has been deprecated in favour of PT_PAX_FLAGS and XATTR_PAX_FLAGS |
6178 |
-+ support. |
6179 |
++ attr = tree_cons(NULL, build_string(14, "context error"), NULL); |
6180 |
++ attr = tree_cons(get_identifier("error"), attr, NULL); |
6181 |
++ decl_attributes(&context_error_decl, attr, 0); |
6182 |
++} |
6183 |
+ |
6184 |
-+ Note that if you enable PT_PAX_FLAGS or XATTR_PAX_FLAGS marking |
6185 |
-+ support as well, they will override the legacy EI_PAX marks. |
6186 |
++static bool context_gate(void) |
6187 |
++{ |
6188 |
++ tree context_attr; |
6189 |
+ |
6190 |
-+ If you enable none of the marking options then all applications |
6191 |
-+ will run with PaX enabled on them by default. |
6192 |
++return true; |
6193 |
+ |
6194 |
-+config PAX_PT_PAX_FLAGS |
6195 |
-+ bool 'Use ELF program header marking' |
6196 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6197 |
-+ help |
6198 |
-+ Enabling this option will allow you to control PaX features on |
6199 |
-+ a per executable basis via the 'paxctl' utility available at |
6200 |
-+ http://pax.grsecurity.net/. The control flags will be read from |
6201 |
-+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking |
6202 |
-+ has the benefits of supporting both soft mode and being fully |
6203 |
-+ integrated into the toolchain (the binutils patch is available |
6204 |
-+ from http://pax.grsecurity.net). |
6205 |
-+ |
6206 |
-+ Note that if you enable the legacy EI_PAX marking support as well, |
6207 |
-+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. |
6208 |
-+ |
6209 |
-+ If you enable both PT_PAX_FLAGS and XATTR_PAX_FLAGS support then you |
6210 |
-+ must make sure that the marks are the same if a binary has both marks. |
6211 |
++ context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl)); |
6212 |
++ return context_attr != NULL_TREE; |
6213 |
++} |
6214 |
+ |
6215 |
-+ If you enable none of the marking options then all applications |
6216 |
-+ will run with PaX enabled on them by default. |
6217 |
++static basic_block verify_context_before(gimple_stmt_iterator *gsi, tree context, tree inout, tree error) |
6218 |
++{ |
6219 |
++ gimple stmt; |
6220 |
++ basic_block cond_bb, join_bb, true_bb; |
6221 |
++ edge e; |
6222 |
++ location_t loc; |
6223 |
++ const char *file; |
6224 |
++ int line; |
6225 |
++ size_t len; |
6226 |
++ tree filename; |
6227 |
+ |
6228 |
-+config PAX_XATTR_PAX_FLAGS |
6229 |
-+ bool 'Use filesystem extended attributes marking' |
6230 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6231 |
-+ select CIFS_XATTR if CIFS |
6232 |
-+ select EXT2_FS_XATTR if EXT2_FS |
6233 |
-+ select EXT3_FS_XATTR if EXT3_FS |
6234 |
-+ select F2FS_FS_XATTR if F2FS_FS |
6235 |
-+ select JFFS2_FS_XATTR if JFFS2_FS |
6236 |
-+ select REISERFS_FS_XATTR if REISERFS_FS |
6237 |
-+ select SQUASHFS_XATTR if SQUASHFS |
6238 |
-+ select TMPFS_XATTR if TMPFS |
6239 |
-+ help |
6240 |
-+ Enabling this option will allow you to control PaX features on |
6241 |
-+ a per executable basis via the 'setfattr' utility. The control |
6242 |
-+ flags will be read from the user.pax.flags extended attribute of |
6243 |
-+ the file. This marking has the benefit of supporting binary-only |
6244 |
-+ applications that self-check themselves (e.g., skype) and would |
6245 |
-+ not tolerate chpax/paxctl changes. The main drawback is that |
6246 |
-+ extended attributes are not supported by some filesystems (e.g., |
6247 |
-+ isofs, udf, vfat) so copying files through such filesystems will |
6248 |
-+ lose the extended attributes and these PaX markings. |
6249 |
++ stmt = gsi_stmt(*gsi); |
6250 |
++ if (gimple_has_location(stmt)) { |
6251 |
++ loc = gimple_location(stmt); |
6252 |
++ file = gimple_filename(stmt); |
6253 |
++ line = gimple_lineno(stmt); |
6254 |
++ } else { |
6255 |
++ loc = DECL_SOURCE_LOCATION(current_function_decl); |
6256 |
++ file = DECL_SOURCE_FILE(current_function_decl); |
6257 |
++ line = DECL_SOURCE_LINE(current_function_decl); |
6258 |
++ } |
6259 |
++ gcc_assert(file); |
6260 |
+ |
6261 |
-+ Note that if you enable the legacy EI_PAX marking support as well, |
6262 |
-+ the EI_PAX marks will be overridden by the XATTR_PAX_FLAGS marks. |
6263 |
++ // if (context != count) __context_error__(__FILE__, __LINE__); |
6264 |
++ stmt = gimple_build_cond(NE_EXPR, context, inout, NULL_TREE, NULL_TREE); |
6265 |
++ gimple_set_location(stmt, loc); |
6266 |
++ gsi_insert_before(gsi, stmt, GSI_NEW_STMT); |
6267 |
+ |
6268 |
-+ If you enable both PT_PAX_FLAGS and XATTR_PAX_FLAGS support then you |
6269 |
-+ must make sure that the marks are the same if a binary has both marks. |
6270 |
++ cond_bb = gsi_bb(*gsi); |
6271 |
++ gcc_assert(!gsi_end_p(*gsi)); |
6272 |
++ gcc_assert(stmt == gsi_stmt(*gsi)); |
6273 |
+ |
6274 |
-+ If you enable none of the marking options then all applications |
6275 |
-+ will run with PaX enabled on them by default. |
6276 |
++ e = split_block(cond_bb, gsi_stmt(*gsi)); |
6277 |
++ cond_bb = e->src; |
6278 |
++ join_bb = e->dest; |
6279 |
++ e->flags = EDGE_FALSE_VALUE; |
6280 |
++ e->probability = REG_BR_PROB_BASE; |
6281 |
+ |
6282 |
-+choice |
6283 |
-+ prompt 'MAC system integration' |
6284 |
-+ default PAX_HAVE_ACL_FLAGS |
6285 |
-+ help |
6286 |
-+ Mandatory Access Control systems have the option of controlling |
6287 |
-+ PaX flags on a per executable basis, choose the method supported |
6288 |
-+ by your particular system. |
6289 |
++ true_bb = create_empty_bb(EXIT_BLOCK_PTR_FOR_FN(cfun)->prev_bb); |
6290 |
++ make_edge(cond_bb, true_bb, EDGE_TRUE_VALUE); |
6291 |
++ make_edge(true_bb, join_bb, EDGE_FALLTHRU); |
6292 |
+ |
6293 |
-+ - "none": if your MAC system does not interact with PaX, |
6294 |
-+ - "direct": if your MAC system defines pax_set_initial_flags() itself, |
6295 |
-+ - "hook": if your MAC system uses the pax_set_initial_flags_func callback. |
6296 |
++ set_immediate_dominator(CDI_DOMINATORS, true_bb, cond_bb); |
6297 |
++ set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb); |
6298 |
+ |
6299 |
-+ NOTE: this option is for developers/integrators only. |
6300 |
++ gcc_assert(cond_bb->loop_father == join_bb->loop_father); |
6301 |
++ add_bb_to_loop(true_bb, cond_bb->loop_father); |
6302 |
+ |
6303 |
-+ config PAX_NO_ACL_FLAGS |
6304 |
-+ bool 'none' |
6305 |
++ // insert call to builtin_trap or __context_error__ |
6306 |
++ *gsi = gsi_start_bb(true_bb); |
6307 |
+ |
6308 |
-+ config PAX_HAVE_ACL_FLAGS |
6309 |
-+ bool 'direct' |
6310 |
++// stmt = gimple_build_call(builtin_decl_implicit(BUILT_IN_TRAP), 0); |
6311 |
++ len = strlen(file) + 1; |
6312 |
++ filename = build_string(len, file); |
6313 |
++ TREE_TYPE(filename) = build_array_type(unsigned_char_type_node, build_index_type(size_int(len))); |
6314 |
++ filename = build1(ADDR_EXPR, const_ptr_type_node, filename); |
6315 |
++ stmt = gimple_build_call(error, 2, filename, build_int_cst(NULL_TREE, line)); |
6316 |
++ gimple_set_location(stmt, loc); |
6317 |
++ gsi_insert_after(gsi, stmt, GSI_CONTINUE_LINKING); |
6318 |
+ |
6319 |
-+ config PAX_HOOK_ACL_FLAGS |
6320 |
-+ bool 'hook' |
6321 |
-+endchoice |
6322 |
++ *gsi = gsi_start_nondebug_bb(join_bb); |
6323 |
++ return join_bb; |
6324 |
++} |
6325 |
+ |
6326 |
-+endmenu |
6327 |
++static void update_context(gimple_stmt_iterator *gsi, tree context, int diff) |
6328 |
++{ |
6329 |
++ gimple assign; |
6330 |
++ tree op; |
6331 |
+ |
6332 |
-+menu "Non-executable pages" |
6333 |
-+ depends on PAX |
6334 |
++ op = fold_build2_loc(UNKNOWN_LOCATION, PLUS_EXPR, integer_type_node, context, build_int_cst(integer_type_node, diff)); |
6335 |
++ assign = gimple_build_assign(context, op); |
6336 |
++ gsi_insert_after(gsi, assign, GSI_NEW_STMT); |
6337 |
++ update_stmt(assign); |
6338 |
++} |
6339 |
+ |
6340 |
-+config PAX_NOEXEC |
6341 |
-+ bool "Enforce non-executable pages" |
6342 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6343 |
-+ depends on ALPHA || (ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || IA64 || MIPS || PARISC || PPC || S390 || SPARC || X86 |
6344 |
-+ help |
6345 |
-+ By design some architectures do not allow for protecting memory |
6346 |
-+ pages against execution or even if they do, Linux does not make |
6347 |
-+ use of this feature. In practice this means that if a page is |
6348 |
-+ readable (such as the stack or heap) it is also executable. |
6349 |
++static basic_block track_context(basic_block bb, tree context) |
6350 |
++{ |
6351 |
++ gimple_stmt_iterator gsi; |
6352 |
++ gimple assign; |
6353 |
+ |
6354 |
-+ There is a well known exploit technique that makes use of this |
6355 |
-+ fact and a common programming mistake where an attacker can |
6356 |
-+ introduce code of his choice somewhere in the attacked program's |
6357 |
-+ memory (typically the stack or the heap) and then execute it. |
6358 |
++ // adjust context according to the context information on any call stmt |
6359 |
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
6360 |
++ gimple stmt = gsi_stmt(gsi); |
6361 |
++ tree fndecl, context_attr; |
6362 |
++ tree lock, in, out; |
6363 |
++ int incount, outcount; |
6364 |
+ |
6365 |
-+ If the attacked program was running with different (typically |
6366 |
-+ higher) privileges than that of the attacker, then he can elevate |
6367 |
-+ his own privilege level (e.g. get a root shell, write to files for |
6368 |
-+ which he does not have write access to, etc). |
6369 |
++ if (!is_gimple_call(stmt)) |
6370 |
++ continue; |
6371 |
+ |
6372 |
-+ Enabling this option will let you choose from various features |
6373 |
-+ that prevent the injection and execution of 'foreign' code in |
6374 |
-+ a program. |
6375 |
++ fndecl = gimple_call_fndecl(stmt); |
6376 |
++ if (!fndecl) |
6377 |
++ continue; |
6378 |
+ |
6379 |
-+ This will also break programs that rely on the old behaviour and |
6380 |
-+ expect that dynamically allocated memory via the malloc() family |
6381 |
-+ of functions is executable (which it is not). Notable examples |
6382 |
-+ are the XFree86 4.x server, the java runtime and wine. |
6383 |
++ if (fndecl == context_function_decl) { |
6384 |
++ unsigned int num_ops = gimple_num_ops(stmt); |
6385 |
++ int diff = tree_to_shwi(gimple_op(stmt, num_ops - 1)); |
6386 |
+ |
6387 |
-+config PAX_PAGEEXEC |
6388 |
-+ bool "Paging based non-executable pages" |
6389 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6390 |
-+ depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MATOM || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7) |
6391 |
-+ select ARCH_TRACK_EXEC_LIMIT if X86_32 |
6392 |
-+ help |
6393 |
-+ This implementation is based on the paging feature of the CPU. |
6394 |
-+ On i386 without hardware non-executable bit support there is a |
6395 |
-+ variable but usually low performance impact, however on Intel's |
6396 |
-+ P4 core based CPUs it is very high so you should not enable this |
6397 |
-+ for kernels meant to be used on such CPUs. |
6398 |
++ gcc_assert(diff); |
6399 |
++ update_context(&gsi, context, diff); |
6400 |
++ continue; |
6401 |
++ } |
6402 |
+ |
6403 |
-+ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386 |
6404 |
-+ with hardware non-executable bit support there is no performance |
6405 |
-+ impact, on ppc the impact is negligible. |
6406 |
++ context_attr = lookup_attribute("context", DECL_ATTRIBUTES(fndecl)); |
6407 |
++ if (!context_attr) |
6408 |
++ continue; |
6409 |
+ |
6410 |
-+ Note that several architectures require various emulations due to |
6411 |
-+ badly designed userland ABIs, this will cause a performance impact |
6412 |
-+ but will disappear as soon as userland is fixed. For example, ppc |
6413 |
-+ userland MUST have been built with secure-plt by a recent toolchain. |
6414 |
++ gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out)); |
6415 |
++ incount = tree_to_shwi(in); |
6416 |
++ outcount = tree_to_shwi(out); |
6417 |
++ bb = verify_context_before(&gsi, context, in, context_error_decl); |
6418 |
++ update_context(&gsi, context, outcount - incount); |
6419 |
++ } |
6420 |
+ |
6421 |
-+config PAX_SEGMEXEC |
6422 |
-+ bool "Segmentation based non-executable pages" |
6423 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6424 |
-+ depends on PAX_NOEXEC && X86_32 |
6425 |
-+ help |
6426 |
-+ This implementation is based on the segmentation feature of the |
6427 |
-+ CPU and has a very small performance impact, however applications |
6428 |
-+ will be limited to a 1.5 GB address space instead of the normal |
6429 |
-+ 3 GB. |
6430 |
++ return bb; |
6431 |
++} |
6432 |
+ |
6433 |
-+config PAX_EMUTRAMP |
6434 |
-+ bool "Emulate trampolines" |
6435 |
-+ default y if PARISC || GRKERNSEC_CONFIG_AUTO |
6436 |
-+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || X86) |
6437 |
-+ help |
6438 |
-+ There are some programs and libraries that for one reason or |
6439 |
-+ another attempt to execute special small code snippets from |
6440 |
-+ non-executable memory pages. Most notable examples are the |
6441 |
-+ signal handler return code generated by the kernel itself and |
6442 |
-+ the GCC trampolines. |
6443 |
++static bool bb_any_loop(basic_block bb) |
6444 |
++{ |
6445 |
++ return bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP); |
6446 |
++} |
6447 |
+ |
6448 |
-+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then |
6449 |
-+ such programs will no longer work under your kernel. |
6450 |
++static unsigned int context_execute(void) |
6451 |
++{ |
6452 |
++ basic_block bb; |
6453 |
++ gimple assign; |
6454 |
++ gimple_stmt_iterator gsi; |
6455 |
++ tree context_attr, context; |
6456 |
++ tree lock, in, out; |
6457 |
+ |
6458 |
-+ As a remedy you can say Y here and use the 'chpax' or 'paxctl' |
6459 |
-+ utilities to enable trampoline emulation for the affected programs |
6460 |
-+ yet still have the protection provided by the non-executable pages. |
6461 |
++ loop_optimizer_init(LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); |
6462 |
++ gcc_assert(current_loops); |
6463 |
+ |
6464 |
-+ On parisc you MUST enable this option and EMUSIGRT as well, otherwise |
6465 |
-+ your system will not even boot. |
6466 |
++ calculate_dominance_info(CDI_DOMINATORS); |
6467 |
++ calculate_dominance_info(CDI_POST_DOMINATORS); |
6468 |
+ |
6469 |
-+ Alternatively you can say N here and use the 'chpax' or 'paxctl' |
6470 |
-+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC |
6471 |
-+ for the affected files. |
6472 |
++ context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl)); |
6473 |
++ if (context_attr) { |
6474 |
++ gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out)); |
6475 |
++ } else { |
6476 |
++ in = out = integer_zero_node; |
6477 |
++ } |
6478 |
+ |
6479 |
-+ NOTE: enabling this feature *may* open up a loophole in the |
6480 |
-+ protection provided by non-executable pages that an attacker |
6481 |
-+ could abuse. Therefore the best solution is to not have any |
6482 |
-+ files on your system that would require this option. This can |
6483 |
-+ be achieved by not using libc5 (which relies on the kernel |
6484 |
-+ signal handler return code) and not using or rewriting programs |
6485 |
-+ that make use of the nested function implementation of GCC. |
6486 |
-+ Skilled users can just fix GCC itself so that it implements |
6487 |
-+ nested function calls in a way that does not interfere with PaX. |
6488 |
++ // 1. create local context variable |
6489 |
++ context = create_tmp_var(integer_type_node, "context"); |
6490 |
++ add_referenced_var(context); |
6491 |
++ mark_sym_for_renaming(context); |
6492 |
+ |
6493 |
-+config PAX_EMUSIGRT |
6494 |
-+ bool "Automatically emulate sigreturn trampolines" |
6495 |
-+ depends on PAX_EMUTRAMP && PARISC |
6496 |
-+ default y |
6497 |
-+ help |
6498 |
-+ Enabling this option will have the kernel automatically detect |
6499 |
-+ and emulate signal return trampolines executing on the stack |
6500 |
-+ that would otherwise lead to task termination. |
6501 |
++ // 2. initialize local context variable |
6502 |
++ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
6503 |
++ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
6504 |
++ if (!single_pred_p(bb)) { |
6505 |
++ gcc_assert(bb_any_loop(bb)); |
6506 |
++ split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
6507 |
++ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
6508 |
++ } |
6509 |
++ gsi = gsi_start_bb(bb); |
6510 |
++ assign = gimple_build_assign(context, in); |
6511 |
++ gsi_insert_before(&gsi, assign, GSI_NEW_STMT); |
6512 |
++ update_stmt(assign); |
6513 |
+ |
6514 |
-+ This solution is intended as a temporary one for users with |
6515 |
-+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, |
6516 |
-+ Modula-3 runtime, etc) or executables linked to such, basically |
6517 |
-+ everything that does not specify its own SA_RESTORER function in |
6518 |
-+ normal executable memory like glibc 2.1+ does. |
6519 |
++ // 3. instrument each BB to track the local context variable |
6520 |
++ FOR_EACH_BB_FN(bb, cfun) { |
6521 |
++ bb = track_context(bb, context); |
6522 |
++ } |
6523 |
+ |
6524 |
-+ On parisc you MUST enable this option, otherwise your system will |
6525 |
-+ not even boot. |
6526 |
++ // 4. verify the local context variable against the expected state |
6527 |
++ if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds)) { |
6528 |
++ gcc_assert(single_pred_p(EXIT_BLOCK_PTR_FOR_FN(cfun))); |
6529 |
++ gsi = gsi_last_nondebug_bb(single_pred(EXIT_BLOCK_PTR_FOR_FN(cfun))); |
6530 |
++ verify_context_before(&gsi, context, out, context_error_decl); |
6531 |
++ } |
6532 |
+ |
6533 |
-+ NOTE: this feature cannot be disabled on a per executable basis |
6534 |
-+ and since it *does* open up a loophole in the protection provided |
6535 |
-+ by non-executable pages, the best solution is to not have any |
6536 |
-+ files on your system that would require this option. |
6537 |
++ free_dominance_info(CDI_DOMINATORS); |
6538 |
++ free_dominance_info(CDI_POST_DOMINATORS); |
6539 |
++ loop_optimizer_finalize(); |
6540 |
++ return 0; |
6541 |
++} |
6542 |
+ |
6543 |
-+config PAX_MPROTECT |
6544 |
-+ bool "Restrict mprotect()" |
6545 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6546 |
-+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) |
6547 |
-+ help |
6548 |
-+ Enabling this option will prevent programs from |
6549 |
-+ - changing the executable status of memory pages that were |
6550 |
-+ not originally created as executable, |
6551 |
-+ - making read-only executable pages writable again, |
6552 |
-+ - creating executable pages from anonymous memory, |
6553 |
-+ - making read-only-after-relocations (RELRO) data pages writable again. |
6554 |
++#define PASS_NAME context |
6555 |
++#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg |
6556 |
++//#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts |
6557 |
++#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_verify_flow | TODO_update_ssa |
6558 |
++#include "gcc-generate-gimple-pass.h" |
6559 |
+ |
6560 |
-+ You should say Y here to complete the protection provided by |
6561 |
-+ the enforcement of non-executable pages. |
6562 |
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
6563 |
++{ |
6564 |
++ const char * const plugin_name = plugin_info->base_name; |
6565 |
++ const int argc = plugin_info->argc; |
6566 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
6567 |
++ int i; |
6568 |
++ bool enable_user, enable_context; |
6569 |
++ struct register_pass_info context_pass_info; |
6570 |
+ |
6571 |
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
6572 |
-+ this feature on a per file basis. |
6573 |
++ static const struct ggc_root_tab gt_ggc_r_gt_checker[] = { |
6574 |
++ { |
6575 |
++ .base = &context_function_decl, |
6576 |
++ .nelt = 1, |
6577 |
++ .stride = sizeof(context_function_decl), |
6578 |
++ .cb = >_ggc_mx_tree_node, |
6579 |
++ .pchw = >_pch_nx_tree_node |
6580 |
++ }, |
6581 |
++ { |
6582 |
++ .base = &context_error_decl, |
6583 |
++ .nelt = 1, |
6584 |
++ .stride = sizeof(context_error_decl), |
6585 |
++ .cb = >_ggc_mx_tree_node, |
6586 |
++ .pchw = >_pch_nx_tree_node |
6587 |
++ }, |
6588 |
++ LAST_GGC_ROOT_TAB |
6589 |
++ }; |
6590 |
+ |
6591 |
-+config PAX_MPROTECT_COMPAT |
6592 |
-+ bool "Use legacy/compat protection demoting (read help)" |
6593 |
-+ depends on PAX_MPROTECT |
6594 |
-+ default n |
6595 |
-+ help |
6596 |
-+ The current implementation of PAX_MPROTECT denies RWX allocations/mprotects |
6597 |
-+ by sending the proper error code to the application. For some older |
6598 |
-+ userland, this can cause problems with applications that assume such |
6599 |
-+ allocations will not be prevented by PaX or SELinux and other access |
6600 |
-+ control systems and have no fallback mechanisms. For modern distros, |
6601 |
-+ this option should generally be set to 'N'. |
6602 |
-+ |
6603 |
-+config PAX_ELFRELOCS |
6604 |
-+ bool "Allow ELF text relocations (read help)" |
6605 |
-+ depends on PAX_MPROTECT |
6606 |
-+ default n |
6607 |
-+ help |
6608 |
-+ Non-executable pages and mprotect() restrictions are effective |
6609 |
-+ in preventing the introduction of new executable code into an |
6610 |
-+ attacked task's address space. There remain only two venues |
6611 |
-+ for this kind of attack: if the attacker can execute already |
6612 |
-+ existing code in the attacked task then he can either have it |
6613 |
-+ create and mmap() a file containing his code or have it mmap() |
6614 |
-+ an already existing ELF library that does not have position |
6615 |
-+ independent code in it and use mprotect() on it to make it |
6616 |
-+ writable and copy his code there. While protecting against |
6617 |
-+ the former approach is beyond PaX, the latter can be prevented |
6618 |
-+ by having only PIC ELF libraries on one's system (which do not |
6619 |
-+ need to relocate their code). If you are sure this is your case, |
6620 |
-+ as is the case with all modern Linux distributions, then leave |
6621 |
-+ this option disabled. You should say 'n' here. |
6622 |
++ context_pass_info.pass = make_context_pass(); |
6623 |
++// context_pass_info.reference_pass_name = "ssa"; |
6624 |
++ context_pass_info.reference_pass_name = "phiprop"; |
6625 |
++ context_pass_info.ref_pass_instance_number = 1; |
6626 |
++ context_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
6627 |
+ |
6628 |
-+config PAX_ETEXECRELOCS |
6629 |
-+ bool "Allow ELF ET_EXEC text relocations" |
6630 |
-+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC) |
6631 |
-+ select PAX_ELFRELOCS |
6632 |
-+ default y |
6633 |
-+ help |
6634 |
-+ On some architectures there are incorrectly created applications |
6635 |
-+ that require text relocations and would not work without enabling |
6636 |
-+ this option. If you are an alpha, ia64 or parisc user, you should |
6637 |
-+ enable this option and disable it once you have made sure that |
6638 |
-+ none of your applications need it. |
6639 |
++ if (!plugin_default_version_check(version, &gcc_version)) { |
6640 |
++ error(G_("incompatible gcc/plugin versions")); |
6641 |
++ return 1; |
6642 |
++ } |
6643 |
+ |
6644 |
-+config PAX_EMUPLT |
6645 |
-+ bool "Automatically emulate ELF PLT" |
6646 |
-+ depends on PAX_MPROTECT && (ALPHA || PARISC || SPARC) |
6647 |
-+ default y |
6648 |
-+ help |
6649 |
-+ Enabling this option will have the kernel automatically detect |
6650 |
-+ and emulate the Procedure Linkage Table entries in ELF files. |
6651 |
-+ On some architectures such entries are in writable memory, and |
6652 |
-+ become non-executable leading to task termination. Therefore |
6653 |
-+ it is mandatory that you enable this option on alpha, parisc, |
6654 |
-+ sparc and sparc64, otherwise your system would not even boot. |
6655 |
++ register_callback(plugin_name, PLUGIN_INFO, NULL, &checker_plugin_info); |
6656 |
+ |
6657 |
-+ NOTE: this feature *does* open up a loophole in the protection |
6658 |
-+ provided by the non-executable pages, therefore the proper |
6659 |
-+ solution is to modify the toolchain to produce a PLT that does |
6660 |
-+ not need to be writable. |
6661 |
++ enable_user = false; |
6662 |
++ enable_context = false; |
6663 |
++ for (i = 0; i < argc; ++i) { |
6664 |
++ if (!strcmp(argv[i].key, "user")) { |
6665 |
++ enable_user = true; |
6666 |
++ continue; |
6667 |
++ } |
6668 |
++ if (!strcmp(argv[i].key, "context")) { |
6669 |
++ enable_context = true; |
6670 |
++ continue; |
6671 |
++ } |
6672 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
6673 |
++ } |
6674 |
+ |
6675 |
-+config PAX_DLRESOLVE |
6676 |
-+ bool 'Emulate old glibc resolver stub' |
6677 |
-+ depends on PAX_EMUPLT && SPARC |
6678 |
-+ default n |
6679 |
-+ help |
6680 |
-+ This option is needed if userland has an old glibc (before 2.4) |
6681 |
-+ that puts a 'save' instruction into the runtime generated resolver |
6682 |
-+ stub that needs special emulation. |
6683 |
++ if (enable_user) |
6684 |
++ register_callback(plugin_name, PLUGIN_PRAGMAS, register_checker_address_spaces, NULL); |
6685 |
++ if (enable_context) { |
6686 |
++ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
6687 |
++ register_callback(plugin_name, PLUGIN_START_UNIT, context_start_unit, NULL); |
6688 |
++ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_checker); |
6689 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &context_pass_info); |
6690 |
++ } |
6691 |
+ |
6692 |
-+config PAX_KERNEXEC |
6693 |
-+ bool "Enforce non-executable kernel pages" |
6694 |
-+ default y if GRKERNSEC_CONFIG_AUTO && (!X86 || GRKERNSEC_CONFIG_VIRT_NONE || (GRKERNSEC_CONFIG_VIRT_EPT && GRKERNSEC_CONFIG_VIRT_GUEST) || (GRKERNSEC_CONFIG_VIRT_EPT && GRKERNSEC_CONFIG_VIRT_KVM)) |
6695 |
-+ depends on (X86 || (ARM && (CPU_V6 || CPU_V6K || CPU_V7) && !(ARM_LPAE && MODULES))) && !XEN |
6696 |
-+ select PAX_PER_CPU_PGD if X86_64 || (X86_32 && X86_PAE) |
6697 |
-+ select PAX_KERNEXEC_PLUGIN if X86_64 |
6698 |
-+ select ARM_KERNMEM_PERMS if ARM |
6699 |
-+ help |
6700 |
-+ This is the kernel land equivalent of PAGEEXEC and MPROTECT, |
6701 |
-+ that is, enabling this option will make it harder to inject |
6702 |
-+ and execute 'foreign' code in kernel memory itself. |
6703 |
++ return 0; |
6704 |
++} |
6705 |
+diff --git a/scripts/gcc-plugins/colorize_plugin.c b/scripts/gcc-plugins/colorize_plugin.c |
6706 |
+new file mode 100644 |
6707 |
+index 0000000..ffe60f6 |
6708 |
+--- /dev/null |
6709 |
++++ b/scripts/gcc-plugins/colorize_plugin.c |
6710 |
+@@ -0,0 +1,162 @@ |
6711 |
++/* |
6712 |
++ * Copyright 2012-2016 by PaX Team <pageexec@××××××××.hu> |
6713 |
++ * Licensed under the GPL v2 |
6714 |
++ * |
6715 |
++ * Note: the choice of the license means that the compilation process is |
6716 |
++ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
6717 |
++ * but for the kernel it doesn't matter since it doesn't link against |
6718 |
++ * any of the gcc libraries |
6719 |
++ * |
6720 |
++ * gcc plugin to colorize diagnostic output |
6721 |
++ * |
6722 |
++ */ |
6723 |
+ |
6724 |
-+ Note that on amd64, CONFIG_EFI enabled with "efi=old_map" on |
6725 |
-+ the kernel command-line will result in an RWX physical map. |
6726 |
++#include "gcc-common.h" |
6727 |
+ |
6728 |
-+ Likewise, the EFI runtime services are necessarily mapped as |
6729 |
-+ RWX. If CONFIG_EFI is enabled on an EFI-capable system, it |
6730 |
-+ is recommended that you boot with "noefi" on the kernel |
6731 |
-+ command-line if possible to eliminate the mapping. |
6732 |
++int plugin_is_GPL_compatible; |
6733 |
+ |
6734 |
-+choice |
6735 |
-+ prompt "Return Address Instrumentation Method" |
6736 |
-+ default PAX_KERNEXEC_PLUGIN_METHOD_BTS |
6737 |
-+ depends on PAX_KERNEXEC_PLUGIN |
6738 |
-+ help |
6739 |
-+ Select the method used to instrument function pointer dereferences. |
6740 |
-+ Note that binary modules cannot be instrumented by this approach. |
6741 |
++static struct plugin_info colorize_plugin_info = { |
6742 |
++ .version = "201602181345", |
6743 |
++ .help = "color=[never|always|auto]\tdetermine when to colorize\n", |
6744 |
++}; |
6745 |
+ |
6746 |
-+ Note that the implementation requires a gcc with plugin support, |
6747 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
6748 |
-+ headers explicitly in addition to the normal gcc package. |
6749 |
++#define GREEN "\033[32m\033[K" |
6750 |
++#define LIGHTGREEN "\033[1;32m\033[K" |
6751 |
++#define YELLOW "\033[33m\033[K" |
6752 |
++#define LIGHTYELLOW "\033[1;33m\033[K" |
6753 |
++#define RED "\033[31m\033[K" |
6754 |
++#define LIGHTRED "\033[1;31m\033[K" |
6755 |
++#define BLUE "\033[34m\033[K" |
6756 |
++#define LIGHTBLUE "\033[1;34m\033[K" |
6757 |
++#define BRIGHT "\033[1;m\033[K" |
6758 |
++#define NORMAL "\033[m\033[K" |
6759 |
+ |
6760 |
-+ config PAX_KERNEXEC_PLUGIN_METHOD_BTS |
6761 |
-+ bool "bts" |
6762 |
-+ help |
6763 |
-+ This method is compatible with binary only modules but has |
6764 |
-+ a higher runtime overhead. |
6765 |
++static diagnostic_starter_fn old_starter; |
6766 |
++static diagnostic_finalizer_fn old_finalizer; |
6767 |
+ |
6768 |
-+ config PAX_KERNEXEC_PLUGIN_METHOD_OR |
6769 |
-+ bool "or" |
6770 |
-+ depends on !PARAVIRT |
6771 |
-+ help |
6772 |
-+ This method is incompatible with binary only modules but has |
6773 |
-+ a lower runtime overhead. |
6774 |
-+endchoice |
6775 |
++static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic) |
6776 |
++{ |
6777 |
++ const char *color; |
6778 |
++ char *newprefix; |
6779 |
+ |
6780 |
-+config PAX_KERNEXEC_PLUGIN_METHOD |
6781 |
-+ string |
6782 |
-+ default "bts" if PAX_KERNEXEC_PLUGIN_METHOD_BTS |
6783 |
-+ default "or" if PAX_KERNEXEC_PLUGIN_METHOD_OR |
6784 |
-+ default "" |
6785 |
++ switch (diagnostic->kind) { |
6786 |
++ case DK_NOTE: |
6787 |
++ color = LIGHTBLUE; |
6788 |
++ break; |
6789 |
+ |
6790 |
-+config PAX_KERNEXEC_MODULE_TEXT |
6791 |
-+ int "Minimum amount of memory reserved for module code" |
6792 |
-+ default "8" if (!GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_SERVER) |
6793 |
-+ default "12" if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_DESKTOP) |
6794 |
-+ depends on PAX_KERNEXEC && X86_32 |
6795 |
-+ help |
6796 |
-+ Due to implementation details the kernel must reserve a fixed |
6797 |
-+ amount of memory for runtime allocated code (such as modules) |
6798 |
-+ at compile time that cannot be changed at runtime. Here you |
6799 |
-+ can specify the minimum amount in MB that will be reserved. |
6800 |
-+ Due to the same implementation details this size will always |
6801 |
-+ be rounded up to the next 2/4 MB boundary (depends on PAE) so |
6802 |
-+ the actually available memory for runtime allocated code will |
6803 |
-+ usually be more than this minimum. |
6804 |
++ case DK_PEDWARN: |
6805 |
++ case DK_WARNING: |
6806 |
++ color = LIGHTYELLOW; |
6807 |
++ break; |
6808 |
+ |
6809 |
-+ The default 4 MB should be enough for most users but if you have |
6810 |
-+ an excessive number of modules (e.g., most distribution configs |
6811 |
-+ compile many drivers as modules) or use huge modules such as |
6812 |
-+ nvidia's kernel driver, you will need to adjust this amount. |
6813 |
-+ A good rule of thumb is to look at your currently loaded kernel |
6814 |
-+ modules and add up their sizes. |
6815 |
++ case DK_ERROR: |
6816 |
++ case DK_FATAL: |
6817 |
++ case DK_ICE: |
6818 |
++ case DK_PERMERROR: |
6819 |
++ case DK_SORRY: |
6820 |
++ color = LIGHTRED; |
6821 |
++ break; |
6822 |
+ |
6823 |
-+endmenu |
6824 |
++ default: |
6825 |
++ color = NORMAL; |
6826 |
++ } |
6827 |
+ |
6828 |
-+menu "Address Space Layout Randomization" |
6829 |
-+ depends on PAX |
6830 |
++ old_starter(context, diagnostic); |
6831 |
++ if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix)) |
6832 |
++ return; |
6833 |
++ pp_destroy_prefix(context->printer); |
6834 |
++ pp_set_prefix(context->printer, newprefix); |
6835 |
++} |
6836 |
+ |
6837 |
-+config PAX_ASLR |
6838 |
-+ bool "Address Space Layout Randomization" |
6839 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6840 |
-+ help |
6841 |
-+ Many if not most exploit techniques rely on the knowledge of |
6842 |
-+ certain addresses in the attacked program. The following options |
6843 |
-+ will allow the kernel to apply a certain amount of randomization |
6844 |
-+ to specific parts of the program thereby forcing an attacker to |
6845 |
-+ guess them in most cases. Any failed guess will most likely crash |
6846 |
-+ the attacked program which allows the kernel to detect such attempts |
6847 |
-+ and react on them. PaX itself provides no reaction mechanisms, |
6848 |
-+ instead it is strongly encouraged that you make use of grsecurity's |
6849 |
-+ (http://www.grsecurity.net/) built-in crash detection features or |
6850 |
-+ develop one yourself. |
6851 |
++static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic) |
6852 |
++{ |
6853 |
++ old_finalizer(context, diagnostic); |
6854 |
++} |
6855 |
+ |
6856 |
-+ By saying Y here you can choose to randomize the following areas: |
6857 |
-+ - top of the task's kernel stack |
6858 |
-+ - top of the task's userland stack |
6859 |
-+ - base address for mmap() requests that do not specify one |
6860 |
-+ (this includes all libraries) |
6861 |
-+ - base address of the main executable |
6862 |
++static void colorize_arm(void) |
6863 |
++{ |
6864 |
++ old_starter = diagnostic_starter(global_dc); |
6865 |
++ old_finalizer = diagnostic_finalizer(global_dc); |
6866 |
+ |
6867 |
-+ It is strongly recommended to say Y here as address space layout |
6868 |
-+ randomization has negligible impact on performance yet it provides |
6869 |
-+ a very effective protection. |
6870 |
++ diagnostic_starter(global_dc) = start_colorize; |
6871 |
++ diagnostic_finalizer(global_dc) = finalize_colorize; |
6872 |
++} |
6873 |
+ |
6874 |
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
6875 |
-+ this feature on a per file basis. |
6876 |
++static unsigned int colorize_rearm_execute(void) |
6877 |
++{ |
6878 |
++ if (diagnostic_starter(global_dc) == start_colorize) |
6879 |
++ return 0; |
6880 |
+ |
6881 |
-+config PAX_RANDKSTACK |
6882 |
-+ bool "Randomize kernel stack base" |
6883 |
-+ default y if GRKERNSEC_CONFIG_AUTO && !(GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_VIRTUALBOX) |
6884 |
-+ depends on X86_TSC && X86 |
6885 |
-+ help |
6886 |
-+ By saying Y here the kernel will randomize every task's kernel |
6887 |
-+ stack on every system call. This will not only force an attacker |
6888 |
-+ to guess it but also prevent him from making use of possible |
6889 |
-+ leaked information about it. |
6890 |
++ colorize_arm(); |
6891 |
++ return 0; |
6892 |
++} |
6893 |
+ |
6894 |
-+ Since the kernel stack is a rather scarce resource, randomization |
6895 |
-+ may cause unexpected stack overflows, therefore you should very |
6896 |
-+ carefully test your system. Note that once enabled in the kernel |
6897 |
-+ configuration, this feature cannot be disabled on a per file basis. |
6898 |
++#define PASS_NAME colorize_rearm |
6899 |
++#define NO_GATE |
6900 |
++#include "gcc-generate-simple_ipa-pass.h" |
6901 |
+ |
6902 |
-+config PAX_RANDUSTACK |
6903 |
-+ bool |
6904 |
++static void colorize_start_unit(void *gcc_data, void *user_data) |
6905 |
++{ |
6906 |
++ colorize_arm(); |
6907 |
++} |
6908 |
+ |
6909 |
-+config PAX_RANDMMAP |
6910 |
-+ bool "Randomize user stack and mmap() bases" |
6911 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
6912 |
-+ depends on PAX_ASLR |
6913 |
-+ select PAX_RANDUSTACK |
6914 |
-+ help |
6915 |
-+ By saying Y here the kernel will randomize every task's userland |
6916 |
-+ stack and use a randomized base address for mmap() requests that |
6917 |
-+ do not specify one themselves. |
6918 |
++static bool should_colorize(void) |
6919 |
++{ |
6920 |
++#if BUILDING_GCC_VERSION >= 4009 |
6921 |
++ return false; |
6922 |
++#else |
6923 |
++ char const *t = getenv("TERM"); |
6924 |
+ |
6925 |
-+ The stack randomization is done in two steps where the second |
6926 |
-+ one may apply a big amount of shift to the top of the stack and |
6927 |
-+ cause problems for programs that want to use lots of memory (more |
6928 |
-+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). |
6929 |
++ return t && strcmp(t, "dumb") && isatty(STDERR_FILENO); |
6930 |
++#endif |
6931 |
++} |
6932 |
+ |
6933 |
-+ As a result of mmap randomization all dynamically loaded libraries |
6934 |
-+ will appear at random addresses and therefore be harder to exploit |
6935 |
-+ by a technique where an attacker attempts to execute library code |
6936 |
-+ for his purposes (e.g. spawn a shell from an exploited program that |
6937 |
-+ is running at an elevated privilege level). |
6938 |
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
6939 |
++{ |
6940 |
++ const char * const plugin_name = plugin_info->base_name; |
6941 |
++ const int argc = plugin_info->argc; |
6942 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
6943 |
++ int i; |
6944 |
++ struct register_pass_info colorize_rearm_pass_info; |
6945 |
++ bool colorize; |
6946 |
+ |
6947 |
-+ Furthermore, if a program is relinked as a dynamic ELF file, its |
6948 |
-+ base address will be randomized as well, completing the full |
6949 |
-+ randomization of the address space layout. Attacking such programs |
6950 |
-+ becomes a guess game. You can find an example of doing this at |
6951 |
-+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at |
6952 |
-+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz . |
6953 |
++ colorize_rearm_pass_info.pass = make_colorize_rearm_pass(); |
6954 |
++ colorize_rearm_pass_info.reference_pass_name = "*free_lang_data"; |
6955 |
++ colorize_rearm_pass_info.ref_pass_instance_number = 1; |
6956 |
++ colorize_rearm_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
6957 |
+ |
6958 |
-+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this |
6959 |
-+ feature on a per file basis. |
6960 |
++ if (!plugin_default_version_check(version, &gcc_version)) { |
6961 |
++ error(G_("incompatible gcc/plugin versions")); |
6962 |
++ return 1; |
6963 |
++ } |
6964 |
+ |
6965 |
-+endmenu |
6966 |
++ register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info); |
6967 |
+ |
6968 |
-+menu "Miscellaneous hardening features" |
6969 |
++ colorize = getenv("GCC_COLORS") ? should_colorize() : false; |
6970 |
+ |
6971 |
-+config PAX_MEMORY_SANITIZE |
6972 |
-+ bool "Sanitize all freed memory" |
6973 |
-+ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_PRIORITY_SECURITY) |
6974 |
-+ help |
6975 |
-+ By saying Y here the kernel will erase memory pages and slab objects |
6976 |
-+ as soon as they are freed. This in turn reduces the lifetime of data |
6977 |
-+ stored in them, making it less likely that sensitive information such |
6978 |
-+ as passwords, cryptographic secrets, etc stay in memory for too long. |
6979 |
++ for (i = 0; i < argc; ++i) { |
6980 |
++ if (!strcmp(argv[i].key, "color")) { |
6981 |
++ if (!argv[i].value) { |
6982 |
++ error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
6983 |
++ continue; |
6984 |
++ } |
6985 |
++ if (!strcmp(argv[i].value, "always")) |
6986 |
++ colorize = true; |
6987 |
++ else if (!strcmp(argv[i].value, "never")) |
6988 |
++ colorize = false; |
6989 |
++ else if (!strcmp(argv[i].value, "auto")) |
6990 |
++ colorize = should_colorize(); |
6991 |
++ else |
6992 |
++ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); |
6993 |
++ continue; |
6994 |
++ } |
6995 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
6996 |
++ } |
6997 |
+ |
6998 |
-+ This is especially useful for programs whose runtime is short, long |
6999 |
-+ lived processes and the kernel itself benefit from this as long as |
7000 |
-+ they ensure timely freeing of memory that may hold sensitive |
7001 |
-+ information. |
7002 |
++ if (colorize) { |
7003 |
++ // TODO: parse GCC_COLORS as used by gcc 4.9+ |
7004 |
++ register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL); |
7005 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info); |
7006 |
++ } |
7007 |
++ return 0; |
7008 |
++} |
7009 |
+diff --git a/scripts/gcc-plugins/constify_plugin.c b/scripts/gcc-plugins/constify_plugin.c |
7010 |
+new file mode 100644 |
7011 |
+index 0000000..7142f36 |
7012 |
+--- /dev/null |
7013 |
++++ b/scripts/gcc-plugins/constify_plugin.c |
7014 |
+@@ -0,0 +1,521 @@ |
7015 |
++/* |
7016 |
++ * Copyright 2011 by Emese Revfy <re.emese@×××××.com> |
7017 |
++ * Copyright 2011-2016 by PaX Team <pageexec@××××××××.hu> |
7018 |
++ * Licensed under the GPL v2, or (at your option) v3 |
7019 |
++ * |
7020 |
++ * This gcc plugin constifies all structures which contain only function pointers or are explicitly marked for constification. |
7021 |
++ * |
7022 |
++ * Homepage: |
7023 |
++ * http://www.grsecurity.net/~ephox/const_plugin/ |
7024 |
++ * |
7025 |
++ * Usage: |
7026 |
++ * $ gcc -I`gcc -print-file-name=plugin`/include -fPIC -shared -O2 -o constify_plugin.so constify_plugin.c |
7027 |
++ * $ gcc -fplugin=constify_plugin.so test.c -O2 |
7028 |
++ */ |
7029 |
+ |
7030 |
-+ A nice side effect of the sanitization of slab objects is the |
7031 |
-+ reduction of possible info leaks caused by padding bytes within the |
7032 |
-+ leaky structures. Use-after-free bugs for structures containing |
7033 |
-+ pointers can also be detected as dereferencing the sanitized pointer |
7034 |
-+ will generate an access violation. |
7035 |
++#include "gcc-common.h" |
7036 |
+ |
7037 |
-+ The tradeoff is performance impact, on a single CPU system kernel |
7038 |
-+ compilation sees a 3% slowdown, other systems and workloads may vary |
7039 |
-+ and you are advised to test this feature on your expected workload |
7040 |
-+ before deploying it. |
7041 |
++// unused C type flag in all versions 4.5-6 |
7042 |
++#define TYPE_CONSTIFY_VISITED(TYPE) TYPE_LANG_FLAG_4(TYPE) |
7043 |
+ |
7044 |
-+ The slab sanitization feature excludes a few slab caches per default |
7045 |
-+ for performance reasons. To extend the feature to cover those as |
7046 |
-+ well, pass "pax_sanitize_slab=full" as kernel command line parameter. |
7047 |
++int plugin_is_GPL_compatible; |
7048 |
+ |
7049 |
-+ To reduce the performance penalty by sanitizing pages only, albeit |
7050 |
-+ limiting the effectiveness of this feature at the same time, slab |
7051 |
-+ sanitization can be disabled with the kernel command line parameter |
7052 |
-+ "pax_sanitize_slab=off". |
7053 |
++static bool enabled = true; |
7054 |
+ |
7055 |
-+ Note that this feature does not protect data stored in live pages, |
7056 |
-+ e.g., process memory swapped to disk may stay there for a long time. |
7057 |
++static struct plugin_info const_plugin_info = { |
7058 |
++ .version = "201605212045", |
7059 |
++ .help = "disable\tturn off constification\n", |
7060 |
++}; |
7061 |
+ |
7062 |
-+config PAX_MEMORY_STACKLEAK |
7063 |
-+ bool "Sanitize kernel stack" |
7064 |
-+ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_PRIORITY_SECURITY) |
7065 |
-+ depends on X86 |
7066 |
-+ help |
7067 |
-+ By saying Y here the kernel will erase the kernel stack before it |
7068 |
-+ returns from a system call. This in turn reduces the information |
7069 |
-+ that a kernel stack leak bug can reveal. |
7070 |
++typedef struct { |
7071 |
++ bool has_fptr_field; |
7072 |
++ bool has_writable_field; |
7073 |
++ bool has_do_const_field; |
7074 |
++ bool has_no_const_field; |
7075 |
++} constify_info; |
7076 |
+ |
7077 |
-+ Note that such a bug can still leak information that was put on |
7078 |
-+ the stack by the current system call (the one eventually triggering |
7079 |
-+ the bug) but traces of earlier system calls on the kernel stack |
7080 |
-+ cannot leak anymore. |
7081 |
++static const_tree get_field_type(const_tree field) |
7082 |
++{ |
7083 |
++ return strip_array_types(TREE_TYPE(field)); |
7084 |
++} |
7085 |
+ |
7086 |
-+ The tradeoff is performance impact: on a single CPU system kernel |
7087 |
-+ compilation sees a 1% slowdown, other systems and workloads may vary |
7088 |
-+ and you are advised to test this feature on your expected workload |
7089 |
-+ before deploying it. |
7090 |
++static bool is_fptr(const_tree field) |
7091 |
++{ |
7092 |
++ const_tree ptr = get_field_type(field); |
7093 |
+ |
7094 |
-+ Note that the full feature requires a gcc with plugin support, |
7095 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
7096 |
-+ headers explicitly in addition to the normal gcc package. Using |
7097 |
-+ older gcc versions means that functions with large enough stack |
7098 |
-+ frames may leave uninitialized memory behind that may be exposed |
7099 |
-+ to a later syscall leaking the stack. |
7100 |
++ if (TREE_CODE(ptr) != POINTER_TYPE) |
7101 |
++ return false; |
7102 |
+ |
7103 |
-+config PAX_MEMORY_STRUCTLEAK |
7104 |
-+ bool "Forcibly initialize local variables copied to userland" |
7105 |
-+ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_PRIORITY_SECURITY) |
7106 |
-+ help |
7107 |
-+ By saying Y here the kernel will zero initialize some local |
7108 |
-+ variables that are going to be copied to userland. This in |
7109 |
-+ turn prevents unintended information leakage from the kernel |
7110 |
-+ stack should later code forget to explicitly set all parts of |
7111 |
-+ the copied variable. |
7112 |
++ return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE; |
7113 |
++} |
7114 |
+ |
7115 |
-+ The tradeoff is less performance impact than PAX_MEMORY_STACKLEAK |
7116 |
-+ at a much smaller coverage. |
7117 |
++/* |
7118 |
++ * determine whether the given structure type meets the requirements for automatic constification, |
7119 |
++ * including the constification attributes on nested structure types |
7120 |
++ */ |
7121 |
++static void constifiable(const_tree node, constify_info *cinfo) |
7122 |
++{ |
7123 |
++ const_tree field; |
7124 |
+ |
7125 |
-+ Note that the implementation requires a gcc with plugin support, |
7126 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
7127 |
-+ headers explicitly in addition to the normal gcc package. |
7128 |
++ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); |
7129 |
+ |
7130 |
-+config PAX_MEMORY_UDEREF |
7131 |
-+ bool "Prevent invalid userland pointer dereference" |
7132 |
-+ default y if GRKERNSEC_CONFIG_AUTO && !(X86_64 && GRKERNSEC_CONFIG_PRIORITY_PERF) && !(X86_64 && GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_VIRTUALBOX) && (!X86 || GRKERNSEC_CONFIG_VIRT_NONE || GRKERNSEC_CONFIG_VIRT_EPT) |
7133 |
-+ depends on (X86 || (ARM && (CPU_V6 || CPU_V6K || CPU_V7) && !ARM_LPAE)) && !UML_X86 && !XEN |
7134 |
-+ select PAX_PER_CPU_PGD if X86_64 |
7135 |
-+ help |
7136 |
-+ By saying Y here the kernel will be prevented from dereferencing |
7137 |
-+ userland pointers in contexts where the kernel expects only kernel |
7138 |
-+ pointers. This is both a useful runtime debugging feature and a |
7139 |
-+ security measure that prevents exploiting a class of kernel bugs. |
7140 |
++ // e.g., pointer to structure fields while still constructing the structure type |
7141 |
++ if (TYPE_FIELDS(node) == NULL_TREE) |
7142 |
++ return; |
7143 |
+ |
7144 |
-+ The tradeoff is that some virtualization solutions may experience |
7145 |
-+ a huge slowdown and therefore you should not enable this feature |
7146 |
-+ for kernels meant to run in such environments. Whether a given VM |
7147 |
-+ solution is affected or not is best determined by simply trying it |
7148 |
-+ out, the performance impact will be obvious right on boot as this |
7149 |
-+ mechanism engages from very early on. A good rule of thumb is that |
7150 |
-+ VMs running on CPUs without hardware virtualization support (i.e., |
7151 |
-+ the majority of IA-32 CPUs) will likely experience the slowdown. |
7152 |
++ for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { |
7153 |
++ const_tree type = get_field_type(field); |
7154 |
++ enum tree_code code = TREE_CODE(type); |
7155 |
+ |
7156 |
-+ On X86_64 the kernel will make use of PCID support when available |
7157 |
-+ (Intel's Westmere, Sandy Bridge, etc) for better security (default) |
7158 |
-+ or performance impact. Pass pax_weakuderef on the kernel command |
7159 |
-+ line to choose the latter. |
7160 |
++ if (node == type) |
7161 |
++ continue; |
7162 |
+ |
7163 |
-+config PAX_REFCOUNT |
7164 |
-+ bool "Prevent various kernel object reference counter overflows" |
7165 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
7166 |
-+ depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || MIPS || PPC || SPARC64 || X86) |
7167 |
-+ help |
7168 |
-+ By saying Y here the kernel will detect and prevent overflowing |
7169 |
-+ various (but not all) kinds of object reference counters. Such |
7170 |
-+ overflows can normally occur due to bugs only and are often, if |
7171 |
-+ not always, exploitable. |
7172 |
++ if (is_fptr(field)) |
7173 |
++ cinfo->has_fptr_field = true; |
7174 |
++ else if (code == RECORD_TYPE || code == UNION_TYPE) { |
7175 |
++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) |
7176 |
++ cinfo->has_do_const_field = true; |
7177 |
++ else if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) |
7178 |
++ cinfo->has_no_const_field = true; |
7179 |
++ else |
7180 |
++ constifiable(type, cinfo); |
7181 |
++ } else if (!TREE_READONLY(field)) |
7182 |
++ cinfo->has_writable_field = true; |
7183 |
++ } |
7184 |
++} |
7185 |
+ |
7186 |
-+ The tradeoff is that data structures protected by an overflowed |
7187 |
-+ refcount will never be freed and therefore will leak memory. Note |
7188 |
-+ that this leak also happens even without this protection but in |
7189 |
-+ that case the overflow can eventually trigger the freeing of the |
7190 |
-+ data structure while it is still being used elsewhere, resulting |
7191 |
-+ in the exploitable situation that this feature prevents. |
7192 |
++static bool constified(const_tree node) |
7193 |
++{ |
7194 |
++ constify_info cinfo = { |
7195 |
++ .has_fptr_field = false, |
7196 |
++ .has_writable_field = false, |
7197 |
++ .has_do_const_field = false, |
7198 |
++ .has_no_const_field = false |
7199 |
++ }; |
7200 |
+ |
7201 |
-+ Since this has a negligible performance impact, you should enable |
7202 |
-+ this feature. |
7203 |
++ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); |
7204 |
+ |
7205 |
-+config PAX_CONSTIFY_PLUGIN |
7206 |
-+ bool "Automatically constify eligible structures" |
7207 |
-+ default y |
7208 |
-+ depends on !UML && PAX_KERNEXEC |
7209 |
-+ help |
7210 |
-+ By saying Y here the compiler will automatically constify a class |
7211 |
-+ of types that contain only function pointers. This reduces the |
7212 |
-+ kernel's attack surface and also produces a better memory layout. |
7213 |
++ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) { |
7214 |
++// gcc_assert(!TYPE_READONLY(node)); |
7215 |
++ return false; |
7216 |
++ } |
7217 |
+ |
7218 |
-+ Note that the implementation requires a gcc with plugin support, |
7219 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
7220 |
-+ headers explicitly in addition to the normal gcc package. |
7221 |
-+ |
7222 |
-+ Note that if some code really has to modify constified variables |
7223 |
-+ then the source code will have to be patched to allow it. Examples |
7224 |
-+ can be found in PaX itself (the no_const attribute) and for some |
7225 |
-+ out-of-tree modules at http://www.grsecurity.net/~paxguy1/ . |
7226 |
++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) { |
7227 |
++ gcc_assert(TYPE_READONLY(node)); |
7228 |
++ return true; |
7229 |
++ } |
7230 |
+ |
7231 |
-+config PAX_USERCOPY |
7232 |
-+ bool "Harden heap object copies between kernel and userland" |
7233 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
7234 |
-+ depends on ARM || IA64 || PPC || SPARC || X86 |
7235 |
-+ depends on GRKERNSEC && (SLAB || SLUB || SLOB) |
7236 |
-+ select PAX_USERCOPY_SLABS |
7237 |
-+ help |
7238 |
-+ By saying Y here the kernel will enforce the size of heap objects |
7239 |
-+ when they are copied in either direction between the kernel and |
7240 |
-+ userland, even if only a part of the heap object is copied. |
7241 |
++ constifiable(node, &cinfo); |
7242 |
++ if ((!cinfo.has_fptr_field || cinfo.has_writable_field || cinfo.has_no_const_field) && !cinfo.has_do_const_field) |
7243 |
++ return false; |
7244 |
+ |
7245 |
-+ Specifically, this checking prevents information leaking from the |
7246 |
-+ kernel heap during kernel to userland copies (if the kernel heap |
7247 |
-+ object is otherwise fully initialized) and prevents kernel heap |
7248 |
-+ overflows during userland to kernel copies. |
7249 |
++ return TYPE_READONLY(node); |
7250 |
++} |
7251 |
+ |
7252 |
-+ Note that the current implementation provides the strictest bounds |
7253 |
-+ checks for the SLUB allocator. |
7254 |
++static void deconstify_tree(tree node); |
7255 |
+ |
7256 |
-+ Enabling this option also enables per-slab cache protection against |
7257 |
-+ data in a given cache being copied into/out of via userland |
7258 |
-+ accessors. Though the whitelist of regions will be reduced over |
7259 |
-+ time, it notably protects important data structures like task structs. |
7260 |
++static void deconstify_type(tree type) |
7261 |
++{ |
7262 |
++ tree field; |
7263 |
+ |
7264 |
-+ If frame pointers are enabled on x86, this option will also restrict |
7265 |
-+ copies into and out of the kernel stack to local variables within a |
7266 |
-+ single frame. |
7267 |
++ gcc_assert(TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE); |
7268 |
+ |
7269 |
-+ Since this has a negligible performance impact, you should enable |
7270 |
-+ this feature. |
7271 |
++ for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { |
7272 |
++ const_tree fieldtype = get_field_type(field); |
7273 |
+ |
7274 |
-+config PAX_USERCOPY_DEBUG |
7275 |
-+ bool |
7276 |
-+ depends on X86 && PAX_USERCOPY |
7277 |
-+ default n |
7278 |
++ // special case handling of simple ptr-to-same-array-type members |
7279 |
++ if (TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE) { |
7280 |
++ tree ptrtype = TREE_TYPE(TREE_TYPE(field)); |
7281 |
+ |
7282 |
-+config PAX_SIZE_OVERFLOW |
7283 |
-+ bool "Prevent various integer overflows in function size parameters" |
7284 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
7285 |
-+ help |
7286 |
-+ By saying Y here the kernel recomputes expressions of function |
7287 |
-+ arguments marked by a size_overflow attribute with double integer |
7288 |
-+ precision (DImode/TImode for 32/64 bit integer types). |
7289 |
++ if (TREE_TYPE(TREE_TYPE(field)) == type) |
7290 |
++ continue; |
7291 |
++ if (TREE_CODE(ptrtype) != RECORD_TYPE && TREE_CODE(ptrtype) != UNION_TYPE) |
7292 |
++ continue; |
7293 |
++ if (!constified(ptrtype)) |
7294 |
++ continue; |
7295 |
++ if (TYPE_MAIN_VARIANT(ptrtype) == TYPE_MAIN_VARIANT(type)) { |
7296 |
++ TREE_TYPE(field) = copy_node(TREE_TYPE(field)); |
7297 |
++ TREE_TYPE(TREE_TYPE(field)) = build_qualified_type(type, TYPE_QUALS(ptrtype) & ~TYPE_QUAL_CONST); |
7298 |
++ } |
7299 |
++ continue; |
7300 |
++ } |
7301 |
++ if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE) |
7302 |
++ continue; |
7303 |
++ if (!constified(fieldtype)) |
7304 |
++ continue; |
7305 |
+ |
7306 |
-+ The recomputed argument is checked against TYPE_MAX and an event |
7307 |
-+ is logged on overflow and the triggering process is killed. |
7308 |
++ deconstify_tree(field); |
7309 |
++ TREE_READONLY(field) = 0; |
7310 |
++ } |
7311 |
++ TYPE_READONLY(type) = 0; |
7312 |
++ C_TYPE_FIELDS_READONLY(type) = 0; |
7313 |
++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
7314 |
++ TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); |
7315 |
++ TYPE_ATTRIBUTES(type) = remove_attribute("do_const", TYPE_ATTRIBUTES(type)); |
7316 |
++ } |
7317 |
++} |
7318 |
+ |
7319 |
-+ Homepage: https://github.com/ephox-gcc-plugins |
7320 |
++static void deconstify_tree(tree node) |
7321 |
++{ |
7322 |
++ tree old_type, new_type, field; |
7323 |
+ |
7324 |
-+ Note that the implementation requires a gcc with plugin support, |
7325 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
7326 |
-+ headers explicitly in addition to the normal gcc package. |
7327 |
++ old_type = TREE_TYPE(node); |
7328 |
++ while (TREE_CODE(old_type) == ARRAY_TYPE && TREE_CODE(TREE_TYPE(old_type)) != ARRAY_TYPE) { |
7329 |
++ node = TREE_TYPE(node) = copy_node(old_type); |
7330 |
++ old_type = TREE_TYPE(old_type); |
7331 |
++ } |
7332 |
+ |
7333 |
-+config PAX_LATENT_ENTROPY |
7334 |
-+ bool "Generate some entropy during boot and runtime" |
7335 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
7336 |
-+ help |
7337 |
-+ By saying Y here the kernel will instrument some kernel code to |
7338 |
-+ extract some entropy from both original and artificially created |
7339 |
-+ program state. This will help especially embedded systems where |
7340 |
-+ there is little 'natural' source of entropy normally. The cost |
7341 |
-+ is some slowdown of the boot process and fork and irq processing. |
7342 |
++ gcc_assert(TREE_CODE(old_type) == RECORD_TYPE || TREE_CODE(old_type) == UNION_TYPE); |
7343 |
++ gcc_assert(TYPE_READONLY(old_type) && (TYPE_QUALS(old_type) & TYPE_QUAL_CONST)); |
7344 |
+ |
7345 |
-+ When pax_extra_latent_entropy is passed on the kernel command line, |
7346 |
-+ entropy will be extracted from up to the first 4GB of RAM while the |
7347 |
-+ runtime memory allocator is being initialized. This costs even more |
7348 |
-+ slowdown of the boot process. |
7349 |
++ new_type = build_qualified_type(old_type, TYPE_QUALS(old_type) & ~TYPE_QUAL_CONST); |
7350 |
++ TYPE_FIELDS(new_type) = copy_list(TYPE_FIELDS(new_type)); |
7351 |
++ for (field = TYPE_FIELDS(new_type); field; field = TREE_CHAIN(field)) |
7352 |
++ DECL_FIELD_CONTEXT(field) = new_type; |
7353 |
+ |
7354 |
-+ Note that the implementation requires a gcc with plugin support, |
7355 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
7356 |
-+ headers explicitly in addition to the normal gcc package. |
7357 |
++ deconstify_type(new_type); |
7358 |
+ |
7359 |
-+ Note that entropy extracted this way is not cryptographically |
7360 |
-+ secure! |
7361 |
++ TREE_TYPE(node) = new_type; |
7362 |
++} |
7363 |
+ |
7364 |
-+config PAX_RAP |
7365 |
-+ bool "Prevent code reuse attacks" |
7366 |
-+ depends on X86_64 |
7367 |
-+ default y if GRKERNSEC_CONFIG_AUTO |
7368 |
-+ help |
7369 |
-+ By saying Y here the kernel will check indirect control transfers |
7370 |
-+ in order to detect and prevent attacks that try to hijack control |
7371 |
-+ flow by overwriting code pointers. |
7372 |
++static tree handle_no_const_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
7373 |
++{ |
7374 |
++ tree type; |
7375 |
++ constify_info cinfo = { |
7376 |
++ .has_fptr_field = false, |
7377 |
++ .has_writable_field = false, |
7378 |
++ .has_do_const_field = false, |
7379 |
++ .has_no_const_field = false |
7380 |
++ }; |
7381 |
+ |
7382 |
-+ Note that binary modules cannot be instrumented by this approach. |
7383 |
++ *no_add_attrs = true; |
7384 |
++ if (TREE_CODE(*node) == FUNCTION_DECL) { |
7385 |
++ error("%qE attribute does not apply to functions (%qF)", name, *node); |
7386 |
++ return NULL_TREE; |
7387 |
++ } |
7388 |
+ |
7389 |
-+ Note that the implementation requires a gcc with plugin support, |
7390 |
-+ i.e., gcc 4.5 or newer. You may need to install the supporting |
7391 |
-+ headers explicitly in addition to the normal gcc package. |
7392 |
++ if (TREE_CODE(*node) == PARM_DECL) { |
7393 |
++ error("%qE attribute does not apply to function parameters (%qD)", name, *node); |
7394 |
++ return NULL_TREE; |
7395 |
++ } |
7396 |
+ |
7397 |
-+endmenu |
7398 |
++ if (TREE_CODE(*node) == VAR_DECL) { |
7399 |
++ error("%qE attribute does not apply to variables (%qD)", name, *node); |
7400 |
++ return NULL_TREE; |
7401 |
++ } |
7402 |
+ |
7403 |
-+endmenu |
7404 |
++ if (TYPE_P(*node)) { |
7405 |
++ type = *node; |
7406 |
++ } else { |
7407 |
++ if (TREE_CODE(*node) != TYPE_DECL) { |
7408 |
++ error("%qE attribute does not apply to %qD (%qT)", name, *node, TREE_TYPE(*node)); |
7409 |
++ return NULL_TREE; |
7410 |
++ } |
7411 |
++ type = TREE_TYPE(*node); |
7412 |
++ } |
7413 |
+ |
7414 |
-+source grsecurity/Kconfig |
7415 |
++ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) { |
7416 |
++ error("%qE attribute used on %qT applies to struct and union types only", name, type); |
7417 |
++ return NULL_TREE; |
7418 |
++ } |
7419 |
+ |
7420 |
-+endmenu |
7421 |
++ if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) { |
7422 |
++ error("%qE attribute is already applied to the type %qT", name, type); |
7423 |
++ return NULL_TREE; |
7424 |
++ } |
7425 |
+ |
7426 |
-+endmenu |
7427 |
++ if (TYPE_P(*node)) { |
7428 |
++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) |
7429 |
++ error("%qE attribute used on type %qT is incompatible with 'do_const'", name, type); |
7430 |
++ else |
7431 |
++ *no_add_attrs = false; |
7432 |
++ return NULL_TREE; |
7433 |
++ } |
7434 |
+ |
7435 |
- source security/keys/Kconfig |
7436 |
- |
7437 |
- config SECURITY_DMESG_RESTRICT |
7438 |
-@@ -104,7 +1087,7 @@ config INTEL_TXT |
7439 |
- config LSM_MMAP_MIN_ADDR |
7440 |
- int "Low address space for LSM to protect from user allocation" |
7441 |
- depends on SECURITY && SECURITY_SELINUX |
7442 |
-- default 32768 if ARM || (ARM64 && COMPAT) |
7443 |
-+ default 32768 if ALPHA || ARM || (ARM64 && COMPAT) || PARISC || SPARC32 |
7444 |
- default 65536 |
7445 |
- help |
7446 |
- This is the portion of low virtual memory which should be protected |
7447 |
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c |
7448 |
-index 913f377..6e392d5 100644 |
7449 |
---- a/security/apparmor/file.c |
7450 |
-+++ b/security/apparmor/file.c |
7451 |
-@@ -348,8 +348,8 @@ static inline bool xindex_is_subset(u32 link, u32 target) |
7452 |
- int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry, |
7453 |
- struct path *new_dir, struct dentry *new_dentry) |
7454 |
- { |
7455 |
-- struct path link = { new_dir->mnt, new_dentry }; |
7456 |
-- struct path target = { new_dir->mnt, old_dentry }; |
7457 |
-+ struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry }; |
7458 |
-+ struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry }; |
7459 |
- struct path_cond cond = { |
7460 |
- d_backing_inode(old_dentry)->i_uid, |
7461 |
- d_backing_inode(old_dentry)->i_mode |
7462 |
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h |
7463 |
-index c28b0f2..3b9fee0 100644 |
7464 |
---- a/security/apparmor/include/policy.h |
7465 |
-+++ b/security/apparmor/include/policy.h |
7466 |
-@@ -134,7 +134,7 @@ struct aa_namespace { |
7467 |
- struct aa_ns_acct acct; |
7468 |
- struct aa_profile *unconfined; |
7469 |
- struct list_head sub_ns; |
7470 |
-- atomic_t uniq_null; |
7471 |
-+ atomic_unchecked_t uniq_null; |
7472 |
- long uniq_id; |
7473 |
- |
7474 |
- struct dentry *dents[AAFS_NS_SIZEOF]; |
7475 |
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c |
7476 |
-index dec607c..37fe357 100644 |
7477 |
---- a/security/apparmor/lsm.c |
7478 |
-+++ b/security/apparmor/lsm.c |
7479 |
-@@ -176,7 +176,7 @@ static int common_perm_dir_dentry(int op, struct path *dir, |
7480 |
- struct dentry *dentry, u32 mask, |
7481 |
- struct path_cond *cond) |
7482 |
- { |
7483 |
-- struct path path = { dir->mnt, dentry }; |
7484 |
-+ struct path path = { .mnt = dir->mnt, .dentry = dentry }; |
7485 |
- |
7486 |
- return common_perm(op, &path, mask, cond); |
7487 |
- } |
7488 |
-@@ -193,7 +193,7 @@ static int common_perm_dir_dentry(int op, struct path *dir, |
7489 |
- static int common_perm_mnt_dentry(int op, struct vfsmount *mnt, |
7490 |
- struct dentry *dentry, u32 mask) |
7491 |
- { |
7492 |
-- struct path path = { mnt, dentry }; |
7493 |
-+ struct path path = { .mnt = mnt, .dentry = dentry }; |
7494 |
- struct path_cond cond = { d_backing_inode(dentry)->i_uid, |
7495 |
- d_backing_inode(dentry)->i_mode |
7496 |
- }; |
7497 |
-@@ -315,8 +315,8 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry, |
7498 |
- |
7499 |
- profile = aa_current_profile(); |
7500 |
- if (!unconfined(profile)) { |
7501 |
-- struct path old_path = { old_dir->mnt, old_dentry }; |
7502 |
-- struct path new_path = { new_dir->mnt, new_dentry }; |
7503 |
-+ struct path old_path = { .mnt = old_dir->mnt, .dentry = old_dentry }; |
7504 |
-+ struct path new_path = { .mnt = new_dir->mnt, .dentry = new_dentry }; |
7505 |
- struct path_cond cond = { d_backing_inode(old_dentry)->i_uid, |
7506 |
- d_backing_inode(old_dentry)->i_mode |
7507 |
- }; |
7508 |
-@@ -677,11 +677,11 @@ static const struct kernel_param_ops param_ops_aalockpolicy = { |
7509 |
- .get = param_get_aalockpolicy |
7510 |
- }; |
7511 |
- |
7512 |
--static int param_set_audit(const char *val, struct kernel_param *kp); |
7513 |
--static int param_get_audit(char *buffer, struct kernel_param *kp); |
7514 |
-+static int param_set_audit(const char *val, const struct kernel_param *kp); |
7515 |
-+static int param_get_audit(char *buffer, const struct kernel_param *kp); |
7516 |
- |
7517 |
--static int param_set_mode(const char *val, struct kernel_param *kp); |
7518 |
--static int param_get_mode(char *buffer, struct kernel_param *kp); |
7519 |
-+static int param_set_mode(const char *val, const struct kernel_param *kp); |
7520 |
-+static int param_get_mode(char *buffer, const struct kernel_param *kp); |
7521 |
- |
7522 |
- /* Flag values, also controllable via /sys/module/apparmor/parameters |
7523 |
- * We define special types as we want to do additional mediation. |
7524 |
-@@ -791,7 +791,7 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp) |
7525 |
- return param_get_uint(buffer, kp); |
7526 |
- } |
7527 |
- |
7528 |
--static int param_get_audit(char *buffer, struct kernel_param *kp) |
7529 |
-+static int param_get_audit(char *buffer, const struct kernel_param *kp) |
7530 |
- { |
7531 |
- if (!capable(CAP_MAC_ADMIN)) |
7532 |
- return -EPERM; |
7533 |
-@@ -802,7 +802,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp) |
7534 |
- return sprintf(buffer, "%s", audit_mode_names[aa_g_audit]); |
7535 |
- } |
7536 |
- |
7537 |
--static int param_set_audit(const char *val, struct kernel_param *kp) |
7538 |
-+static int param_set_audit(const char *val, const struct kernel_param *kp) |
7539 |
- { |
7540 |
- int i; |
7541 |
- if (!capable(CAP_MAC_ADMIN)) |
7542 |
-@@ -824,7 +824,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp) |
7543 |
- return -EINVAL; |
7544 |
- } |
7545 |
- |
7546 |
--static int param_get_mode(char *buffer, struct kernel_param *kp) |
7547 |
-+static int param_get_mode(char *buffer, const struct kernel_param *kp) |
7548 |
- { |
7549 |
- if (!capable(CAP_MAC_ADMIN)) |
7550 |
- return -EPERM; |
7551 |
-@@ -835,7 +835,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp) |
7552 |
- return sprintf(buffer, "%s", aa_profile_mode_names[aa_g_profile_mode]); |
7553 |
- } |
7554 |
- |
7555 |
--static int param_set_mode(const char *val, struct kernel_param *kp) |
7556 |
-+static int param_set_mode(const char *val, const struct kernel_param *kp) |
7557 |
- { |
7558 |
- int i; |
7559 |
- if (!capable(CAP_MAC_ADMIN)) |
7560 |
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c |
7561 |
-index 705c287..81257f1 100644 |
7562 |
---- a/security/apparmor/policy.c |
7563 |
-+++ b/security/apparmor/policy.c |
7564 |
-@@ -298,7 +298,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix, |
7565 |
- /* ns and ns->unconfined share ns->unconfined refcount */ |
7566 |
- ns->unconfined->ns = ns; |
7567 |
- |
7568 |
-- atomic_set(&ns->uniq_null, 0); |
7569 |
-+ atomic_set_unchecked(&ns->uniq_null, 0); |
7570 |
- |
7571 |
- return ns; |
7572 |
- |
7573 |
-@@ -689,7 +689,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat) |
7574 |
- { |
7575 |
- struct aa_profile *profile = NULL; |
7576 |
- char *name; |
7577 |
-- int uniq = atomic_inc_return(&parent->ns->uniq_null); |
7578 |
-+ int uniq = atomic_inc_return_unchecked(&parent->ns->uniq_null); |
7579 |
- |
7580 |
- /* freed below */ |
7581 |
- name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL); |
7582 |
-diff --git a/security/commoncap.c b/security/commoncap.c |
7583 |
-index 48071ed..b805e0f 100644 |
7584 |
---- a/security/commoncap.c |
7585 |
-+++ b/security/commoncap.c |
7586 |
-@@ -438,6 +438,32 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data |
7587 |
- return 0; |
7588 |
- } |
7589 |
- |
7590 |
-+/* returns: |
7591 |
-+ 1 for suid privilege |
7592 |
-+ 2 for sgid privilege |
7593 |
-+ 3 for fscap privilege |
7594 |
-+*/ |
7595 |
-+int is_privileged_binary(const struct dentry *dentry) |
7596 |
++ constifiable(type, &cinfo); |
7597 |
++ if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
7598 |
++ if (enabled) { |
7599 |
++ if TYPE_P(*node) |
7600 |
++ deconstify_type(*node); |
7601 |
++ else |
7602 |
++ deconstify_tree(*node); |
7603 |
++ } |
7604 |
++ if (TYPE_P(*node)) |
7605 |
++ TYPE_CONSTIFY_VISITED(*node) = 1; |
7606 |
++ else |
7607 |
++ TYPE_CONSTIFY_VISITED(TREE_TYPE(*node)) = 1; |
7608 |
++ return NULL_TREE; |
7609 |
++ } |
7610 |
++ |
7611 |
++ if (enabled && TYPE_FIELDS(type)) |
7612 |
++ error("%qE attribute used on type %qT that is not constified", name, type); |
7613 |
++ return NULL_TREE; |
7614 |
++} |
7615 |
++ |
7616 |
++static void constify_type(tree type) |
7617 |
+{ |
7618 |
-+ struct cpu_vfs_cap_data capdata; |
7619 |
-+ struct inode *inode = dentry->d_inode; |
7620 |
++ TYPE_READONLY(type) = 1; |
7621 |
++ C_TYPE_FIELDS_READONLY(type) = 1; |
7622 |
++ TYPE_CONSTIFY_VISITED(type) = 1; |
7623 |
++// TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); |
7624 |
++// TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("do_const"), NULL_TREE, TYPE_ATTRIBUTES(type)); |
7625 |
++} |
7626 |
+ |
7627 |
-+ if (!inode || S_ISDIR(inode->i_mode)) |
7628 |
-+ return 0; |
7629 |
++static tree handle_do_const_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
7630 |
++{ |
7631 |
++ *no_add_attrs = true; |
7632 |
++ if (!TYPE_P(*node)) { |
7633 |
++ error("%qE attribute applies to types only (%qD)", name, *node); |
7634 |
++ return NULL_TREE; |
7635 |
++ } |
7636 |
+ |
7637 |
-+ if (inode->i_mode & S_ISUID) |
7638 |
++ if (TREE_CODE(*node) != RECORD_TYPE && TREE_CODE(*node) != UNION_TYPE) { |
7639 |
++ error("%qE attribute used on %qT applies to struct and union types only", name, *node); |
7640 |
++ return NULL_TREE; |
7641 |
++ } |
7642 |
++ |
7643 |
++ if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(*node))) { |
7644 |
++ error("%qE attribute used on %qT is already applied to the type", name, *node); |
7645 |
++ return NULL_TREE; |
7646 |
++ } |
7647 |
++ |
7648 |
++ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(*node))) { |
7649 |
++ error("%qE attribute used on %qT is incompatible with 'no_const'", name, *node); |
7650 |
++ return NULL_TREE; |
7651 |
++ } |
7652 |
++ |
7653 |
++ *no_add_attrs = false; |
7654 |
++ return NULL_TREE; |
7655 |
++} |
7656 |
++ |
7657 |
++static struct attribute_spec no_const_attr = { |
7658 |
++ .name = "no_const", |
7659 |
++ .min_length = 0, |
7660 |
++ .max_length = 0, |
7661 |
++ .decl_required = false, |
7662 |
++ .type_required = false, |
7663 |
++ .function_type_required = false, |
7664 |
++ .handler = handle_no_const_attribute, |
7665 |
++#if BUILDING_GCC_VERSION >= 4007 |
7666 |
++ .affects_type_identity = true |
7667 |
++#endif |
7668 |
++}; |
7669 |
++ |
7670 |
++static struct attribute_spec do_const_attr = { |
7671 |
++ .name = "do_const", |
7672 |
++ .min_length = 0, |
7673 |
++ .max_length = 0, |
7674 |
++ .decl_required = false, |
7675 |
++ .type_required = false, |
7676 |
++ .function_type_required = false, |
7677 |
++ .handler = handle_do_const_attribute, |
7678 |
++#if BUILDING_GCC_VERSION >= 4007 |
7679 |
++ .affects_type_identity = true |
7680 |
++#endif |
7681 |
++}; |
7682 |
++ |
7683 |
++static void register_attributes(void *event_data, void *data) |
7684 |
++{ |
7685 |
++ register_attribute(&no_const_attr); |
7686 |
++ register_attribute(&do_const_attr); |
7687 |
++} |
7688 |
++ |
7689 |
++static void finish_type(void *event_data, void *data) |
7690 |
++{ |
7691 |
++ tree type = (tree)event_data; |
7692 |
++ constify_info cinfo = { |
7693 |
++ .has_fptr_field = false, |
7694 |
++ .has_writable_field = false, |
7695 |
++ .has_do_const_field = false, |
7696 |
++ .has_no_const_field = false |
7697 |
++ }; |
7698 |
++ |
7699 |
++ if (type == NULL_TREE || type == error_mark_node) |
7700 |
++ return; |
7701 |
++ |
7702 |
++#if BUILDING_GCC_VERSION >= 5000 |
7703 |
++ if (TREE_CODE(type) == ENUMERAL_TYPE) |
7704 |
++ return; |
7705 |
++#endif |
7706 |
++ |
7707 |
++ if (TYPE_FIELDS(type) == NULL_TREE || TYPE_CONSTIFY_VISITED(type)) |
7708 |
++ return; |
7709 |
++ |
7710 |
++ constifiable(type, &cinfo); |
7711 |
++ |
7712 |
++ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) { |
7713 |
++ if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || cinfo.has_do_const_field) { |
7714 |
++ deconstify_type(type); |
7715 |
++ TYPE_CONSTIFY_VISITED(type) = 1; |
7716 |
++ } else |
7717 |
++ error("'no_const' attribute used on type %qT that is not constified", type); |
7718 |
++ return; |
7719 |
++ } |
7720 |
++ |
7721 |
++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
7722 |
++ if (!cinfo.has_writable_field && !cinfo.has_no_const_field) { |
7723 |
++ error("'do_const' attribute used on type %qT that is%sconstified", type, cinfo.has_fptr_field ? " " : " not "); |
7724 |
++ return; |
7725 |
++ } |
7726 |
++ constify_type(type); |
7727 |
++ return; |
7728 |
++ } |
7729 |
++ |
7730 |
++ if (cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) { |
7731 |
++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
7732 |
++ error("'do_const' attribute used on type %qT that is constified", type); |
7733 |
++ return; |
7734 |
++ } |
7735 |
++ constify_type(type); |
7736 |
++ return; |
7737 |
++ } |
7738 |
++ |
7739 |
++ deconstify_type(type); |
7740 |
++ TYPE_CONSTIFY_VISITED(type) = 1; |
7741 |
++} |
7742 |
++ |
7743 |
++static void check_global_variables(void *event_data, void *data) |
7744 |
++{ |
7745 |
++ varpool_node_ptr node; |
7746 |
++ |
7747 |
++ FOR_EACH_VARIABLE(node) { |
7748 |
++ tree var = NODE_DECL(node); |
7749 |
++ tree type = TREE_TYPE(var); |
7750 |
++ |
7751 |
++ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) |
7752 |
++ continue; |
7753 |
++ |
7754 |
++ if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) |
7755 |
++ continue; |
7756 |
++ |
7757 |
++ if (!TYPE_CONSTIFY_VISITED(type)) |
7758 |
++ continue; |
7759 |
++ |
7760 |
++ if (DECL_EXTERNAL(var)) |
7761 |
++ continue; |
7762 |
++ |
7763 |
++ if (DECL_INITIAL(var)) |
7764 |
++ continue; |
7765 |
++ |
7766 |
++ // this works around a gcc bug/feature where uninitialized globals |
7767 |
++ // are moved into the .bss section regardless of any constification |
7768 |
++ DECL_INITIAL(var) = build_constructor(type, NULL); |
7769 |
++// inform(DECL_SOURCE_LOCATION(var), "constified variable %qE moved into .rodata", var); |
7770 |
++ } |
7771 |
++} |
7772 |
++ |
7773 |
++static unsigned int check_local_variables_execute(void) |
7774 |
++{ |
7775 |
++ unsigned int ret = 0; |
7776 |
++ tree var; |
7777 |
++ |
7778 |
++ unsigned int i; |
7779 |
++ |
7780 |
++ FOR_EACH_LOCAL_DECL(cfun, i, var) { |
7781 |
++ tree type = TREE_TYPE(var); |
7782 |
++ |
7783 |
++ gcc_assert(DECL_P(var)); |
7784 |
++ if (is_global_var(var)) |
7785 |
++ continue; |
7786 |
++ |
7787 |
++ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) |
7788 |
++ continue; |
7789 |
++ |
7790 |
++ if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) |
7791 |
++ continue; |
7792 |
++ |
7793 |
++ if (!TYPE_CONSTIFY_VISITED(type)) |
7794 |
++ continue; |
7795 |
++ |
7796 |
++ error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var); |
7797 |
++ ret = 1; |
7798 |
++ } |
7799 |
++ return ret; |
7800 |
++} |
7801 |
++ |
7802 |
++#define PASS_NAME check_local_variables |
7803 |
++#define NO_GATE |
7804 |
++#include "gcc-generate-gimple-pass.h" |
7805 |
++ |
7806 |
++static struct { |
7807 |
++ const char *name; |
7808 |
++ const char *asm_op; |
7809 |
++} sections[] = { |
7810 |
++ {".init.rodata", "\t.section\t.init.rodata,\"a\""}, |
7811 |
++ {".ref.rodata", "\t.section\t.ref.rodata,\"a\""}, |
7812 |
++ {".devinit.rodata", "\t.section\t.devinit.rodata,\"a\""}, |
7813 |
++ {".devexit.rodata", "\t.section\t.devexit.rodata,\"a\""}, |
7814 |
++ {".cpuinit.rodata", "\t.section\t.cpuinit.rodata,\"a\""}, |
7815 |
++ {".cpuexit.rodata", "\t.section\t.cpuexit.rodata,\"a\""}, |
7816 |
++ {".meminit.rodata", "\t.section\t.meminit.rodata,\"a\""}, |
7817 |
++ {".memexit.rodata", "\t.section\t.memexit.rodata,\"a\""}, |
7818 |
++ {".data..read_only", "\t.section\t.data..read_only,\"a\""}, |
7819 |
++}; |
7820 |
++ |
7821 |
++static unsigned int (*old_section_type_flags)(tree decl, const char *name, int reloc); |
7822 |
++ |
7823 |
++static unsigned int constify_section_type_flags(tree decl, const char *name, int reloc) |
7824 |
++{ |
7825 |
++ size_t i; |
7826 |
++ |
7827 |
++ for (i = 0; i < ARRAY_SIZE(sections); i++) |
7828 |
++ if (!strcmp(sections[i].name, name)) |
7829 |
++ return 0; |
7830 |
++ return old_section_type_flags(decl, name, reloc); |
7831 |
++} |
7832 |
++ |
7833 |
++static void constify_start_unit(void *gcc_data, void *user_data) |
7834 |
++{ |
7835 |
++// size_t i; |
7836 |
++ |
7837 |
++// for (i = 0; i < ARRAY_SIZE(sections); i++) |
7838 |
++// sections[i].section = get_unnamed_section(0, output_section_asm_op, sections[i].asm_op); |
7839 |
++// sections[i].section = get_section(sections[i].name, 0, NULL); |
7840 |
++ |
7841 |
++ old_section_type_flags = targetm.section_type_flags; |
7842 |
++ targetm.section_type_flags = constify_section_type_flags; |
7843 |
++} |
7844 |
++ |
7845 |
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
7846 |
++{ |
7847 |
++ const char * const plugin_name = plugin_info->base_name; |
7848 |
++ const int argc = plugin_info->argc; |
7849 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
7850 |
++ int i; |
7851 |
++ |
7852 |
++ struct register_pass_info check_local_variables_pass_info; |
7853 |
++ |
7854 |
++ check_local_variables_pass_info.pass = make_check_local_variables_pass(); |
7855 |
++ check_local_variables_pass_info.reference_pass_name = "ssa"; |
7856 |
++ check_local_variables_pass_info.ref_pass_instance_number = 1; |
7857 |
++ check_local_variables_pass_info.pos_op = PASS_POS_INSERT_BEFORE; |
7858 |
++ |
7859 |
++ if (!plugin_default_version_check(version, &gcc_version)) { |
7860 |
++ error(G_("incompatible gcc/plugin versions")); |
7861 |
+ return 1; |
7862 |
-+ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) |
7863 |
-+ return 2; |
7864 |
++ } |
7865 |
+ |
7866 |
-+ if (!get_vfs_caps_from_disk(dentry, &capdata)) { |
7867 |
-+ if (!cap_isclear(capdata.inheritable) || !cap_isclear(capdata.permitted)) |
7868 |
-+ return 3; |
7869 |
++ for (i = 0; i < argc; ++i) { |
7870 |
++ if (!(strcmp(argv[i].key, "disable"))) { |
7871 |
++ enabled = false; |
7872 |
++ continue; |
7873 |
++ } |
7874 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
7875 |
++ } |
7876 |
++ |
7877 |
++ if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) { |
7878 |
++ inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name); |
7879 |
++ enabled = false; |
7880 |
++ } |
7881 |
++ |
7882 |
++ register_callback(plugin_name, PLUGIN_INFO, NULL, &const_plugin_info); |
7883 |
++ if (enabled) { |
7884 |
++ register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL); |
7885 |
++ register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); |
7886 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &check_local_variables_pass_info); |
7887 |
++ register_callback(plugin_name, PLUGIN_START_UNIT, constify_start_unit, NULL); |
7888 |
+ } |
7889 |
++ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
7890 |
+ |
7891 |
+ return 0; |
7892 |
+} |
7893 |
+diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h |
7894 |
+new file mode 100644 |
7895 |
+index 0000000..0c0b842 |
7896 |
+--- /dev/null |
7897 |
++++ b/scripts/gcc-plugins/gcc-common.h |
7898 |
+@@ -0,0 +1,879 @@ |
7899 |
++#ifndef GCC_COMMON_H_INCLUDED |
7900 |
++#define GCC_COMMON_H_INCLUDED |
7901 |
+ |
7902 |
- /* |
7903 |
- * Attempt to get the on-exec apply capability sets for an executable file from |
7904 |
- * its xattrs and, if present, apply them to the proposed credentials being |
7905 |
-@@ -628,6 +654,9 @@ int cap_bprm_secureexec(struct linux_binprm *bprm) |
7906 |
- const struct cred *cred = current_cred(); |
7907 |
- kuid_t root_uid = make_kuid(cred->user_ns, 0); |
7908 |
- |
7909 |
-+ if (gr_acl_enable_at_secure()) |
7910 |
-+ return 1; |
7911 |
++#include "bversion.h" |
7912 |
++#if BUILDING_GCC_VERSION >= 6000 |
7913 |
++#include "gcc-plugin.h" |
7914 |
++#else |
7915 |
++#include "plugin.h" |
7916 |
++#endif |
7917 |
++#include "plugin-version.h" |
7918 |
++#include "config.h" |
7919 |
++#include "system.h" |
7920 |
++#include "coretypes.h" |
7921 |
++#include "tm.h" |
7922 |
++#include "line-map.h" |
7923 |
++#include "input.h" |
7924 |
++#include "tree.h" |
7925 |
+ |
7926 |
- if (!uid_eq(cred->uid, root_uid)) { |
7927 |
- if (bprm->cap_effective) |
7928 |
- return 1; |
7929 |
-diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h |
7930 |
-index 585af61..b7d35ff 100644 |
7931 |
---- a/security/integrity/ima/ima.h |
7932 |
-+++ b/security/integrity/ima/ima.h |
7933 |
-@@ -125,8 +125,8 @@ int ima_init_template(void); |
7934 |
- extern spinlock_t ima_queue_lock; |
7935 |
- |
7936 |
- struct ima_h_table { |
7937 |
-- atomic_long_t len; /* number of stored measurements in the list */ |
7938 |
-- atomic_long_t violations; |
7939 |
-+ atomic_long_unchecked_t len; /* number of stored measurements in the list */ |
7940 |
-+ atomic_long_unchecked_t violations; |
7941 |
- struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; |
7942 |
- }; |
7943 |
- extern struct ima_h_table ima_htable; |
7944 |
-diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c |
7945 |
-index 1d950fb..a8f4eab 100644 |
7946 |
---- a/security/integrity/ima/ima_api.c |
7947 |
-+++ b/security/integrity/ima/ima_api.c |
7948 |
-@@ -137,7 +137,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, |
7949 |
- int result; |
7950 |
- |
7951 |
- /* can overflow, only indicator */ |
7952 |
-- atomic_long_inc(&ima_htable.violations); |
7953 |
-+ atomic_long_inc_unchecked(&ima_htable.violations); |
7954 |
- |
7955 |
- result = ima_alloc_init_template(&event_data, &entry); |
7956 |
- if (result < 0) { |
7957 |
-diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c |
7958 |
-index f355231..c71f640 100644 |
7959 |
---- a/security/integrity/ima/ima_fs.c |
7960 |
-+++ b/security/integrity/ima/ima_fs.c |
7961 |
-@@ -30,12 +30,12 @@ static DEFINE_MUTEX(ima_write_mutex); |
7962 |
- static int valid_policy = 1; |
7963 |
- #define TMPBUFLEN 12 |
7964 |
- static ssize_t ima_show_htable_value(char __user *buf, size_t count, |
7965 |
-- loff_t *ppos, atomic_long_t *val) |
7966 |
-+ loff_t *ppos, atomic_long_unchecked_t *val) |
7967 |
- { |
7968 |
- char tmpbuf[TMPBUFLEN]; |
7969 |
- ssize_t len; |
7970 |
- |
7971 |
-- len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val)); |
7972 |
-+ len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read_unchecked(val)); |
7973 |
- return simple_read_from_buffer(buf, count, ppos, tmpbuf, len); |
7974 |
- } |
7975 |
- |
7976 |
-diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c |
7977 |
-index 552705d..9920f4fb 100644 |
7978 |
---- a/security/integrity/ima/ima_queue.c |
7979 |
-+++ b/security/integrity/ima/ima_queue.c |
7980 |
-@@ -83,7 +83,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry) |
7981 |
- INIT_LIST_HEAD(&qe->later); |
7982 |
- list_add_tail_rcu(&qe->later, &ima_measurements); |
7983 |
- |
7984 |
-- atomic_long_inc(&ima_htable.len); |
7985 |
-+ atomic_long_inc_unchecked(&ima_htable.len); |
7986 |
- key = ima_hash_key(entry->digest); |
7987 |
- hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]); |
7988 |
- return 0; |
7989 |
-diff --git a/security/keys/internal.h b/security/keys/internal.h |
7990 |
-index 5105c2c..a5010e6 100644 |
7991 |
---- a/security/keys/internal.h |
7992 |
-+++ b/security/keys/internal.h |
7993 |
-@@ -90,12 +90,16 @@ extern void key_type_put(struct key_type *ktype); |
7994 |
- |
7995 |
- extern int __key_link_begin(struct key *keyring, |
7996 |
- const struct keyring_index_key *index_key, |
7997 |
-- struct assoc_array_edit **_edit); |
7998 |
-+ struct assoc_array_edit **_edit) |
7999 |
-+ __acquires(&keyring->sem) |
8000 |
-+ __acquires(&keyring_serialise_link_sem); |
8001 |
- extern int __key_link_check_live_key(struct key *keyring, struct key *key); |
8002 |
- extern void __key_link(struct key *key, struct assoc_array_edit **_edit); |
8003 |
- extern void __key_link_end(struct key *keyring, |
8004 |
- const struct keyring_index_key *index_key, |
8005 |
-- struct assoc_array_edit *edit); |
8006 |
-+ struct assoc_array_edit *edit) |
8007 |
-+ __releases(&keyring->sem) |
8008 |
-+ __releases(&keyring_serialise_link_sem); |
8009 |
- |
8010 |
- extern key_ref_t find_key_to_update(key_ref_t keyring_ref, |
8011 |
- const struct keyring_index_key *index_key); |
8012 |
-@@ -191,7 +195,7 @@ struct request_key_auth { |
8013 |
- void *callout_info; |
8014 |
- size_t callout_len; |
8015 |
- pid_t pid; |
8016 |
--}; |
8017 |
-+} __randomize_layout; |
8018 |
- |
8019 |
- extern struct key_type key_type_request_key_auth; |
8020 |
- extern struct key *request_key_auth_new(struct key *target, |
8021 |
-diff --git a/security/keys/key.c b/security/keys/key.c |
8022 |
-index 09ef276..ab2894f 100644 |
8023 |
---- a/security/keys/key.c |
8024 |
-+++ b/security/keys/key.c |
8025 |
-@@ -283,7 +283,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, |
8026 |
- |
8027 |
- atomic_set(&key->usage, 1); |
8028 |
- init_rwsem(&key->sem); |
8029 |
-- lockdep_set_class(&key->sem, &type->lock_class); |
8030 |
-+ lockdep_set_class(&key->sem, (struct lock_class_key *)&type->lock_class); |
8031 |
- key->index_key.type = type; |
8032 |
- key->user = user; |
8033 |
- key->quotalen = quotalen; |
8034 |
-@@ -1077,7 +1077,9 @@ int register_key_type(struct key_type *ktype) |
8035 |
- struct key_type *p; |
8036 |
- int ret; |
8037 |
- |
8038 |
-- memset(&ktype->lock_class, 0, sizeof(ktype->lock_class)); |
8039 |
-+ pax_open_kernel(); |
8040 |
-+ memset((void *)&ktype->lock_class, 0, sizeof(ktype->lock_class)); |
8041 |
-+ pax_close_kernel(); |
8042 |
- |
8043 |
- ret = -EEXIST; |
8044 |
- down_write(&key_types_sem); |
8045 |
-@@ -1089,7 +1091,7 @@ int register_key_type(struct key_type *ktype) |
8046 |
- } |
8047 |
- |
8048 |
- /* store the type */ |
8049 |
-- list_add(&ktype->link, &key_types_list); |
8050 |
-+ pax_list_add((struct list_head *)&ktype->link, &key_types_list); |
8051 |
- |
8052 |
- pr_notice("Key type %s registered\n", ktype->name); |
8053 |
- ret = 0; |
8054 |
-@@ -1111,7 +1113,7 @@ EXPORT_SYMBOL(register_key_type); |
8055 |
- void unregister_key_type(struct key_type *ktype) |
8056 |
- { |
8057 |
- down_write(&key_types_sem); |
8058 |
-- list_del_init(&ktype->link); |
8059 |
-+ pax_list_del_init((struct list_head *)&ktype->link); |
8060 |
- downgrade_write(&key_types_sem); |
8061 |
- key_gc_keytype(ktype); |
8062 |
- pr_notice("Key type %s unregistered\n", ktype->name); |
8063 |
-@@ -1129,10 +1131,10 @@ void __init key_init(void) |
8064 |
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
8065 |
- |
8066 |
- /* add the special key types */ |
8067 |
-- list_add_tail(&key_type_keyring.link, &key_types_list); |
8068 |
-- list_add_tail(&key_type_dead.link, &key_types_list); |
8069 |
-- list_add_tail(&key_type_user.link, &key_types_list); |
8070 |
-- list_add_tail(&key_type_logon.link, &key_types_list); |
8071 |
-+ pax_list_add_tail((struct list_head *)&key_type_keyring.link, &key_types_list); |
8072 |
-+ pax_list_add_tail((struct list_head *)&key_type_dead.link, &key_types_list); |
8073 |
-+ pax_list_add_tail((struct list_head *)&key_type_user.link, &key_types_list); |
8074 |
-+ pax_list_add_tail((struct list_head *)&key_type_logon.link, &key_types_list); |
8075 |
- |
8076 |
- /* record the root user tracking */ |
8077 |
- rb_link_node(&root_key_user.node, |
8078 |
-diff --git a/security/keys/keyring.c b/security/keys/keyring.c |
8079 |
-index f931ccf..ed9cd36 100644 |
8080 |
---- a/security/keys/keyring.c |
8081 |
-+++ b/security/keys/keyring.c |
8082 |
-@@ -1071,8 +1071,6 @@ static int keyring_detect_cycle(struct key *A, struct key *B) |
8083 |
- int __key_link_begin(struct key *keyring, |
8084 |
- const struct keyring_index_key *index_key, |
8085 |
- struct assoc_array_edit **_edit) |
8086 |
-- __acquires(&keyring->sem) |
8087 |
-- __acquires(&keyring_serialise_link_sem) |
8088 |
- { |
8089 |
- struct assoc_array_edit *edit; |
8090 |
- int ret; |
8091 |
-@@ -1172,8 +1170,6 @@ void __key_link(struct key *key, struct assoc_array_edit **_edit) |
8092 |
- void __key_link_end(struct key *keyring, |
8093 |
- const struct keyring_index_key *index_key, |
8094 |
- struct assoc_array_edit *edit) |
8095 |
-- __releases(&keyring->sem) |
8096 |
-- __releases(&keyring_serialise_link_sem) |
8097 |
- { |
8098 |
- BUG_ON(index_key->type == NULL); |
8099 |
- kenter("%d,%s,", keyring->serial, index_key->type->name); |
8100 |
-diff --git a/security/min_addr.c b/security/min_addr.c |
8101 |
-index f728728..6457a0c 100644 |
8102 |
---- a/security/min_addr.c |
8103 |
-+++ b/security/min_addr.c |
8104 |
-@@ -14,6 +14,7 @@ unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; |
8105 |
- */ |
8106 |
- static void update_mmap_min_addr(void) |
8107 |
- { |
8108 |
-+#ifndef SPARC |
8109 |
- #ifdef CONFIG_LSM_MMAP_MIN_ADDR |
8110 |
- if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) |
8111 |
- mmap_min_addr = dac_mmap_min_addr; |
8112 |
-@@ -22,6 +23,7 @@ static void update_mmap_min_addr(void) |
8113 |
- #else |
8114 |
- mmap_min_addr = dac_mmap_min_addr; |
8115 |
- #endif |
8116 |
-+#endif |
8117 |
- } |
8118 |
- |
8119 |
- /* |
8120 |
-diff --git a/security/selinux/avc.c b/security/selinux/avc.c |
8121 |
-index e60c79d..41fb721 100644 |
8122 |
---- a/security/selinux/avc.c |
8123 |
-+++ b/security/selinux/avc.c |
8124 |
-@@ -71,7 +71,7 @@ struct avc_xperms_node { |
8125 |
- struct avc_cache { |
8126 |
- struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */ |
8127 |
- spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */ |
8128 |
-- atomic_t lru_hint; /* LRU hint for reclaim scan */ |
8129 |
-+ atomic_unchecked_t lru_hint; /* LRU hint for reclaim scan */ |
8130 |
- atomic_t active_nodes; |
8131 |
- u32 latest_notif; /* latest revocation notification */ |
8132 |
- }; |
8133 |
-@@ -183,7 +183,7 @@ void __init avc_init(void) |
8134 |
- spin_lock_init(&avc_cache.slots_lock[i]); |
8135 |
- } |
8136 |
- atomic_set(&avc_cache.active_nodes, 0); |
8137 |
-- atomic_set(&avc_cache.lru_hint, 0); |
8138 |
-+ atomic_set_unchecked(&avc_cache.lru_hint, 0); |
8139 |
- |
8140 |
- avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), |
8141 |
- 0, SLAB_PANIC, NULL); |
8142 |
-@@ -521,7 +521,7 @@ static inline int avc_reclaim_node(void) |
8143 |
- spinlock_t *lock; |
8144 |
- |
8145 |
- for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) { |
8146 |
-- hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); |
8147 |
-+ hvalue = atomic_inc_return_unchecked(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); |
8148 |
- head = &avc_cache.slots[hvalue]; |
8149 |
- lock = &avc_cache.slots_lock[hvalue]; |
8150 |
- |
8151 |
-diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h |
8152 |
-index 1450f85..a91e0bc 100644 |
8153 |
---- a/security/selinux/include/xfrm.h |
8154 |
-+++ b/security/selinux/include/xfrm.h |
8155 |
-@@ -48,7 +48,7 @@ static inline void selinux_xfrm_notify_policyload(void) |
8156 |
- |
8157 |
- rtnl_lock(); |
8158 |
- for_each_net(net) { |
8159 |
-- atomic_inc(&net->xfrm.flow_cache_genid); |
8160 |
-+ atomic_inc_unchecked(&net->xfrm.flow_cache_genid); |
8161 |
- rt_genid_bump_all(net); |
8162 |
- } |
8163 |
- rtnl_unlock(); |
8164 |
-diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c |
8165 |
-index 2367b10..a0c3c51 100644 |
8166 |
---- a/security/tomoyo/file.c |
8167 |
-+++ b/security/tomoyo/file.c |
8168 |
-@@ -692,7 +692,7 @@ int tomoyo_path_number_perm(const u8 type, struct path *path, |
8169 |
- { |
8170 |
- struct tomoyo_request_info r; |
8171 |
- struct tomoyo_obj_info obj = { |
8172 |
-- .path1 = *path, |
8173 |
-+ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
8174 |
- }; |
8175 |
- int error = -ENOMEM; |
8176 |
- struct tomoyo_path_info buf; |
8177 |
-@@ -740,7 +740,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, |
8178 |
- struct tomoyo_path_info buf; |
8179 |
- struct tomoyo_request_info r; |
8180 |
- struct tomoyo_obj_info obj = { |
8181 |
-- .path1 = *path, |
8182 |
-+ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
8183 |
- }; |
8184 |
- int idx; |
8185 |
- |
8186 |
-@@ -786,7 +786,7 @@ int tomoyo_path_perm(const u8 operation, const struct path *path, const char *ta |
8187 |
- { |
8188 |
- struct tomoyo_request_info r; |
8189 |
- struct tomoyo_obj_info obj = { |
8190 |
-- .path1 = *path, |
8191 |
-+ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
8192 |
- }; |
8193 |
- int error; |
8194 |
- struct tomoyo_path_info buf; |
8195 |
-@@ -843,7 +843,7 @@ int tomoyo_mkdev_perm(const u8 operation, struct path *path, |
8196 |
- { |
8197 |
- struct tomoyo_request_info r; |
8198 |
- struct tomoyo_obj_info obj = { |
8199 |
-- .path1 = *path, |
8200 |
-+ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
8201 |
- }; |
8202 |
- int error = -ENOMEM; |
8203 |
- struct tomoyo_path_info buf; |
8204 |
-@@ -890,8 +890,8 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, |
8205 |
- struct tomoyo_path_info buf2; |
8206 |
- struct tomoyo_request_info r; |
8207 |
- struct tomoyo_obj_info obj = { |
8208 |
-- .path1 = *path1, |
8209 |
-- .path2 = *path2, |
8210 |
-+ .path1 = { .mnt = path1->mnt, .dentry = path1->dentry }, |
8211 |
-+ .path2 = { .mnt = path2->mnt, .dentry = path2->dentry } |
8212 |
- }; |
8213 |
- int idx; |
8214 |
- |
8215 |
-diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c |
8216 |
-index 390c646..f2f8db3 100644 |
8217 |
---- a/security/tomoyo/mount.c |
8218 |
-+++ b/security/tomoyo/mount.c |
8219 |
-@@ -118,6 +118,10 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, |
8220 |
- type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) { |
8221 |
- need_dev = -1; /* dev_name is a directory */ |
8222 |
- } else { |
8223 |
-+ if (!capable(CAP_SYS_ADMIN)) { |
8224 |
-+ error = -EPERM; |
8225 |
-+ goto out; |
8226 |
-+ } |
8227 |
- fstype = get_fs_type(type); |
8228 |
- if (!fstype) { |
8229 |
- error = -ENODEV; |
8230 |
-diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c |
8231 |
-index cbf3df4..22b11df 100644 |
8232 |
---- a/security/tomoyo/tomoyo.c |
8233 |
-+++ b/security/tomoyo/tomoyo.c |
8234 |
-@@ -165,7 +165,7 @@ static int tomoyo_path_truncate(struct path *path) |
8235 |
- */ |
8236 |
- static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) |
8237 |
- { |
8238 |
-- struct path path = { parent->mnt, dentry }; |
8239 |
-+ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
8240 |
- return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL); |
8241 |
- } |
8242 |
- |
8243 |
-@@ -181,7 +181,7 @@ static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) |
8244 |
- static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, |
8245 |
- umode_t mode) |
8246 |
- { |
8247 |
-- struct path path = { parent->mnt, dentry }; |
8248 |
-+ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
8249 |
- return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path, |
8250 |
- mode & S_IALLUGO); |
8251 |
- } |
8252 |
-@@ -196,7 +196,7 @@ static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, |
8253 |
- */ |
8254 |
- static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) |
8255 |
- { |
8256 |
-- struct path path = { parent->mnt, dentry }; |
8257 |
-+ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
8258 |
- return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL); |
8259 |
- } |
8260 |
- |
8261 |
-@@ -212,7 +212,7 @@ static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) |
8262 |
- static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, |
8263 |
- const char *old_name) |
8264 |
- { |
8265 |
-- struct path path = { parent->mnt, dentry }; |
8266 |
-+ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
8267 |
- return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name); |
8268 |
- } |
8269 |
- |
8270 |
-@@ -229,7 +229,7 @@ static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, |
8271 |
- static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, |
8272 |
- umode_t mode, unsigned int dev) |
8273 |
- { |
8274 |
-- struct path path = { parent->mnt, dentry }; |
8275 |
-+ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
8276 |
- int type = TOMOYO_TYPE_CREATE; |
8277 |
- const unsigned int perm = mode & S_IALLUGO; |
8278 |
- |
8279 |
-@@ -268,8 +268,8 @@ static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, |
8280 |
- static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, |
8281 |
- struct dentry *new_dentry) |
8282 |
- { |
8283 |
-- struct path path1 = { new_dir->mnt, old_dentry }; |
8284 |
-- struct path path2 = { new_dir->mnt, new_dentry }; |
8285 |
-+ struct path path1 = { .mnt = new_dir->mnt, .dentry = old_dentry }; |
8286 |
-+ struct path path2 = { .mnt = new_dir->mnt, .dentry = new_dentry }; |
8287 |
- return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2); |
8288 |
- } |
8289 |
- |
8290 |
-@@ -288,8 +288,8 @@ static int tomoyo_path_rename(struct path *old_parent, |
8291 |
- struct path *new_parent, |
8292 |
- struct dentry *new_dentry) |
8293 |
- { |
8294 |
-- struct path path1 = { old_parent->mnt, old_dentry }; |
8295 |
-- struct path path2 = { new_parent->mnt, new_dentry }; |
8296 |
-+ struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry }; |
8297 |
-+ struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry }; |
8298 |
- return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); |
8299 |
- } |
8300 |
- |
8301 |
-@@ -417,7 +417,7 @@ static int tomoyo_sb_mount(const char *dev_name, struct path *path, |
8302 |
- */ |
8303 |
- static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) |
8304 |
- { |
8305 |
-- struct path path = { mnt, mnt->mnt_root }; |
8306 |
-+ struct path path = { .mnt = mnt, .dentry = mnt->mnt_root }; |
8307 |
- return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL); |
8308 |
- } |
8309 |
- |
8310 |
-diff --git a/security/yama/Kconfig b/security/yama/Kconfig |
8311 |
-index 90c605e..bf3a29a 100644 |
8312 |
---- a/security/yama/Kconfig |
8313 |
-+++ b/security/yama/Kconfig |
8314 |
-@@ -1,6 +1,6 @@ |
8315 |
- config SECURITY_YAMA |
8316 |
- bool "Yama support" |
8317 |
-- depends on SECURITY |
8318 |
-+ depends on SECURITY && !GRKERNSEC |
8319 |
- default n |
8320 |
- help |
8321 |
- This selects Yama, which extends DAC support with additional |
8322 |
-diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c |
8323 |
-index cb6ed10..fb00554 100644 |
8324 |
---- a/security/yama/yama_lsm.c |
8325 |
-+++ b/security/yama/yama_lsm.c |
8326 |
-@@ -357,7 +357,7 @@ static struct security_hook_list yama_hooks[] = { |
8327 |
- static int yama_dointvec_minmax(struct ctl_table *table, int write, |
8328 |
- void __user *buffer, size_t *lenp, loff_t *ppos) |
8329 |
- { |
8330 |
-- struct ctl_table table_copy; |
8331 |
-+ ctl_table_no_const table_copy; |
8332 |
- |
8333 |
- if (write && !capable(CAP_SYS_PTRACE)) |
8334 |
- return -EPERM; |
8335 |
-diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c |
8336 |
-index a04edff..6811b91 100644 |
8337 |
---- a/sound/aoa/codecs/onyx.c |
8338 |
-+++ b/sound/aoa/codecs/onyx.c |
8339 |
-@@ -54,7 +54,7 @@ struct onyx { |
8340 |
- spdif_locked:1, |
8341 |
- analog_locked:1, |
8342 |
- original_mute:2; |
8343 |
-- int open_count; |
8344 |
-+ local_t open_count; |
8345 |
- struct codec_info *codec_info; |
8346 |
- |
8347 |
- /* mutex serializes concurrent access to the device |
8348 |
-@@ -747,7 +747,7 @@ static int onyx_open(struct codec_info_item *cii, |
8349 |
- struct onyx *onyx = cii->codec_data; |
8350 |
- |
8351 |
- mutex_lock(&onyx->mutex); |
8352 |
-- onyx->open_count++; |
8353 |
-+ local_inc(&onyx->open_count); |
8354 |
- mutex_unlock(&onyx->mutex); |
8355 |
- |
8356 |
- return 0; |
8357 |
-@@ -759,8 +759,7 @@ static int onyx_close(struct codec_info_item *cii, |
8358 |
- struct onyx *onyx = cii->codec_data; |
8359 |
- |
8360 |
- mutex_lock(&onyx->mutex); |
8361 |
-- onyx->open_count--; |
8362 |
-- if (!onyx->open_count) |
8363 |
-+ if (local_dec_and_test(&onyx->open_count)) |
8364 |
- onyx->spdif_locked = onyx->analog_locked = 0; |
8365 |
- mutex_unlock(&onyx->mutex); |
8366 |
- |
8367 |
-diff --git a/sound/aoa/codecs/onyx.h b/sound/aoa/codecs/onyx.h |
8368 |
-index ffd2025..df062c9 100644 |
8369 |
---- a/sound/aoa/codecs/onyx.h |
8370 |
-+++ b/sound/aoa/codecs/onyx.h |
8371 |
-@@ -11,6 +11,7 @@ |
8372 |
- #include <linux/i2c.h> |
8373 |
- #include <asm/pmac_low_i2c.h> |
8374 |
- #include <asm/prom.h> |
8375 |
-+#include <asm/local.h> |
8376 |
- |
8377 |
- /* PCM3052 register definitions */ |
8378 |
- |
8379 |
-diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c |
8380 |
-index ebc9fdf..61f491e 100644 |
8381 |
---- a/sound/core/oss/pcm_oss.c |
8382 |
-+++ b/sound/core/oss/pcm_oss.c |
8383 |
-@@ -1193,10 +1193,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const |
8384 |
- if (in_kernel) { |
8385 |
- mm_segment_t fs; |
8386 |
- fs = snd_enter_user(); |
8387 |
-- ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames); |
8388 |
-+ ret = snd_pcm_lib_write(substream, (void __force_user *)ptr, frames); |
8389 |
- snd_leave_user(fs); |
8390 |
- } else { |
8391 |
-- ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames); |
8392 |
-+ ret = snd_pcm_lib_write(substream, (void __force_user *)ptr, frames); |
8393 |
- } |
8394 |
- if (ret != -EPIPE && ret != -ESTRPIPE) |
8395 |
- break; |
8396 |
-@@ -1236,10 +1236,10 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p |
8397 |
- if (in_kernel) { |
8398 |
- mm_segment_t fs; |
8399 |
- fs = snd_enter_user(); |
8400 |
-- ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames); |
8401 |
-+ ret = snd_pcm_lib_read(substream, (void __force_user *)ptr, frames); |
8402 |
- snd_leave_user(fs); |
8403 |
- } else { |
8404 |
-- ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames); |
8405 |
-+ ret = snd_pcm_lib_read(substream, (void __force_user *)ptr, frames); |
8406 |
- } |
8407 |
- if (ret == -EPIPE) { |
8408 |
- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { |
8409 |
-@@ -1335,7 +1335,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha |
8410 |
- struct snd_pcm_plugin_channel *channels; |
8411 |
- size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; |
8412 |
- if (!in_kernel) { |
8413 |
-- if (copy_from_user(runtime->oss.buffer, (const char __force __user *)buf, bytes)) |
8414 |
-+ if (copy_from_user(runtime->oss.buffer, (const char __force_user *)buf, bytes)) |
8415 |
- return -EFAULT; |
8416 |
- buf = runtime->oss.buffer; |
8417 |
- } |
8418 |
-@@ -1405,7 +1405,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha |
8419 |
- } |
8420 |
- } else { |
8421 |
- tmp = snd_pcm_oss_write2(substream, |
8422 |
-- (const char __force *)buf, |
8423 |
-+ (const char __force_kernel *)buf, |
8424 |
- runtime->oss.period_bytes, 0); |
8425 |
- if (tmp <= 0) |
8426 |
- goto err; |
8427 |
-@@ -1431,7 +1431,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, |
8428 |
- struct snd_pcm_runtime *runtime = substream->runtime; |
8429 |
- snd_pcm_sframes_t frames, frames1; |
8430 |
- #ifdef CONFIG_SND_PCM_OSS_PLUGINS |
8431 |
-- char __user *final_dst = (char __force __user *)buf; |
8432 |
-+ char __user *final_dst = (char __force_user *)buf; |
8433 |
- if (runtime->oss.plugin_first) { |
8434 |
- struct snd_pcm_plugin_channel *channels; |
8435 |
- size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8; |
8436 |
-@@ -1493,7 +1493,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use |
8437 |
- xfer += tmp; |
8438 |
- runtime->oss.buffer_used -= tmp; |
8439 |
- } else { |
8440 |
-- tmp = snd_pcm_oss_read2(substream, (char __force *)buf, |
8441 |
-+ tmp = snd_pcm_oss_read2(substream, (char __force_kernel *)buf, |
8442 |
- runtime->oss.period_bytes, 0); |
8443 |
- if (tmp <= 0) |
8444 |
- goto err; |
8445 |
-@@ -1662,7 +1662,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) |
8446 |
- size1); |
8447 |
- size1 /= runtime->channels; /* frames */ |
8448 |
- fs = snd_enter_user(); |
8449 |
-- snd_pcm_lib_write(substream, (void __force __user *)runtime->oss.buffer, size1); |
8450 |
-+ snd_pcm_lib_write(substream, (void __force_user *)runtime->oss.buffer, size1); |
8451 |
- snd_leave_user(fs); |
8452 |
- } |
8453 |
- } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) { |
8454 |
-diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c |
8455 |
-index 1f64ab0..26a7233 100644 |
8456 |
---- a/sound/core/pcm_compat.c |
8457 |
-+++ b/sound/core/pcm_compat.c |
8458 |
-@@ -31,7 +31,7 @@ static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream, |
8459 |
- int err; |
8460 |
- |
8461 |
- fs = snd_enter_user(); |
8462 |
-- err = snd_pcm_delay(substream, &delay); |
8463 |
-+ err = snd_pcm_delay(substream, (snd_pcm_sframes_t __force_user *)&delay); |
8464 |
- snd_leave_user(fs); |
8465 |
- if (err < 0) |
8466 |
- return err; |
8467 |
-diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c |
8468 |
-index 3a9b66c..2b38b21 100644 |
8469 |
---- a/sound/core/pcm_lib.c |
8470 |
-+++ b/sound/core/pcm_lib.c |
8471 |
-@@ -1867,8 +1867,9 @@ EXPORT_SYMBOL(snd_pcm_lib_ioctl); |
8472 |
- * Even if more than one periods have elapsed since the last call, you |
8473 |
- * have to call this only once. |
8474 |
- */ |
8475 |
--void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) |
8476 |
-+void snd_pcm_period_elapsed(void *_substream) |
8477 |
- { |
8478 |
-+ struct snd_pcm_substream *substream = _substream; |
8479 |
- struct snd_pcm_runtime *runtime; |
8480 |
- unsigned long flags; |
8481 |
- |
8482 |
-diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c |
8483 |
-index 9106d8e..e7e2e3c 100644 |
8484 |
---- a/sound/core/pcm_native.c |
8485 |
-+++ b/sound/core/pcm_native.c |
8486 |
-@@ -3014,11 +3014,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, |
8487 |
- switch (substream->stream) { |
8488 |
- case SNDRV_PCM_STREAM_PLAYBACK: |
8489 |
- result = snd_pcm_playback_ioctl1(NULL, substream, cmd, |
8490 |
-- (void __user *)arg); |
8491 |
-+ (void __force_user *)arg); |
8492 |
- break; |
8493 |
- case SNDRV_PCM_STREAM_CAPTURE: |
8494 |
- result = snd_pcm_capture_ioctl1(NULL, substream, cmd, |
8495 |
-- (void __user *)arg); |
8496 |
-+ (void __force_user *)arg); |
8497 |
- break; |
8498 |
- default: |
8499 |
- result = -EINVAL; |
8500 |
-diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c |
8501 |
-index 795437b..3650746 100644 |
8502 |
---- a/sound/core/rawmidi.c |
8503 |
-+++ b/sound/core/rawmidi.c |
8504 |
-@@ -871,9 +871,10 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, |
8505 |
- * |
8506 |
- * Return: The size of read data, or a negative error code on failure. |
8507 |
- */ |
8508 |
--int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, |
8509 |
-- const unsigned char *buffer, int count) |
8510 |
-+int snd_rawmidi_receive(void *_substream, const void *_buffer, int count) |
8511 |
- { |
8512 |
-+ struct snd_rawmidi_substream *substream = _substream; |
8513 |
-+ const unsigned char *buffer = _buffer; |
8514 |
- unsigned long flags; |
8515 |
- int result = 0, count1; |
8516 |
- struct snd_rawmidi_runtime *runtime = substream->runtime; |
8517 |
-diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c |
8518 |
-index b16dbef04..8eb05a4 100644 |
8519 |
---- a/sound/core/seq/oss/seq_oss_synth.c |
8520 |
-+++ b/sound/core/seq/oss/seq_oss_synth.c |
8521 |
-@@ -653,8 +653,8 @@ snd_seq_oss_synth_info_read(struct snd_info_buffer *buf) |
8522 |
- rec->synth_type, rec->synth_subtype, |
8523 |
- rec->nr_voices); |
8524 |
- snd_iprintf(buf, " capabilities : ioctl %s / load_patch %s\n", |
8525 |
-- enabled_str((long)rec->oper.ioctl), |
8526 |
-- enabled_str((long)rec->oper.load_patch)); |
8527 |
-+ enabled_str(!!rec->oper.ioctl), |
8528 |
-+ enabled_str(!!rec->oper.load_patch)); |
8529 |
- snd_use_lock_free(&rec->use_lock); |
8530 |
- } |
8531 |
- } |
8532 |
-diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c |
8533 |
-index 58e79e0..19751d1 100644 |
8534 |
---- a/sound/core/seq/seq_clientmgr.c |
8535 |
-+++ b/sound/core/seq/seq_clientmgr.c |
8536 |
-@@ -416,7 +416,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, |
8537 |
- if (!client->accept_input || (fifo = client->data.user.fifo) == NULL) |
8538 |
- return -ENXIO; |
8539 |
- |
8540 |
-- if (atomic_read(&fifo->overflow) > 0) { |
8541 |
-+ if (atomic_read_unchecked(&fifo->overflow) > 0) { |
8542 |
- /* buffer overflow is detected */ |
8543 |
- snd_seq_fifo_clear(fifo); |
8544 |
- /* return error code */ |
8545 |
-@@ -446,7 +446,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, |
8546 |
- count -= sizeof(struct snd_seq_event); |
8547 |
- buf += sizeof(struct snd_seq_event); |
8548 |
- err = snd_seq_expand_var_event(&cell->event, count, |
8549 |
-- (char __force *)buf, 0, |
8550 |
-+ (char __force_kernel *)buf, 0, |
8551 |
- sizeof(struct snd_seq_event)); |
8552 |
- if (err < 0) |
8553 |
- break; |
8554 |
-@@ -1062,13 +1062,13 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, |
8555 |
- } |
8556 |
- /* set user space pointer */ |
8557 |
- event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR; |
8558 |
-- event.data.ext.ptr = (char __force *)buf |
8559 |
-+ event.data.ext.ptr = (char __force_kernel *)buf |
8560 |
- + sizeof(struct snd_seq_event); |
8561 |
- len += extlen; /* increment data length */ |
8562 |
- } else { |
8563 |
- #ifdef CONFIG_COMPAT |
8564 |
- if (client->convert32 && snd_seq_ev_is_varusr(&event)) { |
8565 |
-- void *ptr = (void __force *)compat_ptr(event.data.raw32.d[1]); |
8566 |
-+ void *ptr = (void __force_kernel *)compat_ptr(event.data.raw32.d[1]); |
8567 |
- event.data.ext.ptr = ptr; |
8568 |
- } |
8569 |
- #endif |
8570 |
-@@ -2423,7 +2423,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) |
8571 |
- if (client == NULL) |
8572 |
- return -ENXIO; |
8573 |
- fs = snd_enter_user(); |
8574 |
-- result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg); |
8575 |
-+ result = snd_seq_do_ioctl(client, cmd, (void __force_user *)arg); |
8576 |
- snd_leave_user(fs); |
8577 |
- return result; |
8578 |
- } |
8579 |
-diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c |
8580 |
-index 6517590..9905cee 100644 |
8581 |
---- a/sound/core/seq/seq_compat.c |
8582 |
-+++ b/sound/core/seq/seq_compat.c |
8583 |
-@@ -60,7 +60,7 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned |
8584 |
- data->kernel = NULL; |
8585 |
- |
8586 |
- fs = snd_enter_user(); |
8587 |
-- err = snd_seq_do_ioctl(client, cmd, data); |
8588 |
-+ err = snd_seq_do_ioctl(client, cmd, (void __force_user *)data); |
8589 |
- snd_leave_user(fs); |
8590 |
- if (err < 0) |
8591 |
- goto error; |
8592 |
-diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c |
8593 |
-index 1d5acbe..5f55223 100644 |
8594 |
---- a/sound/core/seq/seq_fifo.c |
8595 |
-+++ b/sound/core/seq/seq_fifo.c |
8596 |
-@@ -50,7 +50,7 @@ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize) |
8597 |
- spin_lock_init(&f->lock); |
8598 |
- snd_use_lock_init(&f->use_lock); |
8599 |
- init_waitqueue_head(&f->input_sleep); |
8600 |
-- atomic_set(&f->overflow, 0); |
8601 |
-+ atomic_set_unchecked(&f->overflow, 0); |
8602 |
- |
8603 |
- f->head = NULL; |
8604 |
- f->tail = NULL; |
8605 |
-@@ -96,7 +96,7 @@ void snd_seq_fifo_clear(struct snd_seq_fifo *f) |
8606 |
- unsigned long flags; |
8607 |
- |
8608 |
- /* clear overflow flag */ |
8609 |
-- atomic_set(&f->overflow, 0); |
8610 |
-+ atomic_set_unchecked(&f->overflow, 0); |
8611 |
- |
8612 |
- snd_use_lock_sync(&f->use_lock); |
8613 |
- spin_lock_irqsave(&f->lock, flags); |
8614 |
-@@ -123,7 +123,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, |
8615 |
- err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ |
8616 |
- if (err < 0) { |
8617 |
- if ((err == -ENOMEM) || (err == -EAGAIN)) |
8618 |
-- atomic_inc(&f->overflow); |
8619 |
-+ atomic_inc_unchecked(&f->overflow); |
8620 |
- snd_use_lock_free(&f->use_lock); |
8621 |
- return err; |
8622 |
- } |
8623 |
-diff --git a/sound/core/seq/seq_fifo.h b/sound/core/seq/seq_fifo.h |
8624 |
-index 062c446..a4b6f4c 100644 |
8625 |
---- a/sound/core/seq/seq_fifo.h |
8626 |
-+++ b/sound/core/seq/seq_fifo.h |
8627 |
-@@ -35,7 +35,7 @@ struct snd_seq_fifo { |
8628 |
- spinlock_t lock; |
8629 |
- snd_use_lock_t use_lock; |
8630 |
- wait_queue_head_t input_sleep; |
8631 |
-- atomic_t overflow; |
8632 |
-+ atomic_unchecked_t overflow; |
8633 |
- |
8634 |
- }; |
8635 |
- |
8636 |
-diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c |
8637 |
-index c850345..ec0a853 100644 |
8638 |
---- a/sound/core/seq/seq_memory.c |
8639 |
-+++ b/sound/core/seq/seq_memory.c |
8640 |
-@@ -87,7 +87,7 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event, |
8641 |
- |
8642 |
- if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { |
8643 |
- char buf[32]; |
8644 |
-- char __user *curptr = (char __force __user *)event->data.ext.ptr; |
8645 |
-+ char __user *curptr = (char __force_user *)event->data.ext.ptr; |
8646 |
- while (len > 0) { |
8647 |
- int size = sizeof(buf); |
8648 |
- if (len < size) |
8649 |
-@@ -126,15 +126,19 @@ EXPORT_SYMBOL(snd_seq_dump_var_event); |
8650 |
- * expand the variable length event to linear buffer space. |
8651 |
- */ |
8652 |
- |
8653 |
--static int seq_copy_in_kernel(char **bufptr, const void *src, int size) |
8654 |
-+static int seq_copy_in_kernel(void *_bufptr, const void *src, int size) |
8655 |
- { |
8656 |
-+ char **bufptr = (char **)_bufptr; |
8657 |
-+ |
8658 |
- memcpy(*bufptr, src, size); |
8659 |
- *bufptr += size; |
8660 |
- return 0; |
8661 |
- } |
8662 |
- |
8663 |
--static int seq_copy_in_user(char __user **bufptr, const void *src, int size) |
8664 |
-+static int seq_copy_in_user(void *_bufptr, const void *src, int size) |
8665 |
- { |
8666 |
-+ char __user **bufptr = (char __user **)_bufptr; |
8667 |
-+ |
8668 |
- if (copy_to_user(*bufptr, src, size)) |
8669 |
- return -EFAULT; |
8670 |
- *bufptr += size; |
8671 |
-@@ -158,13 +162,13 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char |
8672 |
- if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { |
8673 |
- if (! in_kernel) |
8674 |
- return -EINVAL; |
8675 |
-- if (copy_from_user(buf, (void __force __user *)event->data.ext.ptr, len)) |
8676 |
-+ if (copy_from_user(buf, (void __force_user *)event->data.ext.ptr, len)) |
8677 |
- return -EFAULT; |
8678 |
- return newlen; |
8679 |
- } |
8680 |
- err = snd_seq_dump_var_event(event, |
8681 |
-- in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel : |
8682 |
-- (snd_seq_dump_func_t)seq_copy_in_user, |
8683 |
-+ in_kernel ? seq_copy_in_kernel : |
8684 |
-+ seq_copy_in_user, |
8685 |
- &buf); |
8686 |
- return err < 0 ? err : newlen; |
8687 |
- } |
8688 |
-@@ -344,7 +348,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, |
8689 |
- tmp->event = src->event; |
8690 |
- src = src->next; |
8691 |
- } else if (is_usrptr) { |
8692 |
-- if (copy_from_user(&tmp->event, (char __force __user *)buf, size)) { |
8693 |
-+ if (copy_from_user(&tmp->event, (char __force_user *)buf, size)) { |
8694 |
- err = -EFAULT; |
8695 |
- goto __error; |
8696 |
- } |
8697 |
-diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c |
8698 |
-index 5dd0ee2..0208e35 100644 |
8699 |
---- a/sound/core/seq/seq_midi.c |
8700 |
-+++ b/sound/core/seq/seq_midi.c |
8701 |
-@@ -111,8 +111,9 @@ static void snd_midi_input_event(struct snd_rawmidi_substream *substream) |
8702 |
- } |
8703 |
- } |
8704 |
- |
8705 |
--static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, int count) |
8706 |
-+static int dump_midi(void *_substream, const void *buf, int count) |
8707 |
- { |
8708 |
-+ struct snd_rawmidi_substream *substream = _substream; |
8709 |
- struct snd_rawmidi_runtime *runtime; |
8710 |
- int tmp; |
8711 |
- |
8712 |
-@@ -148,7 +149,7 @@ static int event_process_midi(struct snd_seq_event *ev, int direct, |
8713 |
- pr_debug("ALSA: seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); |
8714 |
- return 0; |
8715 |
- } |
8716 |
-- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); |
8717 |
-+ snd_seq_dump_var_event(ev, dump_midi, substream); |
8718 |
- snd_midi_event_reset_decode(msynth->parser); |
8719 |
- } else { |
8720 |
- if (msynth->parser == NULL) |
8721 |
-diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c |
8722 |
-index c82ed3e..e11d039 100644 |
8723 |
---- a/sound/core/seq/seq_virmidi.c |
8724 |
-+++ b/sound/core/seq/seq_virmidi.c |
8725 |
-@@ -90,7 +90,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, |
8726 |
- if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { |
8727 |
- if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) |
8728 |
- continue; |
8729 |
-- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream); |
8730 |
-+ snd_seq_dump_var_event(ev, snd_rawmidi_receive, vmidi->substream); |
8731 |
- } else { |
8732 |
- len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); |
8733 |
- if (len > 0) |
8734 |
-diff --git a/sound/core/sound.c b/sound/core/sound.c |
8735 |
-index 175f9e4..3518d31 100644 |
8736 |
---- a/sound/core/sound.c |
8737 |
-+++ b/sound/core/sound.c |
8738 |
-@@ -86,7 +86,7 @@ static void snd_request_other(int minor) |
8739 |
- case SNDRV_MINOR_TIMER: str = "snd-timer"; break; |
8740 |
- default: return; |
8741 |
- } |
8742 |
-- request_module(str); |
8743 |
-+ request_module("%s", str); |
8744 |
- } |
8745 |
- |
8746 |
- #endif /* modular kernel */ |
8747 |
-diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c |
8748 |
-index 2a008a9..a1efb3f 100644 |
8749 |
---- a/sound/drivers/mts64.c |
8750 |
-+++ b/sound/drivers/mts64.c |
8751 |
-@@ -29,6 +29,7 @@ |
8752 |
- #include <sound/initval.h> |
8753 |
- #include <sound/rawmidi.h> |
8754 |
- #include <sound/control.h> |
8755 |
-+#include <asm/local.h> |
8756 |
- |
8757 |
- #define CARD_NAME "Miditerminal 4140" |
8758 |
- #define DRIVER_NAME "MTS64" |
8759 |
-@@ -67,7 +68,7 @@ struct mts64 { |
8760 |
- struct pardevice *pardev; |
8761 |
- int pardev_claimed; |
8762 |
- |
8763 |
-- int open_count; |
8764 |
-+ local_t open_count; |
8765 |
- int current_midi_output_port; |
8766 |
- int current_midi_input_port; |
8767 |
- u8 mode[MTS64_NUM_INPUT_PORTS]; |
8768 |
-@@ -687,7 +688,7 @@ static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream) |
8769 |
- { |
8770 |
- struct mts64 *mts = substream->rmidi->private_data; |
8771 |
- |
8772 |
-- if (mts->open_count == 0) { |
8773 |
-+ if (local_read(&mts->open_count) == 0) { |
8774 |
- /* We don't need a spinlock here, because this is just called |
8775 |
- if the device has not been opened before. |
8776 |
- So there aren't any IRQs from the device */ |
8777 |
-@@ -695,7 +696,7 @@ static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream) |
8778 |
- |
8779 |
- msleep(50); |
8780 |
- } |
8781 |
-- ++(mts->open_count); |
8782 |
-+ local_inc(&mts->open_count); |
8783 |
- |
8784 |
- return 0; |
8785 |
- } |
8786 |
-@@ -705,8 +706,7 @@ static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream) |
8787 |
- struct mts64 *mts = substream->rmidi->private_data; |
8788 |
- unsigned long flags; |
8789 |
- |
8790 |
-- --(mts->open_count); |
8791 |
-- if (mts->open_count == 0) { |
8792 |
-+ if (local_dec_return(&mts->open_count) == 0) { |
8793 |
- /* We need the spinlock_irqsave here because we can still |
8794 |
- have IRQs at this point */ |
8795 |
- spin_lock_irqsave(&mts->lock, flags); |
8796 |
-@@ -715,8 +715,8 @@ static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream) |
8797 |
- |
8798 |
- msleep(500); |
8799 |
- |
8800 |
-- } else if (mts->open_count < 0) |
8801 |
-- mts->open_count = 0; |
8802 |
-+ } else if (local_read(&mts->open_count) < 0) |
8803 |
-+ local_set(&mts->open_count, 0); |
8804 |
- |
8805 |
- return 0; |
8806 |
- } |
8807 |
-diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c |
8808 |
-index 89c7aa0..6d75e49 100644 |
8809 |
---- a/sound/drivers/opl4/opl4_lib.c |
8810 |
-+++ b/sound/drivers/opl4/opl4_lib.c |
8811 |
-@@ -29,7 +29,7 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@×××××××.de>"); |
8812 |
- MODULE_DESCRIPTION("OPL4 driver"); |
8813 |
- MODULE_LICENSE("GPL"); |
8814 |
- |
8815 |
--static void inline snd_opl4_wait(struct snd_opl4 *opl4) |
8816 |
-+static inline void snd_opl4_wait(struct snd_opl4 *opl4) |
8817 |
- { |
8818 |
- int timeout = 10; |
8819 |
- while ((inb(opl4->fm_port) & OPL4_STATUS_BUSY) && --timeout > 0) |
8820 |
-diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c |
8821 |
-index 464385a..46ab3f6 100644 |
8822 |
---- a/sound/drivers/portman2x4.c |
8823 |
-+++ b/sound/drivers/portman2x4.c |
8824 |
-@@ -48,6 +48,7 @@ |
8825 |
- #include <sound/initval.h> |
8826 |
- #include <sound/rawmidi.h> |
8827 |
- #include <sound/control.h> |
8828 |
-+#include <asm/local.h> |
8829 |
- |
8830 |
- #define CARD_NAME "Portman 2x4" |
8831 |
- #define DRIVER_NAME "portman" |
8832 |
-@@ -85,7 +86,7 @@ struct portman { |
8833 |
- struct pardevice *pardev; |
8834 |
- int pardev_claimed; |
8835 |
- |
8836 |
-- int open_count; |
8837 |
-+ local_t open_count; |
8838 |
- int mode[PORTMAN_NUM_INPUT_PORTS]; |
8839 |
- struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS]; |
8840 |
- }; |
8841 |
-diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c |
8842 |
-index bebddc6..f5976be 100644 |
8843 |
---- a/sound/firewire/amdtp-am824.c |
8844 |
-+++ b/sound/firewire/amdtp-am824.c |
8845 |
-@@ -314,7 +314,7 @@ void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port, |
8846 |
- struct amdtp_am824 *p = s->protocol; |
8847 |
- |
8848 |
- if (port < p->midi_ports) |
8849 |
-- ACCESS_ONCE(p->midi[port]) = midi; |
8850 |
-+ ACCESS_ONCE_RW(p->midi[port]) = midi; |
8851 |
- } |
8852 |
- EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger); |
8853 |
- |
8854 |
-diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c |
8855 |
-index ed29026..933d2ae 100644 |
8856 |
---- a/sound/firewire/amdtp-stream.c |
8857 |
-+++ b/sound/firewire/amdtp-stream.c |
8858 |
-@@ -344,7 +344,7 @@ static void update_pcm_pointers(struct amdtp_stream *s, |
8859 |
- ptr = s->pcm_buffer_pointer + frames; |
8860 |
- if (ptr >= pcm->runtime->buffer_size) |
8861 |
- ptr -= pcm->runtime->buffer_size; |
8862 |
-- ACCESS_ONCE(s->pcm_buffer_pointer) = ptr; |
8863 |
-+ ACCESS_ONCE_RW(s->pcm_buffer_pointer) = ptr; |
8864 |
- |
8865 |
- s->pcm_period_pointer += frames; |
8866 |
- if (s->pcm_period_pointer >= pcm->runtime->period_size) { |
8867 |
-@@ -811,7 +811,7 @@ EXPORT_SYMBOL(amdtp_stream_pcm_pointer); |
8868 |
- void amdtp_stream_update(struct amdtp_stream *s) |
8869 |
- { |
8870 |
- /* Precomputing. */ |
8871 |
-- ACCESS_ONCE(s->source_node_id_field) = |
8872 |
-+ ACCESS_ONCE_RW(s->source_node_id_field) = |
8873 |
- (fw_parent_device(s->unit)->card->node_id << CIP_SID_SHIFT) & |
8874 |
- CIP_SID_MASK; |
8875 |
- } |
8876 |
-diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h |
8877 |
-index 8775704..8fea566 100644 |
8878 |
---- a/sound/firewire/amdtp-stream.h |
8879 |
-+++ b/sound/firewire/amdtp-stream.h |
8880 |
-@@ -215,7 +215,7 @@ static inline bool amdtp_stream_pcm_running(struct amdtp_stream *s) |
8881 |
- static inline void amdtp_stream_pcm_trigger(struct amdtp_stream *s, |
8882 |
- struct snd_pcm_substream *pcm) |
8883 |
- { |
8884 |
-- ACCESS_ONCE(s->pcm) = pcm; |
8885 |
-+ ACCESS_ONCE_RW(s->pcm) = pcm; |
8886 |
- } |
8887 |
- |
8888 |
- static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc) |
8889 |
-diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c |
8890 |
-index 0ac92ab..a2081aa 100644 |
8891 |
---- a/sound/firewire/digi00x/amdtp-dot.c |
8892 |
-+++ b/sound/firewire/digi00x/amdtp-dot.c |
8893 |
-@@ -365,7 +365,7 @@ void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, |
8894 |
- struct amdtp_dot *p = s->protocol; |
8895 |
- |
8896 |
- if (port < p->midi_ports) |
8897 |
-- ACCESS_ONCE(p->midi[port]) = midi; |
8898 |
-+ ACCESS_ONCE_RW(p->midi[port]) = midi; |
8899 |
- } |
8900 |
- |
8901 |
- static unsigned int process_tx_data_blocks(struct amdtp_stream *s, |
8902 |
-diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c |
8903 |
-index 48d6dca..a0266c23 100644 |
8904 |
---- a/sound/firewire/isight.c |
8905 |
-+++ b/sound/firewire/isight.c |
8906 |
-@@ -96,7 +96,7 @@ static void isight_update_pointers(struct isight *isight, unsigned int count) |
8907 |
- ptr += count; |
8908 |
- if (ptr >= runtime->buffer_size) |
8909 |
- ptr -= runtime->buffer_size; |
8910 |
-- ACCESS_ONCE(isight->buffer_pointer) = ptr; |
8911 |
-+ ACCESS_ONCE_RW(isight->buffer_pointer) = ptr; |
8912 |
- |
8913 |
- isight->period_counter += count; |
8914 |
- if (isight->period_counter >= runtime->period_size) { |
8915 |
-@@ -293,7 +293,7 @@ static int isight_hw_params(struct snd_pcm_substream *substream, |
8916 |
- if (err < 0) |
8917 |
- return err; |
8918 |
- |
8919 |
-- ACCESS_ONCE(isight->pcm_active) = true; |
8920 |
-+ ACCESS_ONCE_RW(isight->pcm_active) = true; |
8921 |
- |
8922 |
- return 0; |
8923 |
- } |
8924 |
-@@ -331,7 +331,7 @@ static int isight_hw_free(struct snd_pcm_substream *substream) |
8925 |
- { |
8926 |
- struct isight *isight = substream->private_data; |
8927 |
- |
8928 |
-- ACCESS_ONCE(isight->pcm_active) = false; |
8929 |
-+ ACCESS_ONCE_RW(isight->pcm_active) = false; |
8930 |
- |
8931 |
- mutex_lock(&isight->mutex); |
8932 |
- isight_stop_streaming(isight); |
8933 |
-@@ -424,10 +424,10 @@ static int isight_trigger(struct snd_pcm_substream *substream, int cmd) |
8934 |
- |
8935 |
- switch (cmd) { |
8936 |
- case SNDRV_PCM_TRIGGER_START: |
8937 |
-- ACCESS_ONCE(isight->pcm_running) = true; |
8938 |
-+ ACCESS_ONCE_RW(isight->pcm_running) = true; |
8939 |
- break; |
8940 |
- case SNDRV_PCM_TRIGGER_STOP: |
8941 |
-- ACCESS_ONCE(isight->pcm_running) = false; |
8942 |
-+ ACCESS_ONCE_RW(isight->pcm_running) = false; |
8943 |
- break; |
8944 |
- default: |
8945 |
- return -EINVAL; |
8946 |
-diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c |
8947 |
-index bb53eb3..670cd89 100644 |
8948 |
---- a/sound/firewire/oxfw/oxfw-scs1x.c |
8949 |
-+++ b/sound/firewire/oxfw/oxfw-scs1x.c |
8950 |
-@@ -278,9 +278,9 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up) |
8951 |
- |
8952 |
- if (up) { |
8953 |
- scs->input_escape_count = 0; |
8954 |
-- ACCESS_ONCE(scs->input) = stream; |
8955 |
-+ ACCESS_ONCE_RW(scs->input) = stream; |
8956 |
- } else { |
8957 |
-- ACCESS_ONCE(scs->input) = NULL; |
8958 |
-+ ACCESS_ONCE_RW(scs->input) = NULL; |
8959 |
- } |
8960 |
- } |
8961 |
- |
8962 |
-@@ -310,10 +310,10 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *stream, int up) |
8963 |
- scs->output_escaped = false; |
8964 |
- scs->output_idle = false; |
8965 |
- |
8966 |
-- ACCESS_ONCE(scs->output) = stream; |
8967 |
-+ ACCESS_ONCE_RW(scs->output) = stream; |
8968 |
- tasklet_schedule(&scs->tasklet); |
8969 |
- } else { |
8970 |
-- ACCESS_ONCE(scs->output) = NULL; |
8971 |
-+ ACCESS_ONCE_RW(scs->output) = NULL; |
8972 |
- } |
8973 |
- } |
8974 |
- static void midi_playback_drain(struct snd_rawmidi_substream *stream) |
8975 |
-diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c |
8976 |
-index dc91072..d85a10a 100644 |
8977 |
---- a/sound/oss/sb_audio.c |
8978 |
-+++ b/sound/oss/sb_audio.c |
8979 |
-@@ -900,7 +900,7 @@ sb16_copy_from_user(int dev, |
8980 |
- buf16 = (signed short *)(localbuf + localoffs); |
8981 |
- while (c) |
8982 |
- { |
8983 |
-- locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c); |
8984 |
-+ locallen = ((unsigned)c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c); |
8985 |
- if (copy_from_user(lbuf8, |
8986 |
- userbuf+useroffs + p, |
8987 |
- locallen)) |
8988 |
-diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c |
8989 |
-index 213a416..aeab5c9 100644 |
8990 |
---- a/sound/oss/swarm_cs4297a.c |
8991 |
-+++ b/sound/oss/swarm_cs4297a.c |
8992 |
-@@ -2623,7 +2623,6 @@ static int __init cs4297a_init(void) |
8993 |
- { |
8994 |
- struct cs4297a_state *s; |
8995 |
- u32 pwr, id; |
8996 |
-- mm_segment_t fs; |
8997 |
- int rval; |
8998 |
- u64 cfg; |
8999 |
- int mdio_val; |
9000 |
-@@ -2709,22 +2708,23 @@ static int __init cs4297a_init(void) |
9001 |
- if (!rval) { |
9002 |
- char *sb1250_duart_present; |
9003 |
- |
9004 |
-+#if 0 |
9005 |
-+ mm_segment_t fs; |
9006 |
- fs = get_fs(); |
9007 |
- set_fs(KERNEL_DS); |
9008 |
--#if 0 |
9009 |
- val = SOUND_MASK_LINE; |
9010 |
- mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val); |
9011 |
- for (i = 0; i < ARRAY_SIZE(initvol); i++) { |
9012 |
- val = initvol[i].vol; |
9013 |
- mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val); |
9014 |
- } |
9015 |
-+ set_fs(fs); |
9016 |
- // cs4297a_write_ac97(s, 0x18, 0x0808); |
9017 |
- #else |
9018 |
- // cs4297a_write_ac97(s, 0x5e, 0x180); |
9019 |
- cs4297a_write_ac97(s, 0x02, 0x0808); |
9020 |
- cs4297a_write_ac97(s, 0x18, 0x0808); |
9021 |
- #endif |
9022 |
-- set_fs(fs); |
9023 |
- |
9024 |
- list_add(&s->list, &cs4297a_devs); |
9025 |
- |
9026 |
-diff --git a/sound/pci/als300.c b/sound/pci/als300.c |
9027 |
-index add3176..c9394d9 100644 |
9028 |
---- a/sound/pci/als300.c |
9029 |
-+++ b/sound/pci/als300.c |
9030 |
-@@ -647,7 +647,7 @@ static int snd_als300_create(struct snd_card *card, |
9031 |
- struct snd_als300 **rchip) |
9032 |
- { |
9033 |
- struct snd_als300 *chip; |
9034 |
-- void *irq_handler; |
9035 |
-+ irq_handler_t irq_handler; |
9036 |
- int err; |
9037 |
- |
9038 |
- static struct snd_device_ops ops = { |
9039 |
-diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c |
9040 |
-index 1677143..85aca1d 100644 |
9041 |
---- a/sound/pci/aw2/aw2-alsa.c |
9042 |
-+++ b/sound/pci/aw2/aw2-alsa.c |
9043 |
-@@ -458,7 +458,6 @@ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) |
9044 |
- |
9045 |
- /* Define Interrupt callback */ |
9046 |
- snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number, |
9047 |
-- (snd_aw2_saa7146_it_cb) |
9048 |
- snd_pcm_period_elapsed, |
9049 |
- (void *)substream); |
9050 |
- |
9051 |
-@@ -487,7 +486,6 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) |
9052 |
- |
9053 |
- /* Define Interrupt callback */ |
9054 |
- snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number, |
9055 |
-- (snd_aw2_saa7146_it_cb) |
9056 |
- snd_pcm_period_elapsed, |
9057 |
- (void *)substream); |
9058 |
- |
9059 |
-diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c |
9060 |
-index 1d78904..d9c1056 100644 |
9061 |
---- a/sound/pci/aw2/aw2-saa7146.c |
9062 |
-+++ b/sound/pci/aw2/aw2-saa7146.c |
9063 |
-@@ -262,7 +262,7 @@ void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number, |
9064 |
- { |
9065 |
- if (stream_number < NB_STREAM_PLAYBACK) { |
9066 |
- arr_substream_it_playback_cb[stream_number].p_it_callback = |
9067 |
-- (snd_aw2_saa7146_it_cb) p_it_callback; |
9068 |
-+ p_it_callback; |
9069 |
- arr_substream_it_playback_cb[stream_number].p_callback_param = |
9070 |
- (void *)p_callback_param; |
9071 |
- } |
9072 |
-@@ -275,7 +275,7 @@ void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number, |
9073 |
- { |
9074 |
- if (stream_number < NB_STREAM_CAPTURE) { |
9075 |
- arr_substream_it_capture_cb[stream_number].p_it_callback = |
9076 |
-- (snd_aw2_saa7146_it_cb) p_it_callback; |
9077 |
-+ p_it_callback; |
9078 |
- arr_substream_it_capture_cb[stream_number].p_callback_param = |
9079 |
- (void *)p_callback_param; |
9080 |
- } |
9081 |
-diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c |
9082 |
-index 5fcbb06..f4b85df 100644 |
9083 |
---- a/sound/pci/ctxfi/ctamixer.c |
9084 |
-+++ b/sound/pci/ctxfi/ctamixer.c |
9085 |
-@@ -297,8 +297,9 @@ static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer) |
9086 |
- return 0; |
9087 |
- } |
9088 |
- |
9089 |
--int amixer_mgr_create(struct hw *hw, struct amixer_mgr **ramixer_mgr) |
9090 |
-+int amixer_mgr_create(struct hw *hw, void **_ramixer_mgr) |
9091 |
- { |
9092 |
-+ struct amixer_mgr **ramixer_mgr = (struct amixer_mgr **)_ramixer_mgr; |
9093 |
- int err; |
9094 |
- struct amixer_mgr *amixer_mgr; |
9095 |
- |
9096 |
-@@ -326,8 +327,10 @@ error: |
9097 |
- return err; |
9098 |
- } |
9099 |
- |
9100 |
--int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr) |
9101 |
-+int amixer_mgr_destroy(void *_amixer_mgr) |
9102 |
- { |
9103 |
-+ struct amixer_mgr *amixer_mgr = _amixer_mgr; |
9104 |
-+ |
9105 |
- rsc_mgr_uninit(&amixer_mgr->mgr); |
9106 |
- kfree(amixer_mgr); |
9107 |
- return 0; |
9108 |
-@@ -452,8 +455,9 @@ static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum) |
9109 |
- return 0; |
9110 |
- } |
9111 |
- |
9112 |
--int sum_mgr_create(struct hw *hw, struct sum_mgr **rsum_mgr) |
9113 |
-+int sum_mgr_create(struct hw *hw, void **_rsum_mgr) |
9114 |
- { |
9115 |
-+ struct sum_mgr **rsum_mgr = (struct sum_mgr **)_rsum_mgr; |
9116 |
- int err; |
9117 |
- struct sum_mgr *sum_mgr; |
9118 |
- |
9119 |
-@@ -481,8 +485,10 @@ error: |
9120 |
- return err; |
9121 |
- } |
9122 |
- |
9123 |
--int sum_mgr_destroy(struct sum_mgr *sum_mgr) |
9124 |
-+int sum_mgr_destroy(void *_sum_mgr) |
9125 |
- { |
9126 |
-+ struct sum_mgr *sum_mgr = _sum_mgr; |
9127 |
-+ |
9128 |
- rsc_mgr_uninit(&sum_mgr->mgr); |
9129 |
- kfree(sum_mgr); |
9130 |
- return 0; |
9131 |
-diff --git a/sound/pci/ctxfi/ctamixer.h b/sound/pci/ctxfi/ctamixer.h |
9132 |
-index 2de18aa..2fbd01b 100644 |
9133 |
---- a/sound/pci/ctxfi/ctamixer.h |
9134 |
-+++ b/sound/pci/ctxfi/ctamixer.h |
9135 |
-@@ -47,8 +47,8 @@ struct sum_mgr { |
9136 |
- }; |
9137 |
- |
9138 |
- /* Constructor and destructor of daio resource manager */ |
9139 |
--int sum_mgr_create(struct hw *hw, struct sum_mgr **rsum_mgr); |
9140 |
--int sum_mgr_destroy(struct sum_mgr *sum_mgr); |
9141 |
-+int sum_mgr_create(struct hw *hw, void **rsum_mgr); |
9142 |
-+int sum_mgr_destroy(void *sum_mgr); |
9143 |
- |
9144 |
- /* Define the descriptor of a amixer resource */ |
9145 |
- struct amixer_rsc_ops; |
9146 |
-@@ -93,7 +93,7 @@ struct amixer_mgr { |
9147 |
- }; |
9148 |
- |
9149 |
- /* Constructor and destructor of amixer resource manager */ |
9150 |
--int amixer_mgr_create(struct hw *hw, struct amixer_mgr **ramixer_mgr); |
9151 |
--int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr); |
9152 |
-+int amixer_mgr_create(struct hw *hw, void **ramixer_mgr); |
9153 |
-+int amixer_mgr_destroy(void *amixer_mgr); |
9154 |
- |
9155 |
- #endif /* CTAMIXER_H */ |
9156 |
-diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c |
9157 |
-index 977a598..a787004 100644 |
9158 |
---- a/sound/pci/ctxfi/ctatc.c |
9159 |
-+++ b/sound/pci/ctxfi/ctatc.c |
9160 |
-@@ -113,16 +113,16 @@ static struct { |
9161 |
- int (*create)(struct hw *hw, void **rmgr); |
9162 |
- int (*destroy)(void *mgr); |
9163 |
- } rsc_mgr_funcs[NUM_RSCTYP] = { |
9164 |
-- [SRC] = { .create = (create_t)src_mgr_create, |
9165 |
-- .destroy = (destroy_t)src_mgr_destroy }, |
9166 |
-- [SRCIMP] = { .create = (create_t)srcimp_mgr_create, |
9167 |
-- .destroy = (destroy_t)srcimp_mgr_destroy }, |
9168 |
-- [AMIXER] = { .create = (create_t)amixer_mgr_create, |
9169 |
-- .destroy = (destroy_t)amixer_mgr_destroy }, |
9170 |
-- [SUM] = { .create = (create_t)sum_mgr_create, |
9171 |
-- .destroy = (destroy_t)sum_mgr_destroy }, |
9172 |
-- [DAIO] = { .create = (create_t)daio_mgr_create, |
9173 |
-- .destroy = (destroy_t)daio_mgr_destroy } |
9174 |
-+ [SRC] = { .create = src_mgr_create, |
9175 |
-+ .destroy = src_mgr_destroy }, |
9176 |
-+ [SRCIMP] = { .create = srcimp_mgr_create, |
9177 |
-+ .destroy = srcimp_mgr_destroy }, |
9178 |
-+ [AMIXER] = { .create = amixer_mgr_create, |
9179 |
-+ .destroy = amixer_mgr_destroy }, |
9180 |
-+ [SUM] = { .create = sum_mgr_create, |
9181 |
-+ .destroy = sum_mgr_destroy }, |
9182 |
-+ [DAIO] = { .create = daio_mgr_create, |
9183 |
-+ .destroy = daio_mgr_destroy } |
9184 |
- }; |
9185 |
- |
9186 |
- static int |
9187 |
-diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c |
9188 |
-index 7f089cb..6bea28e 100644 |
9189 |
---- a/sound/pci/ctxfi/ctdaio.c |
9190 |
-+++ b/sound/pci/ctxfi/ctdaio.c |
9191 |
-@@ -687,8 +687,9 @@ static int daio_mgr_commit_write(struct daio_mgr *mgr) |
9192 |
- return 0; |
9193 |
- } |
9194 |
- |
9195 |
--int daio_mgr_create(struct hw *hw, struct daio_mgr **rdaio_mgr) |
9196 |
-+int daio_mgr_create(struct hw *hw, void **_rdaio_mgr) |
9197 |
- { |
9198 |
-+ struct daio_mgr **rdaio_mgr = (struct daio_mgr **)_rdaio_mgr; |
9199 |
- int err, i; |
9200 |
- struct daio_mgr *daio_mgr; |
9201 |
- struct imapper *entry; |
9202 |
-@@ -741,8 +742,9 @@ error1: |
9203 |
- return err; |
9204 |
- } |
9205 |
- |
9206 |
--int daio_mgr_destroy(struct daio_mgr *daio_mgr) |
9207 |
-+int daio_mgr_destroy(void *_daio_mgr) |
9208 |
- { |
9209 |
-+ struct daio_mgr *daio_mgr = _daio_mgr; |
9210 |
- unsigned long flags; |
9211 |
- |
9212 |
- /* free daio input mapper list */ |
9213 |
-diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h |
9214 |
-index a30be73..91b8dbd 100644 |
9215 |
---- a/sound/pci/ctxfi/ctdaio.h |
9216 |
-+++ b/sound/pci/ctxfi/ctdaio.h |
9217 |
-@@ -119,7 +119,7 @@ struct daio_mgr { |
9218 |
- }; |
9219 |
- |
9220 |
- /* Constructor and destructor of daio resource manager */ |
9221 |
--int daio_mgr_create(struct hw *hw, struct daio_mgr **rdaio_mgr); |
9222 |
--int daio_mgr_destroy(struct daio_mgr *daio_mgr); |
9223 |
-+int daio_mgr_create(struct hw *hw, void **rdaio_mgr); |
9224 |
-+int daio_mgr_destroy(void *daio_mgr); |
9225 |
- |
9226 |
- #endif /* CTDAIO_H */ |
9227 |
-diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c |
9228 |
-index a5a72df..f86edb8 100644 |
9229 |
---- a/sound/pci/ctxfi/ctsrc.c |
9230 |
-+++ b/sound/pci/ctxfi/ctsrc.c |
9231 |
-@@ -544,8 +544,9 @@ static int src_mgr_commit_write(struct src_mgr *mgr) |
9232 |
- return 0; |
9233 |
- } |
9234 |
- |
9235 |
--int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr) |
9236 |
-+int src_mgr_create(struct hw *hw, void **_rsrc_mgr) |
9237 |
- { |
9238 |
-+ struct src_mgr **rsrc_mgr = (struct src_mgr **)_rsrc_mgr; |
9239 |
- int err, i; |
9240 |
- struct src_mgr *src_mgr; |
9241 |
- |
9242 |
-@@ -584,8 +585,10 @@ error1: |
9243 |
- return err; |
9244 |
- } |
9245 |
- |
9246 |
--int src_mgr_destroy(struct src_mgr *src_mgr) |
9247 |
-+int src_mgr_destroy(void *_src_mgr) |
9248 |
- { |
9249 |
-+ struct src_mgr *src_mgr = _src_mgr; |
9250 |
-+ |
9251 |
- rsc_mgr_uninit(&src_mgr->mgr); |
9252 |
- kfree(src_mgr); |
9253 |
- |
9254 |
-@@ -828,8 +831,9 @@ static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) |
9255 |
- return err; |
9256 |
- } |
9257 |
- |
9258 |
--int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrcimp_mgr) |
9259 |
-+int srcimp_mgr_create(struct hw *hw, void **_rsrcimp_mgr) |
9260 |
- { |
9261 |
-+ struct srcimp_mgr **rsrcimp_mgr = (struct srcimp_mgr **)_rsrcimp_mgr; |
9262 |
- int err; |
9263 |
- struct srcimp_mgr *srcimp_mgr; |
9264 |
- struct imapper *entry; |
9265 |
-@@ -873,8 +877,9 @@ error1: |
9266 |
- return err; |
9267 |
- } |
9268 |
- |
9269 |
--int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr) |
9270 |
-+int srcimp_mgr_destroy(void *_srcimp_mgr) |
9271 |
- { |
9272 |
-+ struct srcimp_mgr *srcimp_mgr = _srcimp_mgr; |
9273 |
- unsigned long flags; |
9274 |
- |
9275 |
- /* free src input mapper list */ |
9276 |
-diff --git a/sound/pci/ctxfi/ctsrc.h b/sound/pci/ctxfi/ctsrc.h |
9277 |
-index 92944a0..fc78ed4 100644 |
9278 |
---- a/sound/pci/ctxfi/ctsrc.h |
9279 |
-+++ b/sound/pci/ctxfi/ctsrc.h |
9280 |
-@@ -143,10 +143,10 @@ struct srcimp_mgr { |
9281 |
- }; |
9282 |
- |
9283 |
- /* Constructor and destructor of SRC resource manager */ |
9284 |
--int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr); |
9285 |
--int src_mgr_destroy(struct src_mgr *src_mgr); |
9286 |
-+int src_mgr_create(struct hw *hw, void **rsrc_mgr); |
9287 |
-+int src_mgr_destroy(void *src_mgr); |
9288 |
- /* Constructor and destructor of SRCIMP resource manager */ |
9289 |
--int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrc_mgr); |
9290 |
--int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr); |
9291 |
-+int srcimp_mgr_create(struct hw *hw, void **rsrc_mgr); |
9292 |
-+int srcimp_mgr_destroy(void *srcimp_mgr); |
9293 |
- |
9294 |
- #endif /* CTSRC_H */ |
9295 |
-diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c |
9296 |
-index 8374188..f073778 100644 |
9297 |
---- a/sound/pci/hda/hda_codec.c |
9298 |
-+++ b/sound/pci/hda/hda_codec.c |
9299 |
-@@ -1743,7 +1743,7 @@ static int get_kctl_0dB_offset(struct hda_codec *codec, |
9300 |
- /* FIXME: set_fs() hack for obtaining user-space TLV data */ |
9301 |
- mm_segment_t fs = get_fs(); |
9302 |
- set_fs(get_ds()); |
9303 |
-- if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv)) |
9304 |
-+ if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), (unsigned int __force_user *)_tlv)) |
9305 |
- tlv = _tlv; |
9306 |
- set_fs(fs); |
9307 |
- } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) |
9308 |
-diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h |
9309 |
-index 149d4cb..7784769 100644 |
9310 |
---- a/sound/pci/ymfpci/ymfpci.h |
9311 |
-+++ b/sound/pci/ymfpci/ymfpci.h |
9312 |
-@@ -358,7 +358,7 @@ struct snd_ymfpci { |
9313 |
- spinlock_t reg_lock; |
9314 |
- spinlock_t voice_lock; |
9315 |
- wait_queue_head_t interrupt_sleep; |
9316 |
-- atomic_t interrupt_sleep_count; |
9317 |
-+ atomic_unchecked_t interrupt_sleep_count; |
9318 |
- struct snd_info_entry *proc_entry; |
9319 |
- const struct firmware *dsp_microcode; |
9320 |
- const struct firmware *controller_microcode; |
9321 |
-diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c |
9322 |
-index 4c26076..a13f370 100644 |
9323 |
---- a/sound/pci/ymfpci/ymfpci_main.c |
9324 |
-+++ b/sound/pci/ymfpci/ymfpci_main.c |
9325 |
-@@ -204,8 +204,8 @@ static void snd_ymfpci_hw_stop(struct snd_ymfpci *chip) |
9326 |
- if ((snd_ymfpci_readl(chip, YDSXGR_STATUS) & 2) == 0) |
9327 |
- break; |
9328 |
- } |
9329 |
-- if (atomic_read(&chip->interrupt_sleep_count)) { |
9330 |
-- atomic_set(&chip->interrupt_sleep_count, 0); |
9331 |
-+ if (atomic_read_unchecked(&chip->interrupt_sleep_count)) { |
9332 |
-+ atomic_set_unchecked(&chip->interrupt_sleep_count, 0); |
9333 |
- wake_up(&chip->interrupt_sleep); |
9334 |
- } |
9335 |
- __end: |
9336 |
-@@ -789,7 +789,7 @@ static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip) |
9337 |
- continue; |
9338 |
- init_waitqueue_entry(&wait, current); |
9339 |
- add_wait_queue(&chip->interrupt_sleep, &wait); |
9340 |
-- atomic_inc(&chip->interrupt_sleep_count); |
9341 |
-+ atomic_inc_unchecked(&chip->interrupt_sleep_count); |
9342 |
- schedule_timeout_uninterruptible(msecs_to_jiffies(50)); |
9343 |
- remove_wait_queue(&chip->interrupt_sleep, &wait); |
9344 |
- } |
9345 |
-@@ -827,8 +827,8 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id) |
9346 |
- snd_ymfpci_writel(chip, YDSXGR_MODE, mode); |
9347 |
- spin_unlock(&chip->reg_lock); |
9348 |
- |
9349 |
-- if (atomic_read(&chip->interrupt_sleep_count)) { |
9350 |
-- atomic_set(&chip->interrupt_sleep_count, 0); |
9351 |
-+ if (atomic_read_unchecked(&chip->interrupt_sleep_count)) { |
9352 |
-+ atomic_set_unchecked(&chip->interrupt_sleep_count, 0); |
9353 |
- wake_up(&chip->interrupt_sleep); |
9354 |
- } |
9355 |
- } |
9356 |
-@@ -2384,7 +2384,7 @@ int snd_ymfpci_create(struct snd_card *card, |
9357 |
- spin_lock_init(&chip->reg_lock); |
9358 |
- spin_lock_init(&chip->voice_lock); |
9359 |
- init_waitqueue_head(&chip->interrupt_sleep); |
9360 |
-- atomic_set(&chip->interrupt_sleep_count, 0); |
9361 |
-+ atomic_set_unchecked(&chip->interrupt_sleep_count, 0); |
9362 |
- chip->card = card; |
9363 |
- chip->pci = pci; |
9364 |
- chip->irq = -1; |
9365 |
-diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c |
9366 |
-index d6f4abb..5d59f0c 100644 |
9367 |
---- a/sound/soc/codecs/cx20442.c |
9368 |
-+++ b/sound/soc/codecs/cx20442.c |
9369 |
-@@ -263,6 +263,12 @@ static int v253_hangup(struct tty_struct *tty) |
9370 |
- return 0; |
9371 |
- } |
9372 |
- |
9373 |
-+static int v253_hw_write(void *client, const char *buf, int count) |
9374 |
-+{ |
9375 |
-+ struct tty_struct *tty = client; |
9376 |
-+ return tty->ops->write(client, buf, count); |
9377 |
-+} |
9378 |
-+ |
9379 |
- /* Line discipline .receive_buf() */ |
9380 |
- static void v253_receive(struct tty_struct *tty, |
9381 |
- const unsigned char *cp, char *fp, int count) |
9382 |
-@@ -280,7 +286,7 @@ static void v253_receive(struct tty_struct *tty, |
9383 |
- |
9384 |
- /* Set up codec driver access to modem controls */ |
9385 |
- cx20442->control_data = tty; |
9386 |
-- codec->hw_write = (hw_write_t)tty->ops->write; |
9387 |
-+ codec->hw_write = v253_hw_write; |
9388 |
- codec->component.card->pop_time = 1; |
9389 |
- } |
9390 |
- } |
9391 |
-diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c |
9392 |
-index 160d61a..10bfd63 100644 |
9393 |
---- a/sound/soc/codecs/sti-sas.c |
9394 |
-+++ b/sound/soc/codecs/sti-sas.c |
9395 |
-@@ -591,11 +591,13 @@ static int sti_sas_driver_probe(struct platform_device *pdev) |
9396 |
- sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; |
9397 |
- |
9398 |
- /* Set dapms*/ |
9399 |
-- sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; |
9400 |
-- sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; |
9401 |
-+ pax_open_kernel(); |
9402 |
-+ *(const void **)&sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; |
9403 |
-+ *(int *)&sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; |
9404 |
- |
9405 |
-- sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes; |
9406 |
-- sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; |
9407 |
-+ *(const void **)&sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes; |
9408 |
-+ *(int *)&sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; |
9409 |
-+ pax_close_kernel(); |
9410 |
- |
9411 |
- /* Store context */ |
9412 |
- dev_set_drvdata(&pdev->dev, drvdata); |
9413 |
-diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c |
9414 |
-index f7a6ce7..82310c8 100644 |
9415 |
---- a/sound/soc/codecs/tlv320dac33.c |
9416 |
-+++ b/sound/soc/codecs/tlv320dac33.c |
9417 |
-@@ -1375,13 +1375,18 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai, |
9418 |
- return 0; |
9419 |
- } |
9420 |
- |
9421 |
-+static int dac33_hw_write(void *client, const char *buf, int count) |
9422 |
-+{ |
9423 |
-+ return i2c_master_send(client, buf, count); |
9424 |
-+} |
9425 |
-+ |
9426 |
- static int dac33_soc_probe(struct snd_soc_codec *codec) |
9427 |
- { |
9428 |
- struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
9429 |
- int ret = 0; |
9430 |
- |
9431 |
- codec->control_data = dac33->control_data; |
9432 |
-- codec->hw_write = (hw_write_t) i2c_master_send; |
9433 |
-+ codec->hw_write = dac33_hw_write; |
9434 |
- dac33->codec = codec; |
9435 |
- |
9436 |
- /* Read the tlv320dac33 ID registers */ |
9437 |
-diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c |
9438 |
-index 35f0469..7c25cd5 100644 |
9439 |
---- a/sound/soc/codecs/uda1380.c |
9440 |
-+++ b/sound/soc/codecs/uda1380.c |
9441 |
-@@ -687,6 +687,11 @@ static struct snd_soc_dai_driver uda1380_dai[] = { |
9442 |
- }, |
9443 |
- }; |
9444 |
- |
9445 |
-+static int uda1380_hw_write(void *client, const char *buf, int count) |
9446 |
-+{ |
9447 |
-+ return i2c_master_send(client, buf, count); |
9448 |
-+} |
9449 |
-+ |
9450 |
- static int uda1380_probe(struct snd_soc_codec *codec) |
9451 |
- { |
9452 |
- struct uda1380_platform_data *pdata =codec->dev->platform_data; |
9453 |
-@@ -695,7 +700,7 @@ static int uda1380_probe(struct snd_soc_codec *codec) |
9454 |
- |
9455 |
- uda1380->codec = codec; |
9456 |
- |
9457 |
-- codec->hw_write = (hw_write_t)i2c_master_send; |
9458 |
-+ codec->hw_write = uda1380_hw_write; |
9459 |
- codec->control_data = uda1380->control_data; |
9460 |
- |
9461 |
- if (!pdata) |
9462 |
-diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h |
9463 |
-index cbb4075..edda3dd 100644 |
9464 |
---- a/sound/soc/intel/skylake/skl-sst-dsp.h |
9465 |
-+++ b/sound/soc/intel/skylake/skl-sst-dsp.h |
9466 |
-@@ -117,14 +117,14 @@ struct skl_dsp_fw_ops { |
9467 |
- int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, char *mod_name); |
9468 |
- int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); |
9469 |
- |
9470 |
--}; |
9471 |
-+} __no_const; |
9472 |
- |
9473 |
- struct skl_dsp_loader_ops { |
9474 |
- int (*alloc_dma_buf)(struct device *dev, |
9475 |
- struct snd_dma_buffer *dmab, size_t size); |
9476 |
- int (*free_dma_buf)(struct device *dev, |
9477 |
- struct snd_dma_buffer *dmab); |
9478 |
--}; |
9479 |
-+} __no_const; |
9480 |
- |
9481 |
- struct skl_load_module_info { |
9482 |
- u16 mod_id; |
9483 |
-diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c |
9484 |
-index 7e0acd8..7fe0f65 100644 |
9485 |
---- a/sound/soc/soc-ac97.c |
9486 |
-+++ b/sound/soc/soc-ac97.c |
9487 |
-@@ -416,8 +416,10 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, |
9488 |
- if (ret) |
9489 |
- return ret; |
9490 |
- |
9491 |
-- ops->warm_reset = snd_soc_ac97_warm_reset; |
9492 |
-- ops->reset = snd_soc_ac97_reset; |
9493 |
-+ pax_open_kernel(); |
9494 |
-+ *(void **)&ops->warm_reset = snd_soc_ac97_warm_reset; |
9495 |
-+ *(void **)&ops->reset = snd_soc_ac97_reset; |
9496 |
-+ pax_close_kernel(); |
9497 |
- |
9498 |
- snd_ac97_rst_cfg = cfg; |
9499 |
- return 0; |
9500 |
-diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c |
9501 |
-index 8382ffa..86af7d0 100644 |
9502 |
---- a/sound/soc/xtensa/xtfpga-i2s.c |
9503 |
-+++ b/sound/soc/xtensa/xtfpga-i2s.c |
9504 |
-@@ -437,7 +437,7 @@ static int xtfpga_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
9505 |
- case SNDRV_PCM_TRIGGER_START: |
9506 |
- case SNDRV_PCM_TRIGGER_RESUME: |
9507 |
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
9508 |
-- ACCESS_ONCE(i2s->tx_ptr) = 0; |
9509 |
-+ ACCESS_ONCE_RW(i2s->tx_ptr) = 0; |
9510 |
- rcu_assign_pointer(i2s->tx_substream, substream); |
9511 |
- xtfpga_pcm_refill_fifo(i2s); |
9512 |
- break; |
9513 |
-diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c |
9514 |
-index a020920..55579f6 100644 |
9515 |
---- a/sound/synth/emux/emux_seq.c |
9516 |
-+++ b/sound/synth/emux/emux_seq.c |
9517 |
-@@ -33,13 +33,13 @@ static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *inf |
9518 |
- * MIDI emulation operators |
9519 |
- */ |
9520 |
- static struct snd_midi_op emux_ops = { |
9521 |
-- snd_emux_note_on, |
9522 |
-- snd_emux_note_off, |
9523 |
-- snd_emux_key_press, |
9524 |
-- snd_emux_terminate_note, |
9525 |
-- snd_emux_control, |
9526 |
-- snd_emux_nrpn, |
9527 |
-- snd_emux_sysex, |
9528 |
-+ .note_on = snd_emux_note_on, |
9529 |
-+ .note_off = snd_emux_note_off, |
9530 |
-+ .key_press = snd_emux_key_press, |
9531 |
-+ .note_terminate = snd_emux_terminate_note, |
9532 |
-+ .control = snd_emux_control, |
9533 |
-+ .nrpn = snd_emux_nrpn, |
9534 |
-+ .sysex = snd_emux_sysex, |
9535 |
- }; |
9536 |
- |
9537 |
- |
9538 |
-diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c |
9539 |
-index 81b7da8..bb2676f 100644 |
9540 |
---- a/sound/usb/line6/driver.c |
9541 |
-+++ b/sound/usb/line6/driver.c |
9542 |
-@@ -307,7 +307,7 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, |
9543 |
- { |
9544 |
- struct usb_device *usbdev = line6->usbdev; |
9545 |
- int ret; |
9546 |
-- unsigned char len; |
9547 |
-+ unsigned char *plen; |
9548 |
- unsigned count; |
9549 |
- |
9550 |
- if (address > 0xffff || datalen > 0xff) |
9551 |
-@@ -324,6 +324,10 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, |
9552 |
- return ret; |
9553 |
- } |
9554 |
- |
9555 |
-+ plen = kmalloc(1, GFP_KERNEL); |
9556 |
-+ if (plen == NULL) |
9557 |
-+ return -ENOMEM; |
9558 |
-+ |
9559 |
- /* Wait for data length. We'll get 0xff until length arrives. */ |
9560 |
- for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { |
9561 |
- mdelay(LINE6_READ_WRITE_STATUS_DELAY); |
9562 |
-@@ -331,30 +335,35 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, |
9563 |
- ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, |
9564 |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | |
9565 |
- USB_DIR_IN, |
9566 |
-- 0x0012, 0x0000, &len, 1, |
9567 |
-+ 0x0012, 0x0000, plen, 1, |
9568 |
- LINE6_TIMEOUT * HZ); |
9569 |
- if (ret < 0) { |
9570 |
- dev_err(line6->ifcdev, |
9571 |
- "receive length failed (error %d)\n", ret); |
9572 |
-+ kfree(plen); |
9573 |
- return ret; |
9574 |
- } |
9575 |
- |
9576 |
-- if (len != 0xff) |
9577 |
-+ if (*plen != 0xff) |
9578 |
- break; |
9579 |
- } |
9580 |
- |
9581 |
-- if (len == 0xff) { |
9582 |
-+ if (*plen == 0xff) { |
9583 |
- dev_err(line6->ifcdev, "read failed after %d retries\n", |
9584 |
- count); |
9585 |
-+ kfree(plen); |
9586 |
- return -EIO; |
9587 |
-- } else if (len != datalen) { |
9588 |
-+ } else if (*plen != datalen) { |
9589 |
- /* should be equal or something went wrong */ |
9590 |
- dev_err(line6->ifcdev, |
9591 |
- "length mismatch (expected %d, got %d)\n", |
9592 |
-- (int)datalen, (int)len); |
9593 |
-+ (int)datalen, (int)*plen); |
9594 |
-+ kfree(plen); |
9595 |
- return -EIO; |
9596 |
- } |
9597 |
- |
9598 |
-+ kfree(plen); |
9599 |
-+ |
9600 |
- /* receive the result: */ |
9601 |
- ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, |
9602 |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
9603 |
-@@ -378,7 +387,7 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, |
9604 |
- { |
9605 |
- struct usb_device *usbdev = line6->usbdev; |
9606 |
- int ret; |
9607 |
-- unsigned char status; |
9608 |
-+ unsigned char *status; |
9609 |
- int count; |
9610 |
- |
9611 |
- if (address > 0xffff || datalen > 0xffff) |
9612 |
-@@ -395,6 +404,10 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, |
9613 |
- return ret; |
9614 |
- } |
9615 |
- |
9616 |
-+ status = kmalloc(1, GFP_KERNEL); |
9617 |
-+ if (status == NULL) |
9618 |
-+ return -ENOMEM; |
9619 |
-+ |
9620 |
- for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { |
9621 |
- mdelay(LINE6_READ_WRITE_STATUS_DELAY); |
9622 |
- |
9623 |
-@@ -403,27 +416,32 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, |
9624 |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | |
9625 |
- USB_DIR_IN, |
9626 |
- 0x0012, 0x0000, |
9627 |
-- &status, 1, LINE6_TIMEOUT * HZ); |
9628 |
-+ status, 1, LINE6_TIMEOUT * HZ); |
9629 |
- |
9630 |
- if (ret < 0) { |
9631 |
- dev_err(line6->ifcdev, |
9632 |
- "receiving status failed (error %d)\n", ret); |
9633 |
-+ kfree(status); |
9634 |
- return ret; |
9635 |
- } |
9636 |
- |
9637 |
-- if (status != 0xff) |
9638 |
-+ if (*status != 0xff) |
9639 |
- break; |
9640 |
- } |
9641 |
- |
9642 |
-- if (status == 0xff) { |
9643 |
-+ if (*status == 0xff) { |
9644 |
- dev_err(line6->ifcdev, "write failed after %d retries\n", |
9645 |
- count); |
9646 |
-+ kfree(status); |
9647 |
- return -EIO; |
9648 |
-- } else if (status != 0) { |
9649 |
-+ } else if (*status != 0) { |
9650 |
- dev_err(line6->ifcdev, "write failed (error %d)\n", ret); |
9651 |
-+ kfree(status); |
9652 |
- return -EIO; |
9653 |
- } |
9654 |
- |
9655 |
-+ kfree(status); |
9656 |
-+ |
9657 |
- return 0; |
9658 |
- } |
9659 |
- EXPORT_SYMBOL_GPL(line6_write_data); |
9660 |
-diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c |
9661 |
-index 6d4c50c..aa658c8 100644 |
9662 |
---- a/sound/usb/line6/toneport.c |
9663 |
-+++ b/sound/usb/line6/toneport.c |
9664 |
-@@ -367,13 +367,19 @@ static bool toneport_has_source_select(struct usb_line6_toneport *toneport) |
9665 |
- */ |
9666 |
- static void toneport_setup(struct usb_line6_toneport *toneport) |
9667 |
- { |
9668 |
-- int ticks; |
9669 |
-+ int *ticks; |
9670 |
- struct usb_line6 *line6 = &toneport->line6; |
9671 |
- struct usb_device *usbdev = line6->usbdev; |
9672 |
- |
9673 |
-+ ticks = kmalloc(sizeof(int), GFP_KERNEL); |
9674 |
-+ if (ticks == NULL) |
9675 |
-+ return; |
9676 |
-+ |
9677 |
- /* sync time on device with host: */ |
9678 |
-- ticks = (int)get_seconds(); |
9679 |
-- line6_write_data(line6, 0x80c6, &ticks, 4); |
9680 |
-+ *ticks = (int)get_seconds(); |
9681 |
-+ line6_write_data(line6, 0x80c6, ticks, sizeof(int)); |
9682 |
-+ |
9683 |
-+ kfree(ticks); |
9684 |
- |
9685 |
- /* enable device: */ |
9686 |
- toneport_send_cmd(usbdev, 0x0301, 0x0000); |
9687 |
-diff --git a/tools/gcc/.gitignore b/tools/gcc/.gitignore |
9688 |
-new file mode 100644 |
9689 |
-index 0000000..de92ed9 |
9690 |
---- /dev/null |
9691 |
-+++ b/tools/gcc/.gitignore |
9692 |
-@@ -0,0 +1 @@ |
9693 |
-+randomize_layout_seed.h |
9694 |
-diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile |
9695 |
-new file mode 100644 |
9696 |
-index 0000000..f1db084 |
9697 |
---- /dev/null |
9698 |
-+++ b/tools/gcc/Makefile |
9699 |
-@@ -0,0 +1,58 @@ |
9700 |
-+#CC := gcc |
9701 |
-+#PLUGIN_SOURCE_FILES := pax_plugin.c |
9702 |
-+#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES)) |
9703 |
-+GCCPLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) |
9704 |
-+#CFLAGS += -I$(GCCPLUGINS_DIR)/include -fPIC -O2 -Wall -W -std=gnu99 |
9705 |
-+ |
9706 |
-+ifeq ($(PLUGINCC),$(HOSTCC)) |
9707 |
-+HOSTLIBS := hostlibs |
9708 |
-+HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(src) -std=gnu99 -ggdb -Wall -W |
9709 |
-+export HOST_EXTRACFLAGS |
9710 |
-+else |
9711 |
-+HOSTLIBS := hostcxxlibs |
9712 |
-+HOST_EXTRACXXFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti -fno-exceptions -fasynchronous-unwind-tables -ggdb -Wall -W -Wno-unused-parameter -Wno-narrowing -Wno-unused-variable |
9713 |
-+export HOST_EXTRACXXFLAGS |
9714 |
-+endif |
9715 |
-+ |
9716 |
-+export GCCPLUGINS_DIR HOSTLIBS |
9717 |
-+ |
9718 |
-+$(HOSTLIBS)-$(CONFIG_PAX_CONSTIFY_PLUGIN) := constify_plugin.so |
9719 |
-+$(HOSTLIBS)-$(CONFIG_PAX_MEMORY_STACKLEAK) += stackleak_plugin.so |
9720 |
-+$(HOSTLIBS)-$(CONFIG_KALLOCSTAT_PLUGIN) += kallocstat_plugin.so |
9721 |
-+$(HOSTLIBS)-$(CONFIG_PAX_KERNEXEC_PLUGIN) += kernexec_plugin.so |
9722 |
-+$(HOSTLIBS)-$(CONFIG_CHECKER_PLUGIN) += checker_plugin.so |
9723 |
-+$(HOSTLIBS)-y += colorize_plugin.so |
9724 |
-+$(HOSTLIBS)-$(CONFIG_PAX_LATENT_ENTROPY) += latent_entropy_plugin.so |
9725 |
-+$(HOSTLIBS)-$(CONFIG_PAX_MEMORY_STRUCTLEAK) += structleak_plugin.so |
9726 |
-+$(HOSTLIBS)-y += initify_plugin.so |
9727 |
-+$(HOSTLIBS)-$(CONFIG_GRKERNSEC_RANDSTRUCT) += randomize_layout_plugin.so |
9728 |
-+ |
9729 |
-+subdir-$(CONFIG_PAX_SIZE_OVERFLOW) := size_overflow_plugin |
9730 |
-+subdir- += size_overflow_plugin |
9731 |
-+ |
9732 |
-+subdir-$(CONFIG_PAX_RAP) += rap_plugin |
9733 |
-+subdir- += rap_plugin |
9734 |
-+ |
9735 |
-+always := $($(HOSTLIBS)-y) |
9736 |
-+ |
9737 |
-+constify_plugin-objs := constify_plugin.o |
9738 |
-+stackleak_plugin-objs := stackleak_plugin.o |
9739 |
-+kallocstat_plugin-objs := kallocstat_plugin.o |
9740 |
-+kernexec_plugin-objs := kernexec_plugin.o |
9741 |
-+checker_plugin-objs := checker_plugin.o |
9742 |
-+colorize_plugin-objs := colorize_plugin.o |
9743 |
-+latent_entropy_plugin-objs := latent_entropy_plugin.o |
9744 |
-+structleak_plugin-objs := structleak_plugin.o |
9745 |
-+initify_plugin-objs := initify_plugin.o |
9746 |
-+rap_plugin-objs := rap_plugin.o sip.o |
9747 |
-+randomize_layout_plugin-objs := randomize_layout_plugin.o |
9748 |
-+ |
9749 |
-+$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h |
9750 |
-+ |
9751 |
-+quiet_cmd_create_randomize_layout_seed = GENSEED $@ |
9752 |
-+ cmd_create_randomize_layout_seed = \ |
9753 |
-+ $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h |
9754 |
-+$(objtree)/$(obj)/randomize_layout_seed.h: FORCE |
9755 |
-+ $(call if_changed,create_randomize_layout_seed) |
9756 |
-+ |
9757 |
-+targets += randomize_layout_seed.h randomize_layout_hash.h |
9758 |
-diff --git a/tools/gcc/checker_plugin.c b/tools/gcc/checker_plugin.c |
9759 |
-new file mode 100644 |
9760 |
-index 0000000..efaf576 |
9761 |
---- /dev/null |
9762 |
-+++ b/tools/gcc/checker_plugin.c |
9763 |
-@@ -0,0 +1,496 @@ |
9764 |
-+/* |
9765 |
-+ * Copyright 2011-2016 by the PaX Team <pageexec@××××××××.hu> |
9766 |
-+ * Licensed under the GPL v2 |
9767 |
-+ * |
9768 |
-+ * Note: the choice of the license means that the compilation process is |
9769 |
-+ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
9770 |
-+ * but for the kernel it doesn't matter since it doesn't link against |
9771 |
-+ * any of the gcc libraries |
9772 |
-+ * |
9773 |
-+ * gcc plugin to implement various sparse (source code checker) features |
9774 |
-+ * |
9775 |
-+ * TODO: |
9776 |
-+ * - define separate __iomem, __percpu and __rcu address spaces (lots of code to patch) |
9777 |
-+ * |
9778 |
-+ * BUGS: |
9779 |
-+ * - none known |
9780 |
-+ */ |
9781 |
-+ |
9782 |
-+#include "gcc-common.h" |
9783 |
-+ |
9784 |
-+extern void c_register_addr_space (const char *str, addr_space_t as); |
9785 |
-+extern enum machine_mode default_addr_space_pointer_mode (addr_space_t); |
9786 |
-+extern enum machine_mode default_addr_space_address_mode (addr_space_t); |
9787 |
-+extern bool default_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as); |
9788 |
-+extern bool default_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as); |
9789 |
-+extern rtx default_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as); |
9790 |
-+ |
9791 |
-+int plugin_is_GPL_compatible; |
9792 |
-+ |
9793 |
-+static struct plugin_info checker_plugin_info = { |
9794 |
-+ .version = "201602181345", |
9795 |
-+ .help = "user\tturn on user/kernel address space checking\n" |
9796 |
-+ "context\tturn on locking context checking\n" |
9797 |
-+}; |
9798 |
-+ |
9799 |
-+#define ADDR_SPACE_KERNEL 0 |
9800 |
-+#define ADDR_SPACE_FORCE_KERNEL 1 |
9801 |
-+#define ADDR_SPACE_USER 2 |
9802 |
-+#define ADDR_SPACE_FORCE_USER 3 |
9803 |
-+#define ADDR_SPACE_IOMEM 0 |
9804 |
-+#define ADDR_SPACE_FORCE_IOMEM 0 |
9805 |
-+#define ADDR_SPACE_PERCPU 0 |
9806 |
-+#define ADDR_SPACE_FORCE_PERCPU 0 |
9807 |
-+#define ADDR_SPACE_RCU 0 |
9808 |
-+#define ADDR_SPACE_FORCE_RCU 0 |
9809 |
-+ |
9810 |
-+static enum machine_mode checker_addr_space_pointer_mode(addr_space_t addrspace) |
9811 |
-+{ |
9812 |
-+ return default_addr_space_pointer_mode(ADDR_SPACE_GENERIC); |
9813 |
-+} |
9814 |
-+ |
9815 |
-+static enum machine_mode checker_addr_space_address_mode(addr_space_t addrspace) |
9816 |
-+{ |
9817 |
-+ return default_addr_space_address_mode(ADDR_SPACE_GENERIC); |
9818 |
-+} |
9819 |
-+ |
9820 |
-+static bool checker_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as) |
9821 |
-+{ |
9822 |
-+ return default_addr_space_valid_pointer_mode(mode, as); |
9823 |
-+} |
9824 |
-+ |
9825 |
-+static bool checker_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as) |
9826 |
-+{ |
9827 |
-+ return default_addr_space_legitimate_address_p(mode, mem, strict, ADDR_SPACE_GENERIC); |
9828 |
-+} |
9829 |
-+ |
9830 |
-+static rtx checker_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as) |
9831 |
-+{ |
9832 |
-+ return default_addr_space_legitimize_address(x, oldx, mode, as); |
9833 |
-+} |
9834 |
-+ |
9835 |
-+static bool checker_addr_space_subset_p(addr_space_t subset, addr_space_t superset) |
9836 |
-+{ |
9837 |
-+ if (subset == ADDR_SPACE_FORCE_KERNEL && superset == ADDR_SPACE_KERNEL) |
9838 |
-+ return true; |
9839 |
-+ |
9840 |
-+ if (subset == ADDR_SPACE_FORCE_USER && superset == ADDR_SPACE_USER) |
9841 |
-+ return true; |
9842 |
-+ |
9843 |
-+ if (subset == ADDR_SPACE_FORCE_IOMEM && superset == ADDR_SPACE_IOMEM) |
9844 |
-+ return true; |
9845 |
-+ |
9846 |
-+ if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_USER) |
9847 |
-+ return true; |
9848 |
-+ |
9849 |
-+ if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_IOMEM) |
9850 |
-+ return true; |
9851 |
-+ |
9852 |
-+ if (subset == ADDR_SPACE_USER && superset == ADDR_SPACE_FORCE_KERNEL) |
9853 |
-+ return true; |
9854 |
-+ |
9855 |
-+ if (subset == ADDR_SPACE_IOMEM && superset == ADDR_SPACE_FORCE_KERNEL) |
9856 |
-+ return true; |
9857 |
-+ |
9858 |
-+ return subset == superset; |
9859 |
-+} |
9860 |
-+ |
9861 |
-+static rtx checker_addr_space_convert(rtx op, tree from_type, tree to_type) |
9862 |
-+{ |
9863 |
-+// addr_space_t from_as = TYPE_ADDR_SPACE(TREE_TYPE(from_type)); |
9864 |
-+// addr_space_t to_as = TYPE_ADDR_SPACE(TREE_TYPE(to_type)); |
9865 |
-+ |
9866 |
-+ return op; |
9867 |
-+} |
9868 |
-+ |
9869 |
-+static void register_checker_address_spaces(void *event_data, void *data) |
9870 |
-+{ |
9871 |
-+ c_register_addr_space("__kernel", ADDR_SPACE_KERNEL); |
9872 |
-+ c_register_addr_space("__force_kernel", ADDR_SPACE_FORCE_KERNEL); |
9873 |
-+ c_register_addr_space("__user", ADDR_SPACE_USER); |
9874 |
-+ c_register_addr_space("__force_user", ADDR_SPACE_FORCE_USER); |
9875 |
-+// c_register_addr_space("__iomem", ADDR_SPACE_IOMEM); |
9876 |
-+// c_register_addr_space("__force_iomem", ADDR_SPACE_FORCE_IOMEM); |
9877 |
-+// c_register_addr_space("__percpu", ADDR_SPACE_PERCPU); |
9878 |
-+// c_register_addr_space("__force_percpu", ADDR_SPACE_FORCE_PERCPU); |
9879 |
-+// c_register_addr_space("__rcu", ADDR_SPACE_RCU); |
9880 |
-+// c_register_addr_space("__force_rcu", ADDR_SPACE_FORCE_RCU); |
9881 |
-+ |
9882 |
-+ targetm.addr_space.pointer_mode = checker_addr_space_pointer_mode; |
9883 |
-+ targetm.addr_space.address_mode = checker_addr_space_address_mode; |
9884 |
-+ targetm.addr_space.valid_pointer_mode = checker_addr_space_valid_pointer_mode; |
9885 |
-+ targetm.addr_space.legitimate_address_p = checker_addr_space_legitimate_address_p; |
9886 |
-+// targetm.addr_space.legitimize_address = checker_addr_space_legitimize_address; |
9887 |
-+ targetm.addr_space.subset_p = checker_addr_space_subset_p; |
9888 |
-+ targetm.addr_space.convert = checker_addr_space_convert; |
9889 |
-+} |
9890 |
-+ |
9891 |
-+static bool split_context_attribute(tree args, tree *lock, tree *in, tree *out) |
9892 |
-+{ |
9893 |
-+ *in = TREE_VALUE(args); |
9894 |
-+ |
9895 |
-+ if (TREE_CODE(*in) != INTEGER_CST) { |
9896 |
-+ *lock = *in; |
9897 |
-+ args = TREE_CHAIN(args); |
9898 |
-+ *in = TREE_VALUE(args); |
9899 |
-+ } else |
9900 |
-+ *lock = NULL_TREE; |
9901 |
-+ |
9902 |
-+ args = TREE_CHAIN(args); |
9903 |
-+ if (*lock && !args) |
9904 |
-+ return false; |
9905 |
-+ |
9906 |
-+ *out = TREE_VALUE(args); |
9907 |
-+ return true; |
9908 |
-+} |
9909 |
-+ |
9910 |
-+static tree handle_context_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
9911 |
-+{ |
9912 |
-+ *no_add_attrs = true; |
9913 |
-+ tree lock, in, out; |
9914 |
-+ |
9915 |
-+ if (TREE_CODE(*node) != FUNCTION_DECL) { |
9916 |
-+ error("%qE attribute applies to functions only (%qD)", name, *node); |
9917 |
-+ return NULL_TREE; |
9918 |
-+ } |
9919 |
-+ |
9920 |
-+ if (!split_context_attribute(args, &lock, &in, &out)) { |
9921 |
-+ error("%qE attribute needs two integers after the lock expression", name); |
9922 |
-+ return NULL_TREE; |
9923 |
-+ } |
9924 |
-+ |
9925 |
-+ if (TREE_CODE(in) != INTEGER_CST) { |
9926 |
-+ error("the 'in' argument of the %qE attribute must be an integer (%qE)", name, in); |
9927 |
-+ return NULL_TREE; |
9928 |
-+ } |
9929 |
-+ |
9930 |
-+ if (TREE_CODE(out) != INTEGER_CST) { |
9931 |
-+ error("the 'out' argument of the %qE attribute must be an integer (%qE)", name, out); |
9932 |
-+ return NULL_TREE; |
9933 |
-+ } |
9934 |
-+ |
9935 |
-+ *no_add_attrs = false; |
9936 |
-+ return NULL_TREE; |
9937 |
-+} |
9938 |
-+ |
9939 |
-+static struct attribute_spec context_attr = { |
9940 |
-+ .name = "context", |
9941 |
-+ .min_length = 2, |
9942 |
-+ .max_length = 3, |
9943 |
-+ .decl_required = true, |
9944 |
-+ .type_required = false, |
9945 |
-+ .function_type_required = false, |
9946 |
-+ .handler = handle_context_attribute, |
9947 |
-+#if BUILDING_GCC_VERSION >= 4007 |
9948 |
-+ .affects_type_identity = true |
9949 |
-+#endif |
9950 |
-+}; |
9951 |
-+ |
9952 |
-+static void register_attributes(void *event_data, void *data) |
9953 |
-+{ |
9954 |
-+ register_attribute(&context_attr); |
9955 |
-+} |
9956 |
-+ |
9957 |
-+static const char context_function[] = "__context__"; |
9958 |
-+static GTY(()) tree context_function_decl; |
9959 |
-+ |
9960 |
-+static const char context_error[] = "__context_error__"; |
9961 |
-+static GTY(()) tree context_error_decl; |
9962 |
-+ |
9963 |
-+static void context_start_unit(void __unused *gcc_data, void __unused *user_data) |
9964 |
-+{ |
9965 |
-+ tree fntype, attr; |
9966 |
-+ |
9967 |
-+ // void __context__(void *, int); |
9968 |
-+ fntype = build_function_type_list(void_type_node, ptr_type_node, integer_type_node, NULL_TREE); |
9969 |
-+ context_function_decl = build_fn_decl(context_function, fntype); |
9970 |
-+ |
9971 |
-+ TREE_PUBLIC(context_function_decl) = 1; |
9972 |
-+ TREE_USED(context_function_decl) = 1; |
9973 |
-+ DECL_EXTERNAL(context_function_decl) = 1; |
9974 |
-+ DECL_ARTIFICIAL(context_function_decl) = 1; |
9975 |
-+ DECL_PRESERVE_P(context_function_decl) = 1; |
9976 |
-+// TREE_NOTHROW(context_function_decl) = 1; |
9977 |
-+// DECL_UNINLINABLE(context_function_decl) = 1; |
9978 |
-+ DECL_ASSEMBLER_NAME(context_function_decl); // for LTO |
9979 |
-+ lang_hooks.decls.pushdecl(context_function_decl); |
9980 |
-+ |
9981 |
-+ // void __context_error__(const void *, int) __attribute__((error("context error"))); |
9982 |
-+ fntype = build_function_type_list(void_type_node, const_ptr_type_node, integer_type_node, NULL_TREE); |
9983 |
-+ context_error_decl = build_fn_decl(context_error, fntype); |
9984 |
-+ |
9985 |
-+ TREE_PUBLIC(context_error_decl) = 1; |
9986 |
-+ TREE_USED(context_error_decl) = 1; |
9987 |
-+ DECL_EXTERNAL(context_error_decl) = 1; |
9988 |
-+ DECL_ARTIFICIAL(context_error_decl) = 1; |
9989 |
-+ DECL_PRESERVE_P(context_error_decl) = 1; |
9990 |
-+// TREE_NOTHROW(context_error_decl) = 1; |
9991 |
-+// DECL_UNINLINABLE(context_error_decl) = 1; |
9992 |
-+ TREE_THIS_VOLATILE(context_error_decl) = 1; |
9993 |
-+ DECL_ASSEMBLER_NAME(context_error_decl); |
9994 |
-+ |
9995 |
-+ attr = tree_cons(NULL, build_string(14, "context error"), NULL); |
9996 |
-+ attr = tree_cons(get_identifier("error"), attr, NULL); |
9997 |
-+ decl_attributes(&context_error_decl, attr, 0); |
9998 |
-+} |
9999 |
-+ |
10000 |
-+static bool context_gate(void) |
10001 |
-+{ |
10002 |
-+ tree context_attr; |
10003 |
-+ |
10004 |
-+return true; |
10005 |
-+ |
10006 |
-+ context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl)); |
10007 |
-+ return context_attr != NULL_TREE; |
10008 |
-+} |
10009 |
-+ |
10010 |
-+static basic_block verify_context_before(gimple_stmt_iterator *gsi, tree context, tree inout, tree error) |
10011 |
-+{ |
10012 |
-+ gimple stmt; |
10013 |
-+ basic_block cond_bb, join_bb, true_bb; |
10014 |
-+ edge e; |
10015 |
-+ location_t loc; |
10016 |
-+ const char *file; |
10017 |
-+ int line; |
10018 |
-+ size_t len; |
10019 |
-+ tree filename; |
10020 |
-+ |
10021 |
-+ stmt = gsi_stmt(*gsi); |
10022 |
-+ if (gimple_has_location(stmt)) { |
10023 |
-+ loc = gimple_location(stmt); |
10024 |
-+ file = gimple_filename(stmt); |
10025 |
-+ line = gimple_lineno(stmt); |
10026 |
-+ } else { |
10027 |
-+ loc = DECL_SOURCE_LOCATION(current_function_decl); |
10028 |
-+ file = DECL_SOURCE_FILE(current_function_decl); |
10029 |
-+ line = DECL_SOURCE_LINE(current_function_decl); |
10030 |
-+ } |
10031 |
-+ gcc_assert(file); |
10032 |
-+ |
10033 |
-+ // if (context != count) __context_error__(__FILE__, __LINE__); |
10034 |
-+ stmt = gimple_build_cond(NE_EXPR, context, inout, NULL_TREE, NULL_TREE); |
10035 |
-+ gimple_set_location(stmt, loc); |
10036 |
-+ gsi_insert_before(gsi, stmt, GSI_NEW_STMT); |
10037 |
-+ |
10038 |
-+ cond_bb = gsi_bb(*gsi); |
10039 |
-+ gcc_assert(!gsi_end_p(*gsi)); |
10040 |
-+ gcc_assert(stmt == gsi_stmt(*gsi)); |
10041 |
-+ |
10042 |
-+ e = split_block(cond_bb, gsi_stmt(*gsi)); |
10043 |
-+ cond_bb = e->src; |
10044 |
-+ join_bb = e->dest; |
10045 |
-+ e->flags = EDGE_FALSE_VALUE; |
10046 |
-+ e->probability = REG_BR_PROB_BASE; |
10047 |
-+ |
10048 |
-+ true_bb = create_empty_bb(EXIT_BLOCK_PTR_FOR_FN(cfun)->prev_bb); |
10049 |
-+ make_edge(cond_bb, true_bb, EDGE_TRUE_VALUE); |
10050 |
-+ make_edge(true_bb, join_bb, EDGE_FALLTHRU); |
10051 |
-+ |
10052 |
-+ set_immediate_dominator(CDI_DOMINATORS, true_bb, cond_bb); |
10053 |
-+ set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb); |
10054 |
-+ |
10055 |
-+ gcc_assert(cond_bb->loop_father == join_bb->loop_father); |
10056 |
-+ add_bb_to_loop(true_bb, cond_bb->loop_father); |
10057 |
-+ |
10058 |
-+ // insert call to builtin_trap or __context_error__ |
10059 |
-+ *gsi = gsi_start_bb(true_bb); |
10060 |
-+ |
10061 |
-+// stmt = gimple_build_call(builtin_decl_implicit(BUILT_IN_TRAP), 0); |
10062 |
-+ len = strlen(file) + 1; |
10063 |
-+ filename = build_string(len, file); |
10064 |
-+ TREE_TYPE(filename) = build_array_type(unsigned_char_type_node, build_index_type(size_int(len))); |
10065 |
-+ filename = build1(ADDR_EXPR, const_ptr_type_node, filename); |
10066 |
-+ stmt = gimple_build_call(error, 2, filename, build_int_cst(NULL_TREE, line)); |
10067 |
-+ gimple_set_location(stmt, loc); |
10068 |
-+ gsi_insert_after(gsi, stmt, GSI_CONTINUE_LINKING); |
10069 |
-+ |
10070 |
-+ *gsi = gsi_start_nondebug_bb(join_bb); |
10071 |
-+ return join_bb; |
10072 |
-+} |
10073 |
-+ |
10074 |
-+static void update_context(gimple_stmt_iterator *gsi, tree context, int diff) |
10075 |
-+{ |
10076 |
-+ gimple assign; |
10077 |
-+ tree op; |
10078 |
-+ |
10079 |
-+ op = fold_build2_loc(UNKNOWN_LOCATION, PLUS_EXPR, integer_type_node, context, build_int_cst(integer_type_node, diff)); |
10080 |
-+ assign = gimple_build_assign(context, op); |
10081 |
-+ gsi_insert_after(gsi, assign, GSI_NEW_STMT); |
10082 |
-+ update_stmt(assign); |
10083 |
-+} |
10084 |
-+ |
10085 |
-+static basic_block track_context(basic_block bb, tree context) |
10086 |
-+{ |
10087 |
-+ gimple_stmt_iterator gsi; |
10088 |
-+ gimple assign; |
10089 |
-+ |
10090 |
-+ // adjust context according to the context information on any call stmt |
10091 |
-+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
10092 |
-+ gimple stmt = gsi_stmt(gsi); |
10093 |
-+ tree fndecl, context_attr; |
10094 |
-+ tree lock, in, out; |
10095 |
-+ int incount, outcount; |
10096 |
-+ |
10097 |
-+ if (!is_gimple_call(stmt)) |
10098 |
-+ continue; |
10099 |
-+ |
10100 |
-+ fndecl = gimple_call_fndecl(stmt); |
10101 |
-+ if (!fndecl) |
10102 |
-+ continue; |
10103 |
-+ |
10104 |
-+ if (fndecl == context_function_decl) { |
10105 |
-+ unsigned int num_ops = gimple_num_ops(stmt); |
10106 |
-+ int diff = tree_to_shwi(gimple_op(stmt, num_ops - 1)); |
10107 |
-+ |
10108 |
-+ gcc_assert(diff); |
10109 |
-+ update_context(&gsi, context, diff); |
10110 |
-+ continue; |
10111 |
-+ } |
10112 |
-+ |
10113 |
-+ context_attr = lookup_attribute("context", DECL_ATTRIBUTES(fndecl)); |
10114 |
-+ if (!context_attr) |
10115 |
-+ continue; |
10116 |
-+ |
10117 |
-+ gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out)); |
10118 |
-+ incount = tree_to_shwi(in); |
10119 |
-+ outcount = tree_to_shwi(out); |
10120 |
-+ bb = verify_context_before(&gsi, context, in, context_error_decl); |
10121 |
-+ update_context(&gsi, context, outcount - incount); |
10122 |
-+ } |
10123 |
-+ |
10124 |
-+ return bb; |
10125 |
-+} |
10126 |
-+ |
10127 |
-+static bool bb_any_loop(basic_block bb) |
10128 |
-+{ |
10129 |
-+ return bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP); |
10130 |
-+} |
10131 |
-+ |
10132 |
-+static unsigned int context_execute(void) |
10133 |
-+{ |
10134 |
-+ basic_block bb; |
10135 |
-+ gimple assign; |
10136 |
-+ gimple_stmt_iterator gsi; |
10137 |
-+ tree context_attr, context; |
10138 |
-+ tree lock, in, out; |
10139 |
-+ |
10140 |
-+ loop_optimizer_init(LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); |
10141 |
-+ gcc_assert(current_loops); |
10142 |
-+ |
10143 |
-+ calculate_dominance_info(CDI_DOMINATORS); |
10144 |
-+ calculate_dominance_info(CDI_POST_DOMINATORS); |
10145 |
-+ |
10146 |
-+ context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl)); |
10147 |
-+ if (context_attr) { |
10148 |
-+ gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out)); |
10149 |
-+ } else { |
10150 |
-+ in = out = integer_zero_node; |
10151 |
-+ } |
10152 |
-+ |
10153 |
-+ // 1. create local context variable |
10154 |
-+ context = create_tmp_var(integer_type_node, "context"); |
10155 |
-+ add_referenced_var(context); |
10156 |
-+ mark_sym_for_renaming(context); |
10157 |
-+ |
10158 |
-+ // 2. initialize local context variable |
10159 |
-+ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
10160 |
-+ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
10161 |
-+ if (!single_pred_p(bb)) { |
10162 |
-+ gcc_assert(bb_any_loop(bb)); |
10163 |
-+ split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
10164 |
-+ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
10165 |
-+ } |
10166 |
-+ gsi = gsi_start_bb(bb); |
10167 |
-+ assign = gimple_build_assign(context, in); |
10168 |
-+ gsi_insert_before(&gsi, assign, GSI_NEW_STMT); |
10169 |
-+ update_stmt(assign); |
10170 |
-+ |
10171 |
-+ // 3. instrument each BB to track the local context variable |
10172 |
-+ FOR_EACH_BB_FN(bb, cfun) { |
10173 |
-+ bb = track_context(bb, context); |
10174 |
-+ } |
10175 |
-+ |
10176 |
-+ // 4. verify the local context variable against the expected state |
10177 |
-+ if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds)) { |
10178 |
-+ gcc_assert(single_pred_p(EXIT_BLOCK_PTR_FOR_FN(cfun))); |
10179 |
-+ gsi = gsi_last_nondebug_bb(single_pred(EXIT_BLOCK_PTR_FOR_FN(cfun))); |
10180 |
-+ verify_context_before(&gsi, context, out, context_error_decl); |
10181 |
-+ } |
10182 |
-+ |
10183 |
-+ free_dominance_info(CDI_DOMINATORS); |
10184 |
-+ free_dominance_info(CDI_POST_DOMINATORS); |
10185 |
-+ loop_optimizer_finalize(); |
10186 |
-+ return 0; |
10187 |
-+} |
10188 |
-+ |
10189 |
-+#define PASS_NAME context |
10190 |
-+#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg |
10191 |
-+//#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts |
10192 |
-+#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_verify_flow | TODO_update_ssa |
10193 |
-+#include "gcc-generate-gimple-pass.h" |
10194 |
-+ |
10195 |
-+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
10196 |
-+{ |
10197 |
-+ const char * const plugin_name = plugin_info->base_name; |
10198 |
-+ const int argc = plugin_info->argc; |
10199 |
-+ const struct plugin_argument * const argv = plugin_info->argv; |
10200 |
-+ int i; |
10201 |
-+ bool enable_user, enable_context; |
10202 |
-+ struct register_pass_info context_pass_info; |
10203 |
-+ |
10204 |
-+ static const struct ggc_root_tab gt_ggc_r_gt_checker[] = { |
10205 |
-+ { |
10206 |
-+ .base = &context_function_decl, |
10207 |
-+ .nelt = 1, |
10208 |
-+ .stride = sizeof(context_function_decl), |
10209 |
-+ .cb = >_ggc_mx_tree_node, |
10210 |
-+ .pchw = >_pch_nx_tree_node |
10211 |
-+ }, |
10212 |
-+ { |
10213 |
-+ .base = &context_error_decl, |
10214 |
-+ .nelt = 1, |
10215 |
-+ .stride = sizeof(context_error_decl), |
10216 |
-+ .cb = >_ggc_mx_tree_node, |
10217 |
-+ .pchw = >_pch_nx_tree_node |
10218 |
-+ }, |
10219 |
-+ LAST_GGC_ROOT_TAB |
10220 |
-+ }; |
10221 |
-+ |
10222 |
-+ context_pass_info.pass = make_context_pass(); |
10223 |
-+// context_pass_info.reference_pass_name = "ssa"; |
10224 |
-+ context_pass_info.reference_pass_name = "phiprop"; |
10225 |
-+ context_pass_info.ref_pass_instance_number = 1; |
10226 |
-+ context_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
10227 |
-+ |
10228 |
-+ if (!plugin_default_version_check(version, &gcc_version)) { |
10229 |
-+ error(G_("incompatible gcc/plugin versions")); |
10230 |
-+ return 1; |
10231 |
-+ } |
10232 |
-+ |
10233 |
-+ register_callback(plugin_name, PLUGIN_INFO, NULL, &checker_plugin_info); |
10234 |
-+ |
10235 |
-+ enable_user = false; |
10236 |
-+ enable_context = false; |
10237 |
-+ for (i = 0; i < argc; ++i) { |
10238 |
-+ if (!strcmp(argv[i].key, "user")) { |
10239 |
-+ enable_user = true; |
10240 |
-+ continue; |
10241 |
-+ } |
10242 |
-+ if (!strcmp(argv[i].key, "context")) { |
10243 |
-+ enable_context = true; |
10244 |
-+ continue; |
10245 |
-+ } |
10246 |
-+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
10247 |
-+ } |
10248 |
-+ |
10249 |
-+ if (enable_user) |
10250 |
-+ register_callback(plugin_name, PLUGIN_PRAGMAS, register_checker_address_spaces, NULL); |
10251 |
-+ if (enable_context) { |
10252 |
-+ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
10253 |
-+ register_callback(plugin_name, PLUGIN_START_UNIT, context_start_unit, NULL); |
10254 |
-+ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_checker); |
10255 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &context_pass_info); |
10256 |
-+ } |
10257 |
-+ |
10258 |
-+ return 0; |
10259 |
-+} |
10260 |
-diff --git a/tools/gcc/colorize_plugin.c b/tools/gcc/colorize_plugin.c |
10261 |
-new file mode 100644 |
10262 |
-index 0000000..ffe60f6 |
10263 |
---- /dev/null |
10264 |
-+++ b/tools/gcc/colorize_plugin.c |
10265 |
-@@ -0,0 +1,162 @@ |
10266 |
-+/* |
10267 |
-+ * Copyright 2012-2016 by PaX Team <pageexec@××××××××.hu> |
10268 |
-+ * Licensed under the GPL v2 |
10269 |
-+ * |
10270 |
-+ * Note: the choice of the license means that the compilation process is |
10271 |
-+ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
10272 |
-+ * but for the kernel it doesn't matter since it doesn't link against |
10273 |
-+ * any of the gcc libraries |
10274 |
-+ * |
10275 |
-+ * gcc plugin to colorize diagnostic output |
10276 |
-+ * |
10277 |
-+ */ |
10278 |
-+ |
10279 |
-+#include "gcc-common.h" |
10280 |
-+ |
10281 |
-+int plugin_is_GPL_compatible; |
10282 |
-+ |
10283 |
-+static struct plugin_info colorize_plugin_info = { |
10284 |
-+ .version = "201602181345", |
10285 |
-+ .help = "color=[never|always|auto]\tdetermine when to colorize\n", |
10286 |
-+}; |
10287 |
-+ |
10288 |
-+#define GREEN "\033[32m\033[K" |
10289 |
-+#define LIGHTGREEN "\033[1;32m\033[K" |
10290 |
-+#define YELLOW "\033[33m\033[K" |
10291 |
-+#define LIGHTYELLOW "\033[1;33m\033[K" |
10292 |
-+#define RED "\033[31m\033[K" |
10293 |
-+#define LIGHTRED "\033[1;31m\033[K" |
10294 |
-+#define BLUE "\033[34m\033[K" |
10295 |
-+#define LIGHTBLUE "\033[1;34m\033[K" |
10296 |
-+#define BRIGHT "\033[1;m\033[K" |
10297 |
-+#define NORMAL "\033[m\033[K" |
10298 |
-+ |
10299 |
-+static diagnostic_starter_fn old_starter; |
10300 |
-+static diagnostic_finalizer_fn old_finalizer; |
10301 |
-+ |
10302 |
-+static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic) |
10303 |
-+{ |
10304 |
-+ const char *color; |
10305 |
-+ char *newprefix; |
10306 |
-+ |
10307 |
-+ switch (diagnostic->kind) { |
10308 |
-+ case DK_NOTE: |
10309 |
-+ color = LIGHTBLUE; |
10310 |
-+ break; |
10311 |
-+ |
10312 |
-+ case DK_PEDWARN: |
10313 |
-+ case DK_WARNING: |
10314 |
-+ color = LIGHTYELLOW; |
10315 |
-+ break; |
10316 |
-+ |
10317 |
-+ case DK_ERROR: |
10318 |
-+ case DK_FATAL: |
10319 |
-+ case DK_ICE: |
10320 |
-+ case DK_PERMERROR: |
10321 |
-+ case DK_SORRY: |
10322 |
-+ color = LIGHTRED; |
10323 |
-+ break; |
10324 |
-+ |
10325 |
-+ default: |
10326 |
-+ color = NORMAL; |
10327 |
-+ } |
10328 |
-+ |
10329 |
-+ old_starter(context, diagnostic); |
10330 |
-+ if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix)) |
10331 |
-+ return; |
10332 |
-+ pp_destroy_prefix(context->printer); |
10333 |
-+ pp_set_prefix(context->printer, newprefix); |
10334 |
-+} |
10335 |
-+ |
10336 |
-+static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic) |
10337 |
-+{ |
10338 |
-+ old_finalizer(context, diagnostic); |
10339 |
-+} |
10340 |
-+ |
10341 |
-+static void colorize_arm(void) |
10342 |
-+{ |
10343 |
-+ old_starter = diagnostic_starter(global_dc); |
10344 |
-+ old_finalizer = diagnostic_finalizer(global_dc); |
10345 |
-+ |
10346 |
-+ diagnostic_starter(global_dc) = start_colorize; |
10347 |
-+ diagnostic_finalizer(global_dc) = finalize_colorize; |
10348 |
-+} |
10349 |
-+ |
10350 |
-+static unsigned int colorize_rearm_execute(void) |
10351 |
-+{ |
10352 |
-+ if (diagnostic_starter(global_dc) == start_colorize) |
10353 |
-+ return 0; |
10354 |
-+ |
10355 |
-+ colorize_arm(); |
10356 |
-+ return 0; |
10357 |
-+} |
10358 |
-+ |
10359 |
-+#define PASS_NAME colorize_rearm |
10360 |
-+#define NO_GATE |
10361 |
-+#include "gcc-generate-simple_ipa-pass.h" |
10362 |
-+ |
10363 |
-+static void colorize_start_unit(void *gcc_data, void *user_data) |
10364 |
-+{ |
10365 |
-+ colorize_arm(); |
10366 |
-+} |
10367 |
-+ |
10368 |
-+static bool should_colorize(void) |
10369 |
-+{ |
10370 |
-+#if BUILDING_GCC_VERSION >= 4009 |
10371 |
-+ return false; |
10372 |
-+#else |
10373 |
-+ char const *t = getenv("TERM"); |
10374 |
-+ |
10375 |
-+ return t && strcmp(t, "dumb") && isatty(STDERR_FILENO); |
10376 |
-+#endif |
10377 |
-+} |
10378 |
-+ |
10379 |
-+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
10380 |
-+{ |
10381 |
-+ const char * const plugin_name = plugin_info->base_name; |
10382 |
-+ const int argc = plugin_info->argc; |
10383 |
-+ const struct plugin_argument * const argv = plugin_info->argv; |
10384 |
-+ int i; |
10385 |
-+ struct register_pass_info colorize_rearm_pass_info; |
10386 |
-+ bool colorize; |
10387 |
-+ |
10388 |
-+ colorize_rearm_pass_info.pass = make_colorize_rearm_pass(); |
10389 |
-+ colorize_rearm_pass_info.reference_pass_name = "*free_lang_data"; |
10390 |
-+ colorize_rearm_pass_info.ref_pass_instance_number = 1; |
10391 |
-+ colorize_rearm_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
10392 |
-+ |
10393 |
-+ if (!plugin_default_version_check(version, &gcc_version)) { |
10394 |
-+ error(G_("incompatible gcc/plugin versions")); |
10395 |
-+ return 1; |
10396 |
-+ } |
10397 |
-+ |
10398 |
-+ register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info); |
10399 |
-+ |
10400 |
-+ colorize = getenv("GCC_COLORS") ? should_colorize() : false; |
10401 |
-+ |
10402 |
-+ for (i = 0; i < argc; ++i) { |
10403 |
-+ if (!strcmp(argv[i].key, "color")) { |
10404 |
-+ if (!argv[i].value) { |
10405 |
-+ error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
10406 |
-+ continue; |
10407 |
-+ } |
10408 |
-+ if (!strcmp(argv[i].value, "always")) |
10409 |
-+ colorize = true; |
10410 |
-+ else if (!strcmp(argv[i].value, "never")) |
10411 |
-+ colorize = false; |
10412 |
-+ else if (!strcmp(argv[i].value, "auto")) |
10413 |
-+ colorize = should_colorize(); |
10414 |
-+ else |
10415 |
-+ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); |
10416 |
-+ continue; |
10417 |
-+ } |
10418 |
-+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
10419 |
-+ } |
10420 |
-+ |
10421 |
-+ if (colorize) { |
10422 |
-+ // TODO: parse GCC_COLORS as used by gcc 4.9+ |
10423 |
-+ register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL); |
10424 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info); |
10425 |
-+ } |
10426 |
-+ return 0; |
10427 |
-+} |
10428 |
-diff --git a/tools/gcc/constify_plugin.c b/tools/gcc/constify_plugin.c |
10429 |
-new file mode 100644 |
10430 |
-index 0000000..b52a700 |
10431 |
---- /dev/null |
10432 |
-+++ b/tools/gcc/constify_plugin.c |
10433 |
-@@ -0,0 +1,521 @@ |
10434 |
-+/* |
10435 |
-+ * Copyright 2011 by Emese Revfy <re.emese@×××××.com> |
10436 |
-+ * Copyright 2011-2016 by PaX Team <pageexec@××××××××.hu> |
10437 |
-+ * Licensed under the GPL v2, or (at your option) v3 |
10438 |
-+ * |
10439 |
-+ * This gcc plugin constifies all structures which contain only function pointers or are explicitly marked for constification. |
10440 |
-+ * |
10441 |
-+ * Homepage: |
10442 |
-+ * http://www.grsecurity.net/~ephox/const_plugin/ |
10443 |
-+ * |
10444 |
-+ * Usage: |
10445 |
-+ * $ gcc -I`gcc -print-file-name=plugin`/include -fPIC -shared -O2 -o constify_plugin.so constify_plugin.c |
10446 |
-+ * $ gcc -fplugin=constify_plugin.so test.c -O2 |
10447 |
-+ */ |
10448 |
-+ |
10449 |
-+#include "gcc-common.h" |
10450 |
-+ |
10451 |
-+// unused C type flag in all versions 4.5-6 |
10452 |
-+#define TYPE_CONSTIFY_VISITED(TYPE) TYPE_LANG_FLAG_4(TYPE) |
10453 |
-+ |
10454 |
-+int plugin_is_GPL_compatible; |
10455 |
-+ |
10456 |
-+static bool constify = true; |
10457 |
-+ |
10458 |
-+static struct plugin_info const_plugin_info = { |
10459 |
-+ .version = "201602181345", |
10460 |
-+ .help = "no-constify\tturn off constification\n", |
10461 |
-+}; |
10462 |
-+ |
10463 |
-+typedef struct { |
10464 |
-+ bool has_fptr_field; |
10465 |
-+ bool has_writable_field; |
10466 |
-+ bool has_do_const_field; |
10467 |
-+ bool has_no_const_field; |
10468 |
-+} constify_info; |
10469 |
-+ |
10470 |
-+static const_tree get_field_type(const_tree field) |
10471 |
-+{ |
10472 |
-+ return strip_array_types(TREE_TYPE(field)); |
10473 |
-+} |
10474 |
-+ |
10475 |
-+static bool is_fptr(const_tree field) |
10476 |
-+{ |
10477 |
-+ const_tree ptr = get_field_type(field); |
10478 |
-+ |
10479 |
-+ if (TREE_CODE(ptr) != POINTER_TYPE) |
10480 |
-+ return false; |
10481 |
-+ |
10482 |
-+ return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE; |
10483 |
-+} |
10484 |
-+ |
10485 |
-+/* |
10486 |
-+ * determine whether the given structure type meets the requirements for automatic constification, |
10487 |
-+ * including the constification attributes on nested structure types |
10488 |
-+ */ |
10489 |
-+static void constifiable(const_tree node, constify_info *cinfo) |
10490 |
-+{ |
10491 |
-+ const_tree field; |
10492 |
-+ |
10493 |
-+ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); |
10494 |
-+ |
10495 |
-+ // e.g., pointer to structure fields while still constructing the structure type |
10496 |
-+ if (TYPE_FIELDS(node) == NULL_TREE) |
10497 |
-+ return; |
10498 |
-+ |
10499 |
-+ for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { |
10500 |
-+ const_tree type = get_field_type(field); |
10501 |
-+ enum tree_code code = TREE_CODE(type); |
10502 |
-+ |
10503 |
-+ if (node == type) |
10504 |
-+ continue; |
10505 |
-+ |
10506 |
-+ if (is_fptr(field)) |
10507 |
-+ cinfo->has_fptr_field = true; |
10508 |
-+ else if (code == RECORD_TYPE || code == UNION_TYPE) { |
10509 |
-+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) |
10510 |
-+ cinfo->has_do_const_field = true; |
10511 |
-+ else if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) |
10512 |
-+ cinfo->has_no_const_field = true; |
10513 |
-+ else |
10514 |
-+ constifiable(type, cinfo); |
10515 |
-+ } else if (!TREE_READONLY(field)) |
10516 |
-+ cinfo->has_writable_field = true; |
10517 |
-+ } |
10518 |
-+} |
10519 |
-+ |
10520 |
-+static bool constified(const_tree node) |
10521 |
-+{ |
10522 |
-+ constify_info cinfo = { |
10523 |
-+ .has_fptr_field = false, |
10524 |
-+ .has_writable_field = false, |
10525 |
-+ .has_do_const_field = false, |
10526 |
-+ .has_no_const_field = false |
10527 |
-+ }; |
10528 |
-+ |
10529 |
-+ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); |
10530 |
-+ |
10531 |
-+ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) { |
10532 |
-+// gcc_assert(!TYPE_READONLY(node)); |
10533 |
-+ return false; |
10534 |
-+ } |
10535 |
-+ |
10536 |
-+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) { |
10537 |
-+ gcc_assert(TYPE_READONLY(node)); |
10538 |
-+ return true; |
10539 |
-+ } |
10540 |
-+ |
10541 |
-+ constifiable(node, &cinfo); |
10542 |
-+ if ((!cinfo.has_fptr_field || cinfo.has_writable_field || cinfo.has_no_const_field) && !cinfo.has_do_const_field) |
10543 |
-+ return false; |
10544 |
-+ |
10545 |
-+ return TYPE_READONLY(node); |
10546 |
-+} |
10547 |
-+ |
10548 |
-+static void deconstify_tree(tree node); |
10549 |
-+ |
10550 |
-+static void deconstify_type(tree type) |
10551 |
-+{ |
10552 |
-+ tree field; |
10553 |
-+ |
10554 |
-+ gcc_assert(TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE); |
10555 |
-+ |
10556 |
-+ for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { |
10557 |
-+ const_tree fieldtype = get_field_type(field); |
10558 |
-+ |
10559 |
-+ // special case handling of simple ptr-to-same-array-type members |
10560 |
-+ if (TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE) { |
10561 |
-+ tree ptrtype = TREE_TYPE(TREE_TYPE(field)); |
10562 |
-+ |
10563 |
-+ if (TREE_TYPE(TREE_TYPE(field)) == type) |
10564 |
-+ continue; |
10565 |
-+ if (TREE_CODE(ptrtype) != RECORD_TYPE && TREE_CODE(ptrtype) != UNION_TYPE) |
10566 |
-+ continue; |
10567 |
-+ if (!constified(ptrtype)) |
10568 |
-+ continue; |
10569 |
-+ if (TYPE_MAIN_VARIANT(ptrtype) == TYPE_MAIN_VARIANT(type)) { |
10570 |
-+ TREE_TYPE(field) = copy_node(TREE_TYPE(field)); |
10571 |
-+ TREE_TYPE(TREE_TYPE(field)) = build_qualified_type(type, TYPE_QUALS(ptrtype) & ~TYPE_QUAL_CONST); |
10572 |
-+ } |
10573 |
-+ continue; |
10574 |
-+ } |
10575 |
-+ if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE) |
10576 |
-+ continue; |
10577 |
-+ if (!constified(fieldtype)) |
10578 |
-+ continue; |
10579 |
-+ |
10580 |
-+ deconstify_tree(field); |
10581 |
-+ TREE_READONLY(field) = 0; |
10582 |
-+ } |
10583 |
-+ TYPE_READONLY(type) = 0; |
10584 |
-+ C_TYPE_FIELDS_READONLY(type) = 0; |
10585 |
-+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
10586 |
-+ TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); |
10587 |
-+ TYPE_ATTRIBUTES(type) = remove_attribute("do_const", TYPE_ATTRIBUTES(type)); |
10588 |
-+ } |
10589 |
-+} |
10590 |
-+ |
10591 |
-+static void deconstify_tree(tree node) |
10592 |
-+{ |
10593 |
-+ tree old_type, new_type, field; |
10594 |
-+ |
10595 |
-+ old_type = TREE_TYPE(node); |
10596 |
-+ while (TREE_CODE(old_type) == ARRAY_TYPE && TREE_CODE(TREE_TYPE(old_type)) != ARRAY_TYPE) { |
10597 |
-+ node = TREE_TYPE(node) = copy_node(old_type); |
10598 |
-+ old_type = TREE_TYPE(old_type); |
10599 |
-+ } |
10600 |
-+ |
10601 |
-+ gcc_assert(TREE_CODE(old_type) == RECORD_TYPE || TREE_CODE(old_type) == UNION_TYPE); |
10602 |
-+ gcc_assert(TYPE_READONLY(old_type) && (TYPE_QUALS(old_type) & TYPE_QUAL_CONST)); |
10603 |
-+ |
10604 |
-+ new_type = build_qualified_type(old_type, TYPE_QUALS(old_type) & ~TYPE_QUAL_CONST); |
10605 |
-+ TYPE_FIELDS(new_type) = copy_list(TYPE_FIELDS(new_type)); |
10606 |
-+ for (field = TYPE_FIELDS(new_type); field; field = TREE_CHAIN(field)) |
10607 |
-+ DECL_FIELD_CONTEXT(field) = new_type; |
10608 |
-+ |
10609 |
-+ deconstify_type(new_type); |
10610 |
-+ |
10611 |
-+ TREE_TYPE(node) = new_type; |
10612 |
-+} |
10613 |
-+ |
10614 |
-+static tree handle_no_const_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
10615 |
-+{ |
10616 |
-+ tree type; |
10617 |
-+ constify_info cinfo = { |
10618 |
-+ .has_fptr_field = false, |
10619 |
-+ .has_writable_field = false, |
10620 |
-+ .has_do_const_field = false, |
10621 |
-+ .has_no_const_field = false |
10622 |
-+ }; |
10623 |
-+ |
10624 |
-+ *no_add_attrs = true; |
10625 |
-+ if (TREE_CODE(*node) == FUNCTION_DECL) { |
10626 |
-+ error("%qE attribute does not apply to functions (%qF)", name, *node); |
10627 |
-+ return NULL_TREE; |
10628 |
-+ } |
10629 |
-+ |
10630 |
-+ if (TREE_CODE(*node) == PARM_DECL) { |
10631 |
-+ error("%qE attribute does not apply to function parameters (%qD)", name, *node); |
10632 |
-+ return NULL_TREE; |
10633 |
-+ } |
10634 |
-+ |
10635 |
-+ if (TREE_CODE(*node) == VAR_DECL) { |
10636 |
-+ error("%qE attribute does not apply to variables (%qD)", name, *node); |
10637 |
-+ return NULL_TREE; |
10638 |
-+ } |
10639 |
-+ |
10640 |
-+ if (TYPE_P(*node)) { |
10641 |
-+ type = *node; |
10642 |
-+ } else { |
10643 |
-+ if (TREE_CODE(*node) != TYPE_DECL) { |
10644 |
-+ error("%qE attribute does not apply to %qD (%qT)", name, *node, TREE_TYPE(*node)); |
10645 |
-+ return NULL_TREE; |
10646 |
-+ } |
10647 |
-+ type = TREE_TYPE(*node); |
10648 |
-+ } |
10649 |
-+ |
10650 |
-+ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) { |
10651 |
-+ error("%qE attribute used on %qT applies to struct and union types only", name, type); |
10652 |
-+ return NULL_TREE; |
10653 |
-+ } |
10654 |
-+ |
10655 |
-+ if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) { |
10656 |
-+ error("%qE attribute is already applied to the type %qT", name, type); |
10657 |
-+ return NULL_TREE; |
10658 |
-+ } |
10659 |
-+ |
10660 |
-+ if (TYPE_P(*node)) { |
10661 |
-+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) |
10662 |
-+ error("%qE attribute used on type %qT is incompatible with 'do_const'", name, type); |
10663 |
-+ else |
10664 |
-+ *no_add_attrs = false; |
10665 |
-+ return NULL_TREE; |
10666 |
-+ } |
10667 |
-+ |
10668 |
-+ constifiable(type, &cinfo); |
10669 |
-+ if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
10670 |
-+ if (constify) { |
10671 |
-+ if TYPE_P(*node) |
10672 |
-+ deconstify_type(*node); |
10673 |
-+ else |
10674 |
-+ deconstify_tree(*node); |
10675 |
-+ } |
10676 |
-+ if (TYPE_P(*node)) |
10677 |
-+ TYPE_CONSTIFY_VISITED(*node) = 1; |
10678 |
-+ else |
10679 |
-+ TYPE_CONSTIFY_VISITED(TREE_TYPE(*node)) = 1; |
10680 |
-+ return NULL_TREE; |
10681 |
-+ } |
10682 |
-+ |
10683 |
-+ if (constify && TYPE_FIELDS(type)) |
10684 |
-+ error("%qE attribute used on type %qT that is not constified", name, type); |
10685 |
-+ return NULL_TREE; |
10686 |
-+} |
10687 |
-+ |
10688 |
-+static void constify_type(tree type) |
10689 |
-+{ |
10690 |
-+ TYPE_READONLY(type) = 1; |
10691 |
-+ C_TYPE_FIELDS_READONLY(type) = 1; |
10692 |
-+ TYPE_CONSTIFY_VISITED(type) = 1; |
10693 |
-+// TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); |
10694 |
-+// TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("do_const"), NULL_TREE, TYPE_ATTRIBUTES(type)); |
10695 |
-+} |
10696 |
-+ |
10697 |
-+static tree handle_do_const_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
10698 |
-+{ |
10699 |
-+ *no_add_attrs = true; |
10700 |
-+ if (!TYPE_P(*node)) { |
10701 |
-+ error("%qE attribute applies to types only (%qD)", name, *node); |
10702 |
-+ return NULL_TREE; |
10703 |
-+ } |
10704 |
-+ |
10705 |
-+ if (TREE_CODE(*node) != RECORD_TYPE && TREE_CODE(*node) != UNION_TYPE) { |
10706 |
-+ error("%qE attribute used on %qT applies to struct and union types only", name, *node); |
10707 |
-+ return NULL_TREE; |
10708 |
-+ } |
10709 |
-+ |
10710 |
-+ if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(*node))) { |
10711 |
-+ error("%qE attribute used on %qT is already applied to the type", name, *node); |
10712 |
-+ return NULL_TREE; |
10713 |
-+ } |
10714 |
-+ |
10715 |
-+ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(*node))) { |
10716 |
-+ error("%qE attribute used on %qT is incompatible with 'no_const'", name, *node); |
10717 |
-+ return NULL_TREE; |
10718 |
-+ } |
10719 |
-+ |
10720 |
-+ *no_add_attrs = false; |
10721 |
-+ return NULL_TREE; |
10722 |
-+} |
10723 |
-+ |
10724 |
-+static struct attribute_spec no_const_attr = { |
10725 |
-+ .name = "no_const", |
10726 |
-+ .min_length = 0, |
10727 |
-+ .max_length = 0, |
10728 |
-+ .decl_required = false, |
10729 |
-+ .type_required = false, |
10730 |
-+ .function_type_required = false, |
10731 |
-+ .handler = handle_no_const_attribute, |
10732 |
-+#if BUILDING_GCC_VERSION >= 4007 |
10733 |
-+ .affects_type_identity = true |
10734 |
-+#endif |
10735 |
-+}; |
10736 |
-+ |
10737 |
-+static struct attribute_spec do_const_attr = { |
10738 |
-+ .name = "do_const", |
10739 |
-+ .min_length = 0, |
10740 |
-+ .max_length = 0, |
10741 |
-+ .decl_required = false, |
10742 |
-+ .type_required = false, |
10743 |
-+ .function_type_required = false, |
10744 |
-+ .handler = handle_do_const_attribute, |
10745 |
-+#if BUILDING_GCC_VERSION >= 4007 |
10746 |
-+ .affects_type_identity = true |
10747 |
-+#endif |
10748 |
-+}; |
10749 |
-+ |
10750 |
-+static void register_attributes(void *event_data, void *data) |
10751 |
-+{ |
10752 |
-+ register_attribute(&no_const_attr); |
10753 |
-+ register_attribute(&do_const_attr); |
10754 |
-+} |
10755 |
-+ |
10756 |
-+static void finish_type(void *event_data, void *data) |
10757 |
-+{ |
10758 |
-+ tree type = (tree)event_data; |
10759 |
-+ constify_info cinfo = { |
10760 |
-+ .has_fptr_field = false, |
10761 |
-+ .has_writable_field = false, |
10762 |
-+ .has_do_const_field = false, |
10763 |
-+ .has_no_const_field = false |
10764 |
-+ }; |
10765 |
-+ |
10766 |
-+ if (type == NULL_TREE || type == error_mark_node) |
10767 |
-+ return; |
10768 |
-+ |
10769 |
-+#if BUILDING_GCC_VERSION >= 5000 |
10770 |
-+ if (TREE_CODE(type) == ENUMERAL_TYPE) |
10771 |
-+ return; |
10772 |
-+#endif |
10773 |
-+ |
10774 |
-+ if (TYPE_FIELDS(type) == NULL_TREE || TYPE_CONSTIFY_VISITED(type)) |
10775 |
-+ return; |
10776 |
-+ |
10777 |
-+ constifiable(type, &cinfo); |
10778 |
-+ |
10779 |
-+ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) { |
10780 |
-+ if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || cinfo.has_do_const_field) { |
10781 |
-+ deconstify_type(type); |
10782 |
-+ TYPE_CONSTIFY_VISITED(type) = 1; |
10783 |
-+ } else |
10784 |
-+ error("'no_const' attribute used on type %qT that is not constified", type); |
10785 |
-+ return; |
10786 |
-+ } |
10787 |
-+ |
10788 |
-+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
10789 |
-+ if (!cinfo.has_writable_field && !cinfo.has_no_const_field) { |
10790 |
-+ error("'do_const' attribute used on type %qT that is%sconstified", type, cinfo.has_fptr_field ? " " : " not "); |
10791 |
-+ return; |
10792 |
-+ } |
10793 |
-+ constify_type(type); |
10794 |
-+ return; |
10795 |
-+ } |
10796 |
-+ |
10797 |
-+ if (cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) { |
10798 |
-+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { |
10799 |
-+ error("'do_const' attribute used on type %qT that is constified", type); |
10800 |
-+ return; |
10801 |
-+ } |
10802 |
-+ constify_type(type); |
10803 |
-+ return; |
10804 |
-+ } |
10805 |
-+ |
10806 |
-+ deconstify_type(type); |
10807 |
-+ TYPE_CONSTIFY_VISITED(type) = 1; |
10808 |
-+} |
10809 |
-+ |
10810 |
-+static void check_global_variables(void *event_data, void *data) |
10811 |
-+{ |
10812 |
-+ varpool_node_ptr node; |
10813 |
-+ |
10814 |
-+ FOR_EACH_VARIABLE(node) { |
10815 |
-+ tree var = NODE_DECL(node); |
10816 |
-+ tree type = TREE_TYPE(var); |
10817 |
-+ |
10818 |
-+ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) |
10819 |
-+ continue; |
10820 |
-+ |
10821 |
-+ if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) |
10822 |
-+ continue; |
10823 |
-+ |
10824 |
-+ if (!TYPE_CONSTIFY_VISITED(type)) |
10825 |
-+ continue; |
10826 |
-+ |
10827 |
-+ if (DECL_EXTERNAL(var)) |
10828 |
-+ continue; |
10829 |
-+ |
10830 |
-+ if (DECL_INITIAL(var)) |
10831 |
-+ continue; |
10832 |
-+ |
10833 |
-+ // this works around a gcc bug/feature where uninitialized globals |
10834 |
-+ // are moved into the .bss section regardless of any constification |
10835 |
-+ DECL_INITIAL(var) = build_constructor(type, NULL); |
10836 |
-+// inform(DECL_SOURCE_LOCATION(var), "constified variable %qE moved into .rodata", var); |
10837 |
-+ } |
10838 |
-+} |
10839 |
-+ |
10840 |
-+static unsigned int check_local_variables_execute(void) |
10841 |
-+{ |
10842 |
-+ unsigned int ret = 0; |
10843 |
-+ tree var; |
10844 |
-+ |
10845 |
-+ unsigned int i; |
10846 |
-+ |
10847 |
-+ FOR_EACH_LOCAL_DECL(cfun, i, var) { |
10848 |
-+ tree type = TREE_TYPE(var); |
10849 |
-+ |
10850 |
-+ gcc_assert(DECL_P(var)); |
10851 |
-+ if (is_global_var(var)) |
10852 |
-+ continue; |
10853 |
-+ |
10854 |
-+ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) |
10855 |
-+ continue; |
10856 |
-+ |
10857 |
-+ if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) |
10858 |
-+ continue; |
10859 |
-+ |
10860 |
-+ if (!TYPE_CONSTIFY_VISITED(type)) |
10861 |
-+ continue; |
10862 |
-+ |
10863 |
-+ error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var); |
10864 |
-+ ret = 1; |
10865 |
-+ } |
10866 |
-+ return ret; |
10867 |
-+} |
10868 |
-+ |
10869 |
-+#define PASS_NAME check_local_variables |
10870 |
-+#define NO_GATE |
10871 |
-+#include "gcc-generate-gimple-pass.h" |
10872 |
-+ |
10873 |
-+static struct { |
10874 |
-+ const char *name; |
10875 |
-+ const char *asm_op; |
10876 |
-+} sections[] = { |
10877 |
-+ {".init.rodata", "\t.section\t.init.rodata,\"a\""}, |
10878 |
-+ {".ref.rodata", "\t.section\t.ref.rodata,\"a\""}, |
10879 |
-+ {".devinit.rodata", "\t.section\t.devinit.rodata,\"a\""}, |
10880 |
-+ {".devexit.rodata", "\t.section\t.devexit.rodata,\"a\""}, |
10881 |
-+ {".cpuinit.rodata", "\t.section\t.cpuinit.rodata,\"a\""}, |
10882 |
-+ {".cpuexit.rodata", "\t.section\t.cpuexit.rodata,\"a\""}, |
10883 |
-+ {".meminit.rodata", "\t.section\t.meminit.rodata,\"a\""}, |
10884 |
-+ {".memexit.rodata", "\t.section\t.memexit.rodata,\"a\""}, |
10885 |
-+ {".data..read_only", "\t.section\t.data..read_only,\"a\""}, |
10886 |
-+}; |
10887 |
-+ |
10888 |
-+static unsigned int (*old_section_type_flags)(tree decl, const char *name, int reloc); |
10889 |
-+ |
10890 |
-+static unsigned int constify_section_type_flags(tree decl, const char *name, int reloc) |
10891 |
-+{ |
10892 |
-+ size_t i; |
10893 |
-+ |
10894 |
-+ for (i = 0; i < ARRAY_SIZE(sections); i++) |
10895 |
-+ if (!strcmp(sections[i].name, name)) |
10896 |
-+ return 0; |
10897 |
-+ return old_section_type_flags(decl, name, reloc); |
10898 |
-+} |
10899 |
-+ |
10900 |
-+static void constify_start_unit(void *gcc_data, void *user_data) |
10901 |
-+{ |
10902 |
-+// size_t i; |
10903 |
-+ |
10904 |
-+// for (i = 0; i < ARRAY_SIZE(sections); i++) |
10905 |
-+// sections[i].section = get_unnamed_section(0, output_section_asm_op, sections[i].asm_op); |
10906 |
-+// sections[i].section = get_section(sections[i].name, 0, NULL); |
10907 |
-+ |
10908 |
-+ old_section_type_flags = targetm.section_type_flags; |
10909 |
-+ targetm.section_type_flags = constify_section_type_flags; |
10910 |
-+} |
10911 |
-+ |
10912 |
-+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
10913 |
-+{ |
10914 |
-+ const char * const plugin_name = plugin_info->base_name; |
10915 |
-+ const int argc = plugin_info->argc; |
10916 |
-+ const struct plugin_argument * const argv = plugin_info->argv; |
10917 |
-+ int i; |
10918 |
-+ |
10919 |
-+ struct register_pass_info check_local_variables_pass_info; |
10920 |
-+ |
10921 |
-+ check_local_variables_pass_info.pass = make_check_local_variables_pass(); |
10922 |
-+ check_local_variables_pass_info.reference_pass_name = "ssa"; |
10923 |
-+ check_local_variables_pass_info.ref_pass_instance_number = 1; |
10924 |
-+ check_local_variables_pass_info.pos_op = PASS_POS_INSERT_BEFORE; |
10925 |
-+ |
10926 |
-+ if (!plugin_default_version_check(version, &gcc_version)) { |
10927 |
-+ error(G_("incompatible gcc/plugin versions")); |
10928 |
-+ return 1; |
10929 |
-+ } |
10930 |
-+ |
10931 |
-+ for (i = 0; i < argc; ++i) { |
10932 |
-+ if (!(strcmp(argv[i].key, "no-constify"))) { |
10933 |
-+ constify = false; |
10934 |
-+ continue; |
10935 |
-+ } |
10936 |
-+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
10937 |
-+ } |
10938 |
-+ |
10939 |
-+ if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) { |
10940 |
-+ inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name); |
10941 |
-+ constify = false; |
10942 |
-+ } |
10943 |
-+ |
10944 |
-+ register_callback(plugin_name, PLUGIN_INFO, NULL, &const_plugin_info); |
10945 |
-+ if (constify) { |
10946 |
-+ register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL); |
10947 |
-+ register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); |
10948 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &check_local_variables_pass_info); |
10949 |
-+ register_callback(plugin_name, PLUGIN_START_UNIT, constify_start_unit, NULL); |
10950 |
-+ } |
10951 |
-+ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
10952 |
-+ |
10953 |
-+ return 0; |
10954 |
-+} |
10955 |
-diff --git a/tools/gcc/gcc-common.h b/tools/gcc/gcc-common.h |
10956 |
-new file mode 100644 |
10957 |
-index 0000000..0c0b842 |
10958 |
---- /dev/null |
10959 |
-+++ b/tools/gcc/gcc-common.h |
10960 |
-@@ -0,0 +1,879 @@ |
10961 |
-+#ifndef GCC_COMMON_H_INCLUDED |
10962 |
-+#define GCC_COMMON_H_INCLUDED |
10963 |
-+ |
10964 |
-+#include "bversion.h" |
10965 |
-+#if BUILDING_GCC_VERSION >= 6000 |
10966 |
-+#include "gcc-plugin.h" |
10967 |
-+#else |
10968 |
-+#include "plugin.h" |
10969 |
-+#endif |
10970 |
-+#include "plugin-version.h" |
10971 |
-+#include "config.h" |
10972 |
-+#include "system.h" |
10973 |
-+#include "coretypes.h" |
10974 |
-+#include "tm.h" |
10975 |
-+#include "line-map.h" |
10976 |
-+#include "input.h" |
10977 |
-+#include "tree.h" |
10978 |
-+ |
10979 |
-+#include "tree-inline.h" |
10980 |
-+#include "version.h" |
10981 |
-+#include "rtl.h" |
10982 |
-+#include "tm_p.h" |
10983 |
-+#include "flags.h" |
10984 |
-+//#include "insn-attr.h" |
10985 |
-+//#include "insn-config.h" |
10986 |
-+//#include "insn-flags.h" |
10987 |
-+#include "hard-reg-set.h" |
10988 |
-+//#include "recog.h" |
10989 |
-+#include "output.h" |
10990 |
-+#include "except.h" |
10991 |
-+#include "function.h" |
10992 |
-+#include "toplev.h" |
10993 |
-+//#include "expr.h" |
10994 |
-+#include "basic-block.h" |
10995 |
-+#include "intl.h" |
10996 |
-+#include "ggc.h" |
10997 |
-+//#include "regs.h" |
10998 |
-+#include "timevar.h" |
10999 |
-+ |
11000 |
-+#include "params.h" |
11001 |
-+ |
11002 |
-+#if BUILDING_GCC_VERSION <= 4009 |
11003 |
-+#include "pointer-set.h" |
11004 |
-+#else |
11005 |
-+#include "hash-map.h" |
11006 |
++#include "tree-inline.h" |
11007 |
++#include "version.h" |
11008 |
++#include "rtl.h" |
11009 |
++#include "tm_p.h" |
11010 |
++#include "flags.h" |
11011 |
++//#include "insn-attr.h" |
11012 |
++//#include "insn-config.h" |
11013 |
++//#include "insn-flags.h" |
11014 |
++#include "hard-reg-set.h" |
11015 |
++//#include "recog.h" |
11016 |
++#include "output.h" |
11017 |
++#include "except.h" |
11018 |
++#include "function.h" |
11019 |
++#include "toplev.h" |
11020 |
++//#include "expr.h" |
11021 |
++#include "basic-block.h" |
11022 |
++#include "intl.h" |
11023 |
++#include "ggc.h" |
11024 |
++//#include "regs.h" |
11025 |
++#include "timevar.h" |
11026 |
++ |
11027 |
++#include "params.h" |
11028 |
++ |
11029 |
++#if BUILDING_GCC_VERSION <= 4009 |
11030 |
++#include "pointer-set.h" |
11031 |
++#else |
11032 |
++#include "hash-map.h" |
11033 |
+#endif |
11034 |
+ |
11035 |
+#include "emit-rtl.h" |
11036 |
@@ -166240,11 +163512,11 @@ index 0000000..0c0b842 |
11037 |
+#endif |
11038 |
+ |
11039 |
+#endif |
11040 |
-diff --git a/tools/gcc/gcc-generate-gimple-pass.h b/tools/gcc/gcc-generate-gimple-pass.h |
11041 |
+diff --git a/scripts/gcc-plugins/gcc-generate-gimple-pass.h b/scripts/gcc-plugins/gcc-generate-gimple-pass.h |
11042 |
new file mode 100644 |
11043 |
index 0000000..0b081fe |
11044 |
--- /dev/null |
11045 |
-+++ b/tools/gcc/gcc-generate-gimple-pass.h |
11046 |
++++ b/scripts/gcc-plugins/gcc-generate-gimple-pass.h |
11047 |
@@ -0,0 +1,175 @@ |
11048 |
+/* |
11049 |
+ * Generator for GIMPLE pass related boilerplate code/data |
11050 |
@@ -166421,11 +163693,11 @@ index 0000000..0b081fe |
11051 |
+#undef __PASS_NAME_PASS_DATA |
11052 |
+ |
11053 |
+#endif /* PASS_NAME */ |
11054 |
-diff --git a/tools/gcc/gcc-generate-ipa-pass.h b/tools/gcc/gcc-generate-ipa-pass.h |
11055 |
+diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h |
11056 |
new file mode 100644 |
11057 |
index 0000000..9bd926e |
11058 |
--- /dev/null |
11059 |
-+++ b/tools/gcc/gcc-generate-ipa-pass.h |
11060 |
++++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h |
11061 |
@@ -0,0 +1,289 @@ |
11062 |
+/* |
11063 |
+ * Generator for IPA pass related boilerplate code/data |
11064 |
@@ -166716,11 +163988,11 @@ index 0000000..9bd926e |
11065 |
+#undef __WRITE_SUMMARY |
11066 |
+ |
11067 |
+#endif /* PASS_NAME */ |
11068 |
-diff --git a/tools/gcc/gcc-generate-rtl-pass.h b/tools/gcc/gcc-generate-rtl-pass.h |
11069 |
+diff --git a/scripts/gcc-plugins/gcc-generate-rtl-pass.h b/scripts/gcc-plugins/gcc-generate-rtl-pass.h |
11070 |
new file mode 100644 |
11071 |
index 0000000..1dc67a5 |
11072 |
--- /dev/null |
11073 |
-+++ b/tools/gcc/gcc-generate-rtl-pass.h |
11074 |
++++ b/scripts/gcc-plugins/gcc-generate-rtl-pass.h |
11075 |
@@ -0,0 +1,175 @@ |
11076 |
+/* |
11077 |
+ * Generator for RTL pass related boilerplate code/data |
11078 |
@@ -166897,11 +164169,11 @@ index 0000000..1dc67a5 |
11079 |
+#undef __PASS_NAME_PASS_DATA |
11080 |
+ |
11081 |
+#endif /* PASS_NAME */ |
11082 |
-diff --git a/tools/gcc/gcc-generate-simple_ipa-pass.h b/tools/gcc/gcc-generate-simple_ipa-pass.h |
11083 |
+diff --git a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h |
11084 |
new file mode 100644 |
11085 |
index 0000000..a27e2b3 |
11086 |
--- /dev/null |
11087 |
-+++ b/tools/gcc/gcc-generate-simple_ipa-pass.h |
11088 |
++++ b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h |
11089 |
@@ -0,0 +1,175 @@ |
11090 |
+/* |
11091 |
+ * Generator for SIMPLE_IPA pass related boilerplate code/data |
11092 |
@@ -167078,11 +164350,11 @@ index 0000000..a27e2b3 |
11093 |
+#undef __PASS_NAME_PASS_DATA |
11094 |
+ |
11095 |
+#endif /* PASS_NAME */ |
11096 |
-diff --git a/tools/gcc/gen-random-seed.sh b/tools/gcc/gen-random-seed.sh |
11097 |
+diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh |
11098 |
new file mode 100644 |
11099 |
index 0000000..7514850 |
11100 |
--- /dev/null |
11101 |
-+++ b/tools/gcc/gen-random-seed.sh |
11102 |
++++ b/scripts/gcc-plugins/gen-random-seed.sh |
11103 |
@@ -0,0 +1,8 @@ |
11104 |
+#!/bin/sh |
11105 |
+ |
11106 |
@@ -167092,11 +164364,11 @@ index 0000000..7514850 |
11107 |
+ HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'` |
11108 |
+ echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2" |
11109 |
+fi |
11110 |
-diff --git a/tools/gcc/initify_plugin.c b/tools/gcc/initify_plugin.c |
11111 |
+diff --git a/scripts/gcc-plugins/initify_plugin.c b/scripts/gcc-plugins/initify_plugin.c |
11112 |
new file mode 100644 |
11113 |
index 0000000..bf3eb6c |
11114 |
--- /dev/null |
11115 |
-+++ b/tools/gcc/initify_plugin.c |
11116 |
++++ b/scripts/gcc-plugins/initify_plugin.c |
11117 |
@@ -0,0 +1,536 @@ |
11118 |
+/* |
11119 |
+ * Copyright 2015-2016 by Emese Revfy <re.emese@×××××.com> |
11120 |
@@ -167634,11 +164906,11 @@ index 0000000..bf3eb6c |
11121 |
+ |
11122 |
+ return 0; |
11123 |
+} |
11124 |
-diff --git a/tools/gcc/kallocstat_plugin.c b/tools/gcc/kallocstat_plugin.c |
11125 |
+diff --git a/scripts/gcc-plugins/kallocstat_plugin.c b/scripts/gcc-plugins/kallocstat_plugin.c |
11126 |
new file mode 100644 |
11127 |
index 0000000..30ecc9a |
11128 |
--- /dev/null |
11129 |
-+++ b/tools/gcc/kallocstat_plugin.c |
11130 |
++++ b/scripts/gcc-plugins/kallocstat_plugin.c |
11131 |
@@ -0,0 +1,135 @@ |
11132 |
+/* |
11133 |
+ * Copyright 2011-2016 by the PaX Team <pageexec@××××××××.hu> |
11134 |
@@ -167775,11 +165047,11 @@ index 0000000..30ecc9a |
11135 |
+ |
11136 |
+ return 0; |
11137 |
+} |
11138 |
-diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c |
11139 |
+diff --git a/scripts/gcc-plugins/kernexec_plugin.c b/scripts/gcc-plugins/kernexec_plugin.c |
11140 |
new file mode 100644 |
11141 |
index 0000000..e31e92f |
11142 |
--- /dev/null |
11143 |
-+++ b/tools/gcc/kernexec_plugin.c |
11144 |
++++ b/scripts/gcc-plugins/kernexec_plugin.c |
11145 |
@@ -0,0 +1,407 @@ |
11146 |
+/* |
11147 |
+ * Copyright 2011-2016 by the PaX Team <pageexec@××××××××.hu> |
11148 |
@@ -168188,12 +165460,12 @@ index 0000000..e31e92f |
11149 |
+ |
11150 |
+ return 0; |
11151 |
+} |
11152 |
-diff --git a/tools/gcc/latent_entropy_plugin.c b/tools/gcc/latent_entropy_plugin.c |
11153 |
+diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c |
11154 |
new file mode 100644 |
11155 |
-index 0000000..50d373c |
11156 |
+index 0000000..f08a221 |
11157 |
--- /dev/null |
11158 |
-+++ b/tools/gcc/latent_entropy_plugin.c |
11159 |
-@@ -0,0 +1,422 @@ |
11160 |
++++ b/scripts/gcc-plugins/latent_entropy_plugin.c |
11161 |
+@@ -0,0 +1,438 @@ |
11162 |
+/* |
11163 |
+ * Copyright 2012-2016 by the PaX Team <pageexec@××××××××.hu> |
11164 |
+ * Licensed under the GPL v2 |
11165 |
@@ -168219,11 +165491,13 @@ index 0000000..50d373c |
11166 |
+ |
11167 |
+int plugin_is_GPL_compatible; |
11168 |
+ |
11169 |
++static bool enabled = true; |
11170 |
++ |
11171 |
+static GTY(()) tree latent_entropy_decl; |
11172 |
+ |
11173 |
+static struct plugin_info latent_entropy_plugin_info = { |
11174 |
-+ .version = "201604022010", |
11175 |
-+ .help = NULL |
11176 |
++ .version = "201605212030", |
11177 |
++ .help = "disable\tturn off latent entropy instrumentation\n", |
11178 |
+}; |
11179 |
+ |
11180 |
+static unsigned HOST_WIDE_INT seed; |
11181 |
@@ -168586,6 +165860,10 @@ index 0000000..50d373c |
11182 |
+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
11183 |
+{ |
11184 |
+ const char * const plugin_name = plugin_info->base_name; |
11185 |
++ const int argc = plugin_info->argc; |
11186 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
11187 |
++ int i; |
11188 |
++ |
11189 |
+ struct register_pass_info latent_entropy_pass_info; |
11190 |
+ |
11191 |
+ latent_entropy_pass_info.pass = make_latent_entropy_pass(); |
11192 |
@@ -168608,19 +165886,29 @@ index 0000000..50d373c |
11193 |
+ return 1; |
11194 |
+ } |
11195 |
+ |
11196 |
++ for (i = 0; i < argc; ++i) { |
11197 |
++ if (!(strcmp(argv[i].key, "disable"))) { |
11198 |
++ enabled = false; |
11199 |
++ continue; |
11200 |
++ } |
11201 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
11202 |
++ } |
11203 |
++ |
11204 |
+ register_callback(plugin_name, PLUGIN_INFO, NULL, &latent_entropy_plugin_info); |
11205 |
-+ register_callback(plugin_name, PLUGIN_START_UNIT, &latent_entropy_start_unit, NULL); |
11206 |
-+ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_latent_entropy); |
11207 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &latent_entropy_pass_info); |
11208 |
++ if (enabled) { |
11209 |
++ register_callback(plugin_name, PLUGIN_START_UNIT, &latent_entropy_start_unit, NULL); |
11210 |
++ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_latent_entropy); |
11211 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &latent_entropy_pass_info); |
11212 |
++ } |
11213 |
+ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
11214 |
+ |
11215 |
+ return 0; |
11216 |
+} |
11217 |
-diff --git a/tools/gcc/randomize_layout_plugin.c b/tools/gcc/randomize_layout_plugin.c |
11218 |
+diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c |
11219 |
new file mode 100644 |
11220 |
index 0000000..a716d7a |
11221 |
--- /dev/null |
11222 |
-+++ b/tools/gcc/randomize_layout_plugin.c |
11223 |
++++ b/scripts/gcc-plugins/randomize_layout_plugin.c |
11224 |
@@ -0,0 +1,940 @@ |
11225 |
+/* |
11226 |
+ * Copyright 2014-2016 by Open Source Security, Inc., Brad Spengler <spender@××××××××××.net> |
11227 |
@@ -169562,21 +166850,21 @@ index 0000000..a716d7a |
11228 |
+ |
11229 |
+ return 0; |
11230 |
+} |
11231 |
-diff --git a/tools/gcc/rap_plugin/Makefile b/tools/gcc/rap_plugin/Makefile |
11232 |
+diff --git a/scripts/gcc-plugins/rap_plugin/Makefile b/scripts/gcc-plugins/rap_plugin/Makefile |
11233 |
new file mode 100644 |
11234 |
index 0000000..8171be8 |
11235 |
--- /dev/null |
11236 |
-+++ b/tools/gcc/rap_plugin/Makefile |
11237 |
++++ b/scripts/gcc-plugins/rap_plugin/Makefile |
11238 |
@@ -0,0 +1,4 @@ |
11239 |
+$(HOSTLIBS)-$(CONFIG_PAX_RAP) += rap_plugin.so |
11240 |
+always := $($(HOSTLIBS)-y) |
11241 |
+ |
11242 |
+rap_plugin-objs := $(patsubst $(srctree)/$(src)/%.c,%.o,$(wildcard $(srctree)/$(src)/*.c)) |
11243 |
-diff --git a/tools/gcc/rap_plugin/rap.h b/tools/gcc/rap_plugin/rap.h |
11244 |
+diff --git a/scripts/gcc-plugins/rap_plugin/rap.h b/scripts/gcc-plugins/rap_plugin/rap.h |
11245 |
new file mode 100644 |
11246 |
index 0000000..f6a284d |
11247 |
--- /dev/null |
11248 |
-+++ b/tools/gcc/rap_plugin/rap.h |
11249 |
++++ b/scripts/gcc-plugins/rap_plugin/rap.h |
11250 |
@@ -0,0 +1,36 @@ |
11251 |
+#ifndef RAP_H_INCLUDED |
11252 |
+#define RAP_H_INCLUDED |
11253 |
@@ -169614,11 +166902,11 @@ index 0000000..f6a284d |
11254 |
+#endif |
11255 |
+ |
11256 |
+#endif |
11257 |
-diff --git a/tools/gcc/rap_plugin/rap_fptr_pass.c b/tools/gcc/rap_plugin/rap_fptr_pass.c |
11258 |
+diff --git a/scripts/gcc-plugins/rap_plugin/rap_fptr_pass.c b/scripts/gcc-plugins/rap_plugin/rap_fptr_pass.c |
11259 |
new file mode 100644 |
11260 |
index 0000000..2f53f14 |
11261 |
--- /dev/null |
11262 |
-+++ b/tools/gcc/rap_plugin/rap_fptr_pass.c |
11263 |
++++ b/scripts/gcc-plugins/rap_plugin/rap_fptr_pass.c |
11264 |
@@ -0,0 +1,220 @@ |
11265 |
+/* |
11266 |
+ * Copyright 2012-2016 by PaX Team <pageexec@××××××××.hu> |
11267 |
@@ -169840,11 +167128,11 @@ index 0000000..2f53f14 |
11268 |
+#define PASS_NAME rap_fptr |
11269 |
+#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_remove_unused_locals | TODO_update_ssa | TODO_cleanup_cfg | TODO_rebuild_cgraph_edges | TODO_verify_flow |
11270 |
+#include "gcc-generate-gimple-pass.h" |
11271 |
-diff --git a/tools/gcc/rap_plugin/rap_hash.c b/tools/gcc/rap_plugin/rap_hash.c |
11272 |
+diff --git a/scripts/gcc-plugins/rap_plugin/rap_hash.c b/scripts/gcc-plugins/rap_plugin/rap_hash.c |
11273 |
new file mode 100644 |
11274 |
index 0000000..7c59f38 |
11275 |
--- /dev/null |
11276 |
-+++ b/tools/gcc/rap_plugin/rap_hash.c |
11277 |
++++ b/scripts/gcc-plugins/rap_plugin/rap_hash.c |
11278 |
@@ -0,0 +1,382 @@ |
11279 |
+/* |
11280 |
+ * Copyright 2012-2016 by PaX Team <pageexec@××××××××.hu> |
11281 |
@@ -170228,11 +167516,11 @@ index 0000000..7c59f38 |
11282 |
+ gcc_assert(rap_imprecise_hashes[uid].hash); |
11283 |
+ } |
11284 |
+} |
11285 |
-diff --git a/tools/gcc/rap_plugin/rap_plugin.c b/tools/gcc/rap_plugin/rap_plugin.c |
11286 |
+diff --git a/scripts/gcc-plugins/rap_plugin/rap_plugin.c b/scripts/gcc-plugins/rap_plugin/rap_plugin.c |
11287 |
new file mode 100644 |
11288 |
index 0000000..bca74dc |
11289 |
--- /dev/null |
11290 |
-+++ b/tools/gcc/rap_plugin/rap_plugin.c |
11291 |
++++ b/scripts/gcc-plugins/rap_plugin/rap_plugin.c |
11292 |
@@ -0,0 +1,511 @@ |
11293 |
+/* |
11294 |
+ * Copyright 2012-2016 by PaX Team <pageexec@××××××××.hu> |
11295 |
@@ -170745,11 +168033,11 @@ index 0000000..bca74dc |
11296 |
+ |
11297 |
+ return 0; |
11298 |
+} |
11299 |
-diff --git a/tools/gcc/rap_plugin/sip.c b/tools/gcc/rap_plugin/sip.c |
11300 |
+diff --git a/scripts/gcc-plugins/rap_plugin/sip.c b/scripts/gcc-plugins/rap_plugin/sip.c |
11301 |
new file mode 100644 |
11302 |
index 0000000..65bc1cd |
11303 |
--- /dev/null |
11304 |
-+++ b/tools/gcc/rap_plugin/sip.c |
11305 |
++++ b/scripts/gcc-plugins/rap_plugin/sip.c |
11306 |
@@ -0,0 +1,96 @@ |
11307 |
+// SipHash-2-4 adapted by the PaX Team from the public domain version written by |
11308 |
+// Jean-Philippe Aumasson <jeanphilippe.aumasson@×××××.com> |
11309 |
@@ -170847,20 +168135,20 @@ index 0000000..65bc1cd |
11310 |
+ b = v0 ^ v1 ^ v2 ^ v3; |
11311 |
+ U64TO8_LE(out, b); |
11312 |
+} |
11313 |
-diff --git a/tools/gcc/size_overflow_plugin/.gitignore b/tools/gcc/size_overflow_plugin/.gitignore |
11314 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/.gitignore b/scripts/gcc-plugins/size_overflow_plugin/.gitignore |
11315 |
new file mode 100644 |
11316 |
index 0000000..c4b24b9 |
11317 |
--- /dev/null |
11318 |
-+++ b/tools/gcc/size_overflow_plugin/.gitignore |
11319 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/.gitignore |
11320 |
@@ -0,0 +1,3 @@ |
11321 |
+disable_size_overflow_hash.h |
11322 |
+size_overflow_hash.h |
11323 |
+size_overflow_hash_aux.h |
11324 |
-diff --git a/tools/gcc/size_overflow_plugin/Makefile b/tools/gcc/size_overflow_plugin/Makefile |
11325 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/Makefile b/scripts/gcc-plugins/size_overflow_plugin/Makefile |
11326 |
new file mode 100644 |
11327 |
index 0000000..f74d85a |
11328 |
--- /dev/null |
11329 |
-+++ b/tools/gcc/size_overflow_plugin/Makefile |
11330 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/Makefile |
11331 |
@@ -0,0 +1,28 @@ |
11332 |
+HOST_EXTRACXXFLAGS += $(call hostcc-option, -fno-ipa-icf) |
11333 |
+ |
11334 |
@@ -170890,11 +168178,11 @@ index 0000000..f74d85a |
11335 |
+ $(call if_changed,build_disable_size_overflow_hash) |
11336 |
+ |
11337 |
+targets += size_overflow_hash.h size_overflow_hash_aux.h disable_size_overflow_hash.h |
11338 |
-diff --git a/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data |
11339 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/disable_size_overflow_hash.data b/scripts/gcc-plugins/size_overflow_plugin/disable_size_overflow_hash.data |
11340 |
new file mode 100644 |
11341 |
index 0000000..2a420f3 |
11342 |
--- /dev/null |
11343 |
-+++ b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data |
11344 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/disable_size_overflow_hash.data |
11345 |
@@ -0,0 +1,12444 @@ |
11346 |
+disable_so_interrupt_pnode_gru_message_queue_desc_4 interrupt_pnode gru_message_queue_desc 0 4 NULL |
11347 |
+disable_so_bch_btree_insert_fndecl_12 bch_btree_insert fndecl 0 12 NULL |
11348 |
@@ -183340,11 +180628,11 @@ index 0000000..2a420f3 |
11349 |
+enable_so_inofree_iagctl_5194 inofree iagctl 0 5194 NULL |
11350 |
+enable_so_inofreefwd_iag_4921 inofreefwd iag 0 4921 NULL |
11351 |
+enable_so_iagnum_iag_23227 iagnum iag 0 23227 NULL |
11352 |
-diff --git a/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh |
11353 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/generate_size_overflow_hash.sh b/scripts/gcc-plugins/size_overflow_plugin/generate_size_overflow_hash.sh |
11354 |
new file mode 100644 |
11355 |
index 0000000..be9724d |
11356 |
--- /dev/null |
11357 |
-+++ b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh |
11358 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/generate_size_overflow_hash.sh |
11359 |
@@ -0,0 +1,103 @@ |
11360 |
+#!/bin/bash |
11361 |
+ |
11362 |
@@ -183449,11 +180737,11 @@ index 0000000..be9724d |
11363 |
+create_array_elements |
11364 |
+ |
11365 |
+exit 0 |
11366 |
-diff --git a/tools/gcc/size_overflow_plugin/insert_size_overflow_asm.c b/tools/gcc/size_overflow_plugin/insert_size_overflow_asm.c |
11367 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/insert_size_overflow_asm.c b/scripts/gcc-plugins/size_overflow_plugin/insert_size_overflow_asm.c |
11368 |
new file mode 100644 |
11369 |
index 0000000..ee987da |
11370 |
--- /dev/null |
11371 |
-+++ b/tools/gcc/size_overflow_plugin/insert_size_overflow_asm.c |
11372 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/insert_size_overflow_asm.c |
11373 |
@@ -0,0 +1,369 @@ |
11374 |
+/* |
11375 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
11376 |
@@ -183824,11 +181112,11 @@ index 0000000..ee987da |
11377 |
+#define TODO_FLAGS_FINISH TODO_dump_func | TODO_verify_ssa | TODO_verify_stmts | TODO_remove_unused_locals | TODO_update_ssa_no_phi | TODO_cleanup_cfg | TODO_ggc_collect | TODO_verify_flow |
11378 |
+ |
11379 |
+#include "gcc-generate-gimple-pass.h" |
11380 |
-diff --git a/tools/gcc/size_overflow_plugin/intentional_overflow.c b/tools/gcc/size_overflow_plugin/intentional_overflow.c |
11381 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/intentional_overflow.c b/scripts/gcc-plugins/size_overflow_plugin/intentional_overflow.c |
11382 |
new file mode 100644 |
11383 |
-index 0000000..6fcc436 |
11384 |
+index 0000000..f29aac6 |
11385 |
--- /dev/null |
11386 |
-+++ b/tools/gcc/size_overflow_plugin/intentional_overflow.c |
11387 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/intentional_overflow.c |
11388 |
@@ -0,0 +1,1166 @@ |
11389 |
+/* |
11390 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
11391 |
@@ -184963,7 +182251,7 @@ index 0000000..6fcc436 |
11392 |
+{ |
11393 |
+ const_tree rhs, lhs_type, rhs_type; |
11394 |
+ const_tree def_rhs1, def_rhs2; |
11395 |
-+ gimple def_stmt; |
11396 |
++ const_gimple def_stmt; |
11397 |
+ gimple def_def_stmt = NULL; |
11398 |
+ |
11399 |
+ if (!gimple_assign_cast_p(stmt)) |
11400 |
@@ -184996,11 +182284,11 @@ index 0000000..6fcc436 |
11401 |
+ // _36 = (signed short) _35; |
11402 |
+ return def_def_stmt && gimple_assign_cast_p(def_def_stmt); |
11403 |
+} |
11404 |
-diff --git a/tools/gcc/size_overflow_plugin/remove_unnecessary_dup.c b/tools/gcc/size_overflow_plugin/remove_unnecessary_dup.c |
11405 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/remove_unnecessary_dup.c b/scripts/gcc-plugins/size_overflow_plugin/remove_unnecessary_dup.c |
11406 |
new file mode 100644 |
11407 |
index 0000000..c910983 |
11408 |
--- /dev/null |
11409 |
-+++ b/tools/gcc/size_overflow_plugin/remove_unnecessary_dup.c |
11410 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/remove_unnecessary_dup.c |
11411 |
@@ -0,0 +1,137 @@ |
11412 |
+/* |
11413 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
11414 |
@@ -185139,11 +182427,11 @@ index 0000000..c910983 |
11415 |
+ } |
11416 |
+} |
11417 |
+ |
11418 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow.h b/tools/gcc/size_overflow_plugin/size_overflow.h |
11419 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow.h b/scripts/gcc-plugins/size_overflow_plugin/size_overflow.h |
11420 |
new file mode 100644 |
11421 |
index 0000000..4bd2e7f |
11422 |
--- /dev/null |
11423 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow.h |
11424 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow.h |
11425 |
@@ -0,0 +1,331 @@ |
11426 |
+#ifndef SIZE_OVERFLOW_H |
11427 |
+#define SIZE_OVERFLOW_H |
11428 |
@@ -185476,11 +182764,11 @@ index 0000000..4bd2e7f |
11429 |
+extern const char * __unused print_intentional_mark_name(enum intentional_mark mark); |
11430 |
+ |
11431 |
+#endif |
11432 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_debug.c b/tools/gcc/size_overflow_plugin/size_overflow_debug.c |
11433 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_debug.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_debug.c |
11434 |
new file mode 100644 |
11435 |
index 0000000..4098952 |
11436 |
--- /dev/null |
11437 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_debug.c |
11438 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_debug.c |
11439 |
@@ -0,0 +1,194 @@ |
11440 |
+/* |
11441 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
11442 |
@@ -185676,11 +182964,11 @@ index 0000000..4098952 |
11443 |
+ |
11444 |
+ gcc_unreachable(); |
11445 |
+} |
11446 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data |
11447 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data |
11448 |
new file mode 100644 |
11449 |
index 0000000..cbb8a80 |
11450 |
--- /dev/null |
11451 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data |
11452 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data |
11453 |
@@ -0,0 +1,21645 @@ |
11454 |
+enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL |
11455 |
+enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL |
11456 |
@@ -207327,11 +204615,11 @@ index 0000000..cbb8a80 |
11457 |
+enable_so_write_page_nocow_fndecl_65527 write_page_nocow fndecl 2 65527 NULL |
11458 |
+enable_so_size_mei_msg_data_65529 size mei_msg_data 0 65529 NULL |
11459 |
+enable_so_connector_write_fndecl_65534 connector_write fndecl 3 65534 NULL |
11460 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash_aux.data b/tools/gcc/size_overflow_plugin/size_overflow_hash_aux.data |
11461 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash_aux.data b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash_aux.data |
11462 |
new file mode 100644 |
11463 |
index 0000000..17bc0d8 |
11464 |
--- /dev/null |
11465 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_hash_aux.data |
11466 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash_aux.data |
11467 |
@@ -0,0 +1,92 @@ |
11468 |
+enable_so_spa_set_aux_vdevs_fndecl_746 spa_set_aux_vdevs fndecl 3 746 NULL |
11469 |
+enable_so_zfs_lookup_fndecl_2144 zfs_lookup fndecl 0 2144 NULL |
11470 |
@@ -207425,11 +204713,11 @@ index 0000000..17bc0d8 |
11471 |
+enable_so_proc_copyin_string_fndecl_62019 proc_copyin_string fndecl 4 62019 NULL |
11472 |
+enable_so_random_get_pseudo_bytes_fndecl_64611 random_get_pseudo_bytes fndecl 2 64611 NULL |
11473 |
+enable_so_zpios_read_fndecl_64734 zpios_read fndecl 3 64734 NULL |
11474 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_ipa.c b/tools/gcc/size_overflow_plugin/size_overflow_ipa.c |
11475 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_ipa.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_ipa.c |
11476 |
new file mode 100644 |
11477 |
index 0000000..0a679f8 |
11478 |
--- /dev/null |
11479 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_ipa.c |
11480 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_ipa.c |
11481 |
@@ -0,0 +1,1163 @@ |
11482 |
+/* |
11483 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
11484 |
@@ -207445,1161 +204733,2326 @@ index 0000000..0a679f8 |
11485 |
+ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
11486 |
+ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
11487 |
+ * |
11488 |
-+ * Usage: |
11489 |
-+ * $ make |
11490 |
-+ * $ make run |
11491 |
++ * Usage: |
11492 |
++ * $ make |
11493 |
++ * $ make run |
11494 |
++ */ |
11495 |
++ |
11496 |
++#include "size_overflow.h" |
11497 |
++#include <libgen.h> |
11498 |
++ |
11499 |
++static void walk_use_def_next_functions(struct walk_use_def_data *use_def_data, tree lhs); |
11500 |
++ |
11501 |
++next_interesting_function_t global_next_interesting_function[GLOBAL_NIFN_LEN]; |
11502 |
++static bool global_changed; |
11503 |
++#define PRINT_DATA_FLOW true |
11504 |
++#define NO_PRINT_DATA_FLOW false |
11505 |
++ |
11506 |
++static struct cgraph_node_hook_list *function_insertion_hook_holder; |
11507 |
++static struct cgraph_2node_hook_list *node_duplication_hook_holder; |
11508 |
++ |
11509 |
++struct cgraph_node *get_cnode(const_tree fndecl) |
11510 |
++{ |
11511 |
++ gcc_assert(TREE_CODE(fndecl) == FUNCTION_DECL); |
11512 |
++#if BUILDING_GCC_VERSION <= 4005 |
11513 |
++ return cgraph_get_node(CONST_CAST_TREE(fndecl)); |
11514 |
++#else |
11515 |
++ return cgraph_get_node(fndecl); |
11516 |
++#endif |
11517 |
++} |
11518 |
++ |
11519 |
++static bool compare_next_interesting_functions(next_interesting_function_t cur_node, const char *decl_name, const char *context, unsigned int num) |
11520 |
++{ |
11521 |
++ // Ignore num without a value |
11522 |
++ if (num != NONE_ARGNUM && cur_node->num != num) |
11523 |
++ return false; |
11524 |
++ if (strcmp(cur_node->context, context)) |
11525 |
++ return false; |
11526 |
++ return !strcmp(cur_node->decl_name, decl_name); |
11527 |
++} |
11528 |
++ |
11529 |
++// Return the context of vardecl. If it is in a file scope then the context is vardecl_filebasename |
11530 |
++static const char* get_vardecl_context(const_tree decl) |
11531 |
++{ |
11532 |
++ expanded_location xloc; |
11533 |
++ char *buf, *path; |
11534 |
++ const char *bname; |
11535 |
++ int len; |
11536 |
++ |
11537 |
++ xloc = expand_location(DECL_SOURCE_LOCATION(decl)); |
11538 |
++ gcc_assert(xloc.file); |
11539 |
++ path = xstrdup(xloc.file); |
11540 |
++ bname = basename(path); |
11541 |
++ |
11542 |
++ len = asprintf(&buf, "vardecl_%s", bname); |
11543 |
++ gcc_assert(len > 0); |
11544 |
++ return buf; |
11545 |
++} |
11546 |
++ |
11547 |
++// Return the type name for a function pointer (or "fielddecl" if the type has no name), otherwise either "vardecl" or "fndecl" |
11548 |
++const char* get_decl_context(const_tree decl) |
11549 |
++{ |
11550 |
++ switch (TREE_CODE(decl)) { |
11551 |
++ case FUNCTION_DECL: |
11552 |
++ return "fndecl"; |
11553 |
++ // TODO: Ignore anonymous types for now |
11554 |
++ case FIELD_DECL: |
11555 |
++ return get_type_name_from_field(decl); |
11556 |
++ case VAR_DECL: |
11557 |
++ if (TREE_PUBLIC(decl) || DECL_EXTERNAL(decl)) |
11558 |
++ return "vardecl"; |
11559 |
++ if (TREE_STATIC(decl) && !TREE_PUBLIC(decl)) |
11560 |
++ return get_vardecl_context(decl); |
11561 |
++ // ignore local variable |
11562 |
++ if (!TREE_STATIC(decl) && !DECL_EXTERNAL(decl)) |
11563 |
++ return NULL; |
11564 |
++ default: |
11565 |
++ debug_tree(decl); |
11566 |
++ gcc_unreachable(); |
11567 |
++ } |
11568 |
++} |
11569 |
++ |
11570 |
++// Find the function with the specified argument in the list |
11571 |
++next_interesting_function_t get_global_next_interesting_function_entry(struct fn_raw_data *raw_data) |
11572 |
++{ |
11573 |
++ next_interesting_function_t cur_node, head; |
11574 |
++ |
11575 |
++ head = global_next_interesting_function[raw_data->hash]; |
11576 |
++ for (cur_node = head; cur_node; cur_node = cur_node->next) { |
11577 |
++ if (raw_data->marked != ASM_STMT_SO_MARK && cur_node->marked == ASM_STMT_SO_MARK) |
11578 |
++ continue; |
11579 |
++ if (compare_next_interesting_functions(cur_node, raw_data->decl_str, raw_data->context, raw_data->num)) |
11580 |
++ return cur_node; |
11581 |
++ } |
11582 |
++ return NULL; |
11583 |
++} |
11584 |
++ |
11585 |
++next_interesting_function_t get_global_next_interesting_function_entry_with_hash(struct fn_raw_data *raw_data) |
11586 |
++{ |
11587 |
++ raw_data->hash = get_decl_hash(raw_data->decl, raw_data->decl_str); |
11588 |
++ if (raw_data->hash == NO_HASH) |
11589 |
++ return NULL; |
11590 |
++ |
11591 |
++ raw_data->context = get_decl_context(raw_data->decl); |
11592 |
++ if (!raw_data->context) |
11593 |
++ return NULL; |
11594 |
++ return get_global_next_interesting_function_entry(raw_data); |
11595 |
++} |
11596 |
++ |
11597 |
++next_interesting_function_t create_new_next_interesting_entry(struct fn_raw_data *raw_data, next_interesting_function_t orig_next_node) |
11598 |
++{ |
11599 |
++ next_interesting_function_t new_node; |
11600 |
++ |
11601 |
++ new_node = (next_interesting_function_t)xmalloc(sizeof(*new_node)); |
11602 |
++ new_node->decl_name = xstrdup(raw_data->decl_str); |
11603 |
++ |
11604 |
++ gcc_assert(raw_data->context); |
11605 |
++ new_node->context = xstrdup(raw_data->context); |
11606 |
++ new_node->hash = raw_data->hash; |
11607 |
++ new_node->num = raw_data->num; |
11608 |
++ new_node->next = NULL; |
11609 |
++ new_node->children = NULL; |
11610 |
++ new_node->marked = raw_data->marked; |
11611 |
++ new_node->orig_next_node = orig_next_node; |
11612 |
++ return new_node; |
11613 |
++} |
11614 |
++ |
11615 |
++// Ignore these functions to not explode coverage (+strncmp+fndecl+3+35130+) |
11616 |
++static bool temporary_skip_these_functions(struct fn_raw_data *raw_data) |
11617 |
++{ |
11618 |
++ if (raw_data->hash == 35130 && !strcmp(raw_data->decl_str, "strncmp")) |
11619 |
++ return true; |
11620 |
++ if (raw_data->hash == 46193 && !strcmp(raw_data->decl_str, "strnlen")) |
11621 |
++ return true; |
11622 |
++ if (raw_data->hash == 43267 && !strcmp(raw_data->decl_str, "strncpy")) |
11623 |
++ return true; |
11624 |
++ if (raw_data->hash == 10300 && !strcmp(raw_data->decl_str, "strncpy_from_user")) |
11625 |
++ return true; |
11626 |
++ if (raw_data->hash == 26117 && !strcmp(raw_data->decl_str, "memchr")) |
11627 |
++ return true; |
11628 |
++ if (raw_data->hash == 16203 && !strcmp(raw_data->decl_str, "memchr_inv")) |
11629 |
++ return true; |
11630 |
++ if (raw_data->hash == 24269 && !strcmp(raw_data->decl_str, "memcmp")) |
11631 |
++ return true; |
11632 |
++ if (raw_data->hash == 60390 && !strcmp(raw_data->decl_str, "memcpy")) |
11633 |
++ return true; |
11634 |
++ if (raw_data->hash == 25040 && !strcmp(raw_data->decl_str, "memmove")) |
11635 |
++ return true; |
11636 |
++ if (raw_data->hash == 29763 && !strcmp(raw_data->decl_str, "memset")) |
11637 |
++ return true; |
11638 |
++ return false; |
11639 |
++} |
11640 |
++ |
11641 |
++// Create the main data structure |
11642 |
++next_interesting_function_t create_new_next_interesting_decl(struct fn_raw_data *raw_data, next_interesting_function_t orig_next_node) |
11643 |
++{ |
11644 |
++ enum tree_code decl_code = TREE_CODE(raw_data->decl); |
11645 |
++ |
11646 |
++ gcc_assert(decl_code == FIELD_DECL || decl_code == FUNCTION_DECL || decl_code == VAR_DECL); |
11647 |
++ |
11648 |
++ if (is_vararg(raw_data->decl, raw_data->num)) |
11649 |
++ return NULL; |
11650 |
++ |
11651 |
++ raw_data->hash = get_decl_hash(raw_data->decl, raw_data->decl_str); |
11652 |
++ if (raw_data->hash == NO_HASH) |
11653 |
++ return NULL; |
11654 |
++ if (get_size_overflow_hash_entry_tree(raw_data->decl, raw_data->num, DISABLE_SIZE_OVERFLOW)) |
11655 |
++ return NULL; |
11656 |
++ if (temporary_skip_these_functions(raw_data)) |
11657 |
++ return NULL; |
11658 |
++ |
11659 |
++ gcc_assert(raw_data->num <= MAX_PARAM); |
11660 |
++ // Clones must have an orig_next_node |
11661 |
++ gcc_assert(!made_by_compiler(raw_data->decl) || orig_next_node); |
11662 |
++ |
11663 |
++ raw_data->context = get_decl_context(raw_data->decl); |
11664 |
++ if (!raw_data->context) |
11665 |
++ return NULL; |
11666 |
++ return create_new_next_interesting_entry(raw_data, orig_next_node); |
11667 |
++} |
11668 |
++ |
11669 |
++void add_to_global_next_interesting_function(next_interesting_function_t new_entry) |
11670 |
++{ |
11671 |
++ next_interesting_function_t cur_global_head, cur_global, cur_global_end = NULL; |
11672 |
++ |
11673 |
++ // new_entry is appended to the end of a list |
11674 |
++ new_entry->next = NULL; |
11675 |
++ |
11676 |
++ cur_global_head = global_next_interesting_function[new_entry->hash]; |
11677 |
++ if (!cur_global_head) { |
11678 |
++ global_next_interesting_function[new_entry->hash] = new_entry; |
11679 |
++ return; |
11680 |
++ } |
11681 |
++ |
11682 |
++ |
11683 |
++ for (cur_global = cur_global_head; cur_global; cur_global = cur_global->next) { |
11684 |
++ if (!cur_global->next) |
11685 |
++ cur_global_end = cur_global; |
11686 |
++ |
11687 |
++ if (compare_next_interesting_functions(cur_global, new_entry->decl_name, new_entry->context, new_entry->num)) |
11688 |
++ return; |
11689 |
++ } |
11690 |
++ |
11691 |
++ gcc_assert(cur_global_end); |
11692 |
++ cur_global_end->next = new_entry; |
11693 |
++} |
11694 |
++ |
11695 |
++/* If the interesting function is a clone then find or create its original next_interesting_function_t node |
11696 |
++ * and add it to global_next_interesting_function |
11697 |
++ */ |
11698 |
++static next_interesting_function_t create_orig_next_node_for_a_clone(struct fn_raw_data *clone_raw_data) |
11699 |
++{ |
11700 |
++ struct fn_raw_data orig_raw_data; |
11701 |
++ next_interesting_function_t orig_next_node; |
11702 |
++ enum tree_code decl_code; |
11703 |
++ |
11704 |
++ orig_raw_data.decl = get_orig_fndecl(clone_raw_data->decl); |
11705 |
++ |
11706 |
++ if (DECL_BUILT_IN(orig_raw_data.decl) || DECL_BUILT_IN_CLASS(orig_raw_data.decl) == BUILT_IN_NORMAL) |
11707 |
++ return NULL; |
11708 |
++ |
11709 |
++ if (made_by_compiler(orig_raw_data.decl)) |
11710 |
++ return NULL; |
11711 |
++ |
11712 |
++ decl_code = TREE_CODE(orig_raw_data.decl); |
11713 |
++ if (decl_code == FIELD_DECL || decl_code == VAR_DECL) |
11714 |
++ orig_raw_data.num = clone_raw_data->num; |
11715 |
++ else |
11716 |
++ orig_raw_data.num = get_correct_argnum(clone_raw_data->decl, orig_raw_data.decl, clone_raw_data->num); |
11717 |
++ |
11718 |
++ // Skip over ISRA.162 parm decls |
11719 |
++ if (orig_raw_data.num == CANNOT_FIND_ARG) |
11720 |
++ return NULL; |
11721 |
++ |
11722 |
++ orig_raw_data.decl_str = get_orig_decl_name(orig_raw_data.decl); |
11723 |
++ orig_raw_data.marked = NO_SO_MARK; |
11724 |
++ orig_next_node = get_global_next_interesting_function_entry_with_hash(&orig_raw_data); |
11725 |
++ if (orig_next_node) |
11726 |
++ return orig_next_node; |
11727 |
++ |
11728 |
++ orig_raw_data.marked = clone_raw_data->marked; |
11729 |
++ orig_next_node = create_new_next_interesting_decl(&orig_raw_data, NULL); |
11730 |
++ if (!orig_next_node) |
11731 |
++ return NULL; |
11732 |
++ |
11733 |
++ add_to_global_next_interesting_function(orig_next_node); |
11734 |
++ return orig_next_node; |
11735 |
++} |
11736 |
++ |
11737 |
++// Find or create the next_interesting_function_t node for decl and num |
11738 |
++next_interesting_function_t get_and_create_next_node_from_global_next_nodes(struct fn_raw_data *raw_data, next_interesting_function_t orig_next_node) |
11739 |
++{ |
11740 |
++ next_interesting_function_t cur_next_cnode; |
11741 |
++ |
11742 |
++ if (DECL_NAME(raw_data->decl) == NULL_TREE) |
11743 |
++ return NULL; |
11744 |
++ raw_data->decl_str = DECL_NAME_POINTER(raw_data->decl); |
11745 |
++ |
11746 |
++ cur_next_cnode = get_global_next_interesting_function_entry_with_hash(raw_data); |
11747 |
++ if (cur_next_cnode) |
11748 |
++ goto out; |
11749 |
++ |
11750 |
++ if (!orig_next_node && made_by_compiler(raw_data->decl)) { |
11751 |
++ orig_next_node = create_orig_next_node_for_a_clone(raw_data); |
11752 |
++ if (!orig_next_node) |
11753 |
++ return NULL; |
11754 |
++ } |
11755 |
++ |
11756 |
++ cur_next_cnode = create_new_next_interesting_decl(raw_data, orig_next_node); |
11757 |
++ if (!cur_next_cnode) |
11758 |
++ return NULL; |
11759 |
++ |
11760 |
++ add_to_global_next_interesting_function(cur_next_cnode); |
11761 |
++out: |
11762 |
++ if (cur_next_cnode->marked != raw_data->marked && cur_next_cnode->marked != NO_SO_MARK) |
11763 |
++ return cur_next_cnode; |
11764 |
++ |
11765 |
++ if (raw_data->marked != NO_SO_MARK && cur_next_cnode->marked == NO_SO_MARK) |
11766 |
++ cur_next_cnode->marked = raw_data->marked; |
11767 |
++ |
11768 |
++ return cur_next_cnode; |
11769 |
++} |
11770 |
++ |
11771 |
++static bool has_next_interesting_function_chain_node(next_interesting_function_t next_cnodes_head, struct fn_raw_data *raw_data) |
11772 |
++{ |
11773 |
++ next_interesting_function_t cur_node; |
11774 |
++ |
11775 |
++ raw_data->decl_str = DECL_NAME_POINTER(raw_data->decl); |
11776 |
++ raw_data->context = get_decl_context(raw_data->decl); |
11777 |
++ // Ignore function if there is no context |
11778 |
++ if (!raw_data->context) |
11779 |
++ return true; |
11780 |
++ |
11781 |
++ for (cur_node = next_cnodes_head; cur_node; cur_node = cur_node->next) { |
11782 |
++ if (compare_next_interesting_functions(cur_node, raw_data->decl_str, raw_data->context, raw_data->num)) |
11783 |
++ return true; |
11784 |
++ } |
11785 |
++ return false; |
11786 |
++} |
11787 |
++ |
11788 |
++static void handle_function(struct walk_use_def_data *use_def_data, tree fndecl, const_tree arg) |
11789 |
++{ |
11790 |
++ struct fn_raw_data raw_data; |
11791 |
++ next_interesting_function_t orig_next_node, new_node; |
11792 |
++ |
11793 |
++ gcc_assert(fndecl != NULL_TREE); |
11794 |
++ |
11795 |
++ // ignore builtins to not explode coverage (e.g., memcpy) |
11796 |
++ if (DECL_BUILT_IN(fndecl) || DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL) |
11797 |
++ return; |
11798 |
++ |
11799 |
++ if (get_intentional_attr_type(fndecl) == MARK_TURN_OFF) |
11800 |
++ return; |
11801 |
++ |
11802 |
++ raw_data.decl = fndecl; |
11803 |
++ raw_data.decl_str = DECL_NAME_POINTER(fndecl); |
11804 |
++ raw_data.marked = NO_SO_MARK; |
11805 |
++ |
11806 |
++ // convert arg into its position |
11807 |
++ if (arg == NULL_TREE) |
11808 |
++ raw_data.num = 0; |
11809 |
++ else |
11810 |
++ raw_data.num = find_arg_number_tree(arg, raw_data.decl); |
11811 |
++ if (raw_data.num == CANNOT_FIND_ARG) |
11812 |
++ return; |
11813 |
++ |
11814 |
++ if (has_next_interesting_function_chain_node(use_def_data->next_cnodes_head, &raw_data)) |
11815 |
++ return; |
11816 |
++ |
11817 |
++ if (made_by_compiler(raw_data.decl)) { |
11818 |
++ orig_next_node = create_orig_next_node_for_a_clone(&raw_data); |
11819 |
++ if (!orig_next_node) |
11820 |
++ return; |
11821 |
++ } else |
11822 |
++ orig_next_node = NULL; |
11823 |
++ |
11824 |
++ new_node = create_new_next_interesting_decl(&raw_data, orig_next_node); |
11825 |
++ if (!new_node) |
11826 |
++ return; |
11827 |
++ new_node->next = use_def_data->next_cnodes_head; |
11828 |
++ use_def_data->next_cnodes_head = new_node; |
11829 |
++} |
11830 |
++ |
11831 |
++static void walk_use_def_next_functions_phi(struct walk_use_def_data *use_def_data, const_tree result) |
11832 |
++{ |
11833 |
++ gphi *phi = as_a_gphi(get_def_stmt(result)); |
11834 |
++ unsigned int i, n = gimple_phi_num_args(phi); |
11835 |
++ |
11836 |
++ pointer_set_insert(use_def_data->visited, phi); |
11837 |
++ for (i = 0; i < n; i++) { |
11838 |
++ tree arg = gimple_phi_arg_def(phi, i); |
11839 |
++ |
11840 |
++ walk_use_def_next_functions(use_def_data, arg); |
11841 |
++ } |
11842 |
++} |
11843 |
++ |
11844 |
++static void walk_use_def_next_functions_binary(struct walk_use_def_data *use_def_data, const_tree lhs) |
11845 |
++{ |
11846 |
++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); |
11847 |
++ tree rhs1, rhs2; |
11848 |
++ |
11849 |
++ rhs1 = gimple_assign_rhs1(def_stmt); |
11850 |
++ rhs2 = gimple_assign_rhs2(def_stmt); |
11851 |
++ |
11852 |
++ walk_use_def_next_functions(use_def_data, rhs1); |
11853 |
++ walk_use_def_next_functions(use_def_data, rhs2); |
11854 |
++} |
11855 |
++ |
11856 |
++static void walk_use_def_next_functions_unary(struct walk_use_def_data *use_def_data, const gassign *stmt) |
11857 |
++{ |
11858 |
++ tree rhs1 = gimple_assign_rhs1(stmt); |
11859 |
++ |
11860 |
++ walk_use_def_next_functions(use_def_data, rhs1); |
11861 |
++} |
11862 |
++ |
11863 |
++void __attribute__((weak)) handle_function_ptr_ret(struct walk_use_def_data *use_def_data __unused, const_tree fn_ptr __unused) |
11864 |
++{ |
11865 |
++} |
11866 |
++ |
11867 |
++static void create_and_append_new_next_interesting_field_var_decl(struct walk_use_def_data *use_def_data, struct fn_raw_data *raw_data) |
11868 |
++{ |
11869 |
++ next_interesting_function_t new_node; |
11870 |
++ |
11871 |
++ if (raw_data->decl == NULL_TREE) |
11872 |
++ return; |
11873 |
++ |
11874 |
++ if (DECL_NAME(raw_data->decl) == NULL_TREE) |
11875 |
++ return; |
11876 |
++ |
11877 |
++ raw_data->decl_str = DECL_NAME_POINTER(raw_data->decl); |
11878 |
++ raw_data->num = 0; |
11879 |
++ raw_data->marked = NO_SO_MARK; |
11880 |
++ |
11881 |
++ new_node = create_new_next_interesting_decl(raw_data, NULL); |
11882 |
++ if (!new_node) |
11883 |
++ return; |
11884 |
++ new_node->next = use_def_data->next_cnodes_head; |
11885 |
++ use_def_data->next_cnodes_head = new_node; |
11886 |
++} |
11887 |
++ |
11888 |
++static void handle_struct_fields(struct walk_use_def_data *use_def_data, const_tree node) |
11889 |
++{ |
11890 |
++ struct fn_raw_data raw_data; |
11891 |
++ |
11892 |
++ switch (TREE_CODE(node)) { |
11893 |
++ case ARRAY_REF: |
11894 |
++#if BUILDING_GCC_VERSION >= 4006 |
11895 |
++ case MEM_REF: |
11896 |
++#endif |
11897 |
++ case INDIRECT_REF: |
11898 |
++ case COMPONENT_REF: |
11899 |
++ raw_data.decl = get_ref_field(node); |
11900 |
++ break; |
11901 |
++ // TODO |
11902 |
++ case BIT_FIELD_REF: |
11903 |
++ case VIEW_CONVERT_EXPR: |
11904 |
++ case REALPART_EXPR: |
11905 |
++ case IMAGPART_EXPR: |
11906 |
++ return; |
11907 |
++ default: |
11908 |
++ debug_tree(node); |
11909 |
++ gcc_unreachable(); |
11910 |
++ } |
11911 |
++ |
11912 |
++ if (get_intentional_attr_type(raw_data.decl) == MARK_TURN_OFF) |
11913 |
++ return; |
11914 |
++ |
11915 |
++ create_and_append_new_next_interesting_field_var_decl(use_def_data, &raw_data); |
11916 |
++} |
11917 |
++ |
11918 |
++static void handle_vardecl(struct walk_use_def_data *use_def_data, tree node) |
11919 |
++{ |
11920 |
++ struct fn_raw_data raw_data; |
11921 |
++ |
11922 |
++ raw_data.decl = node; |
11923 |
++ create_and_append_new_next_interesting_field_var_decl(use_def_data, &raw_data); |
11924 |
++} |
11925 |
++ |
11926 |
++/* Find all functions that influence lhs |
11927 |
++ * |
11928 |
++ * Encountered functions are added to the children vector (next_interesting_function_t). |
11929 |
+ */ |
11930 |
++static void walk_use_def_next_functions(struct walk_use_def_data *use_def_data, tree lhs) |
11931 |
++{ |
11932 |
++ enum tree_code code; |
11933 |
++ const_gimple def_stmt; |
11934 |
+ |
11935 |
-+#include "size_overflow.h" |
11936 |
-+#include <libgen.h> |
11937 |
++ if (skip_types(lhs)) |
11938 |
++ return; |
11939 |
+ |
11940 |
-+static void walk_use_def_next_functions(struct walk_use_def_data *use_def_data, tree lhs); |
11941 |
++ if (VAR_P(lhs)) { |
11942 |
++ handle_vardecl(use_def_data, lhs); |
11943 |
++ return; |
11944 |
++ } |
11945 |
+ |
11946 |
-+next_interesting_function_t global_next_interesting_function[GLOBAL_NIFN_LEN]; |
11947 |
-+static bool global_changed; |
11948 |
-+#define PRINT_DATA_FLOW true |
11949 |
-+#define NO_PRINT_DATA_FLOW false |
11950 |
++ code = TREE_CODE(lhs); |
11951 |
++ if (code == PARM_DECL) { |
11952 |
++ handle_function(use_def_data, current_function_decl, lhs); |
11953 |
++ return; |
11954 |
++ } |
11955 |
+ |
11956 |
-+static struct cgraph_node_hook_list *function_insertion_hook_holder; |
11957 |
-+static struct cgraph_2node_hook_list *node_duplication_hook_holder; |
11958 |
++ if (TREE_CODE_CLASS(code) == tcc_reference) { |
11959 |
++ handle_struct_fields(use_def_data, lhs); |
11960 |
++ return; |
11961 |
++ } |
11962 |
+ |
11963 |
-+struct cgraph_node *get_cnode(const_tree fndecl) |
11964 |
++ if (code != SSA_NAME) |
11965 |
++ return; |
11966 |
++ |
11967 |
++ def_stmt = get_def_stmt(lhs); |
11968 |
++ if (!def_stmt) |
11969 |
++ return; |
11970 |
++ |
11971 |
++ if (pointer_set_insert(use_def_data->visited, def_stmt)) |
11972 |
++ return; |
11973 |
++ |
11974 |
++ switch (gimple_code(def_stmt)) { |
11975 |
++ case GIMPLE_NOP: |
11976 |
++ walk_use_def_next_functions(use_def_data, SSA_NAME_VAR(lhs)); |
11977 |
++ return; |
11978 |
++ case GIMPLE_ASM: |
11979 |
++ if (!is_size_overflow_asm(def_stmt)) |
11980 |
++ return; |
11981 |
++ walk_use_def_next_functions(use_def_data, get_size_overflow_asm_input(as_a_const_gasm(def_stmt))); |
11982 |
++ return; |
11983 |
++ case GIMPLE_CALL: { |
11984 |
++ tree fndecl = gimple_call_fndecl(def_stmt); |
11985 |
++ |
11986 |
++ if (fndecl != NULL_TREE) { |
11987 |
++ handle_function(use_def_data, fndecl, NULL_TREE); |
11988 |
++ return; |
11989 |
++ } |
11990 |
++ fndecl = gimple_call_fn(def_stmt); |
11991 |
++ handle_function_ptr_ret(use_def_data, fndecl); |
11992 |
++ return; |
11993 |
++ } |
11994 |
++ case GIMPLE_PHI: |
11995 |
++ walk_use_def_next_functions_phi(use_def_data, lhs); |
11996 |
++ return; |
11997 |
++ case GIMPLE_ASSIGN: |
11998 |
++ switch (gimple_num_ops(def_stmt)) { |
11999 |
++ case 2: |
12000 |
++ walk_use_def_next_functions_unary(use_def_data, as_a_const_gassign(def_stmt)); |
12001 |
++ return; |
12002 |
++ case 3: |
12003 |
++ walk_use_def_next_functions_binary(use_def_data, lhs); |
12004 |
++ return; |
12005 |
++ } |
12006 |
++ default: |
12007 |
++ debug_gimple_stmt((gimple)def_stmt); |
12008 |
++ error("%s: unknown gimple code", __func__); |
12009 |
++ gcc_unreachable(); |
12010 |
++ } |
12011 |
++} |
12012 |
++ |
12013 |
++// Start the search for next_interesting_function_t children based on the (next_interesting_function_t) parent node |
12014 |
++static next_interesting_function_t search_next_functions(tree node, next_interesting_function_t parent) |
12015 |
+{ |
12016 |
-+ gcc_assert(TREE_CODE(fndecl) == FUNCTION_DECL); |
12017 |
-+#if BUILDING_GCC_VERSION <= 4005 |
12018 |
-+ return cgraph_get_node(CONST_CAST_TREE(fndecl)); |
12019 |
++ struct walk_use_def_data use_def_data; |
12020 |
++ |
12021 |
++ use_def_data.parent = parent; |
12022 |
++ use_def_data.next_cnodes_head = NULL; |
12023 |
++ use_def_data.visited = pointer_set_create(); |
12024 |
++ |
12025 |
++ walk_use_def_next_functions(&use_def_data, node); |
12026 |
++ |
12027 |
++ pointer_set_destroy(use_def_data.visited); |
12028 |
++ return use_def_data.next_cnodes_head; |
12029 |
++} |
12030 |
++ |
12031 |
++// True if child already exists in the next_interesting_function_t children vector |
12032 |
++bool has_next_interesting_function_vec(next_interesting_function_t target, next_interesting_function_t next_node) |
12033 |
++{ |
12034 |
++ unsigned int i; |
12035 |
++ next_interesting_function_t cur; |
12036 |
++ |
12037 |
++ gcc_assert(next_node); |
12038 |
++ // handle recursion |
12039 |
++ if (!strcmp(target->decl_name, next_node->decl_name) && target->num == next_node->num) |
12040 |
++ return true; |
12041 |
++ |
12042 |
++#if BUILDING_GCC_VERSION <= 4007 |
12043 |
++ if (VEC_empty(next_interesting_function_t, target->children)) |
12044 |
++ return false; |
12045 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, target->children, i, cur) { |
12046 |
+#else |
12047 |
-+ return cgraph_get_node(fndecl); |
12048 |
++ FOR_EACH_VEC_SAFE_ELT(target->children, i, cur) { |
12049 |
+#endif |
12050 |
++ if (compare_next_interesting_functions(cur, next_node->decl_name, next_node->context, next_node->num)) |
12051 |
++ return true; |
12052 |
++ } |
12053 |
++ return false; |
12054 |
+} |
12055 |
+ |
12056 |
-+static bool compare_next_interesting_functions(next_interesting_function_t cur_node, const char *decl_name, const char *context, unsigned int num) |
12057 |
++void push_child(next_interesting_function_t parent, next_interesting_function_t child) |
12058 |
+{ |
12059 |
-+ // Ignore num without a value |
12060 |
-+ if (num != NONE_ARGNUM && cur_node->num != num) |
12061 |
-+ return false; |
12062 |
-+ if (strcmp(cur_node->context, context)) |
12063 |
-+ return false; |
12064 |
-+ return !strcmp(cur_node->decl_name, decl_name); |
12065 |
++ if (!has_next_interesting_function_vec(parent, child)) { |
12066 |
++#if BUILDING_GCC_VERSION <= 4007 |
12067 |
++ VEC_safe_push(next_interesting_function_t, heap, parent->children, child); |
12068 |
++#else |
12069 |
++ vec_safe_push(parent->children, child); |
12070 |
++#endif |
12071 |
++ } |
12072 |
+} |
12073 |
+ |
12074 |
-+// Return the context of vardecl. If it is in a file scope then the context is vardecl_filebasename |
12075 |
-+static const char* get_vardecl_context(const_tree decl) |
12076 |
++void __attribute__((weak)) check_local_variables(next_interesting_function_t next_node __unused) {} |
12077 |
++ |
12078 |
++// Add children to parent and global_next_interesting_function |
12079 |
++static void collect_data_for_execute(next_interesting_function_t parent, next_interesting_function_t children) |
12080 |
+{ |
12081 |
-+ expanded_location xloc; |
12082 |
-+ char *buf, *path; |
12083 |
-+ const char *bname; |
12084 |
-+ int len; |
12085 |
++ next_interesting_function_t cur = children; |
12086 |
+ |
12087 |
-+ xloc = expand_location(DECL_SOURCE_LOCATION(decl)); |
12088 |
-+ gcc_assert(xloc.file); |
12089 |
-+ path = xstrdup(xloc.file); |
12090 |
-+ bname = basename(path); |
12091 |
++ gcc_assert(parent); |
12092 |
+ |
12093 |
-+ len = asprintf(&buf, "vardecl_%s", bname); |
12094 |
-+ gcc_assert(len > 0); |
12095 |
-+ return buf; |
12096 |
++ while (cur) { |
12097 |
++ struct fn_raw_data child_raw_data; |
12098 |
++ next_interesting_function_t next, child; |
12099 |
++ |
12100 |
++ next = cur->next; |
12101 |
++ |
12102 |
++ child_raw_data.decl_str = cur->decl_name; |
12103 |
++ child_raw_data.context = cur->context; |
12104 |
++ child_raw_data.hash = cur->hash; |
12105 |
++ child_raw_data.num = cur->num; |
12106 |
++ child_raw_data.marked = NO_SO_MARK; |
12107 |
++ child = get_global_next_interesting_function_entry(&child_raw_data); |
12108 |
++ if (!child) { |
12109 |
++ add_to_global_next_interesting_function(cur); |
12110 |
++ child = cur; |
12111 |
++ } |
12112 |
++ |
12113 |
++ check_local_variables(child); |
12114 |
++ |
12115 |
++ push_child(parent, child); |
12116 |
++ |
12117 |
++ cur = next; |
12118 |
++ } |
12119 |
++ |
12120 |
++ check_local_variables(parent); |
12121 |
+} |
12122 |
+ |
12123 |
-+// Return the type name for a function pointer (or "fielddecl" if the type has no name), otherwise either "vardecl" or "fndecl" |
12124 |
-+const char* get_decl_context(const_tree decl) |
12125 |
++next_interesting_function_t __attribute__((weak)) get_and_create_next_node_from_global_next_nodes_fnptr(const_tree fn_ptr __unused, struct fn_raw_data *raw_data __unused) |
12126 |
+{ |
12127 |
-+ switch (TREE_CODE(decl)) { |
12128 |
-+ case FUNCTION_DECL: |
12129 |
-+ return "fndecl"; |
12130 |
-+ // TODO: Ignore anonymous types for now |
12131 |
-+ case FIELD_DECL: |
12132 |
-+ return get_type_name_from_field(decl); |
12133 |
-+ case VAR_DECL: |
12134 |
-+ if (TREE_PUBLIC(decl) || DECL_EXTERNAL(decl)) |
12135 |
-+ return "vardecl"; |
12136 |
-+ if (TREE_STATIC(decl) && !TREE_PUBLIC(decl)) |
12137 |
-+ return get_vardecl_context(decl); |
12138 |
-+ // ignore local variable |
12139 |
-+ if (!TREE_STATIC(decl) && !DECL_EXTERNAL(decl)) |
12140 |
++ return NULL; |
12141 |
++} |
12142 |
++ |
12143 |
++static next_interesting_function_t create_parent_next_cnode(const_gimple stmt, unsigned int num) |
12144 |
++{ |
12145 |
++ struct fn_raw_data raw_data; |
12146 |
++ |
12147 |
++ raw_data.num = num; |
12148 |
++ raw_data.marked = NO_SO_MARK; |
12149 |
++ |
12150 |
++ switch (gimple_code(stmt)) { |
12151 |
++ case GIMPLE_ASM: |
12152 |
++ raw_data.decl = current_function_decl; |
12153 |
++ raw_data.marked = ASM_STMT_SO_MARK; |
12154 |
++ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
12155 |
++ case GIMPLE_CALL: |
12156 |
++ raw_data.decl = gimple_call_fndecl(stmt); |
12157 |
++ if (raw_data.decl != NULL_TREE) |
12158 |
++ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
12159 |
++ raw_data.decl = gimple_call_fn(stmt); |
12160 |
++ return get_and_create_next_node_from_global_next_nodes_fnptr(raw_data.decl, &raw_data); |
12161 |
++ case GIMPLE_RETURN: |
12162 |
++ raw_data.decl = current_function_decl; |
12163 |
++ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
12164 |
++ case GIMPLE_ASSIGN: { |
12165 |
++ tree lhs = gimple_assign_lhs(stmt); |
12166 |
++ |
12167 |
++ if (VAR_P(lhs)) |
12168 |
++ raw_data.decl = lhs; |
12169 |
++ else |
12170 |
++ raw_data.decl = get_ref_field(lhs); |
12171 |
++ if (raw_data.decl == NULL_TREE) |
12172 |
+ return NULL; |
12173 |
++ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
12174 |
++ } |
12175 |
+ default: |
12176 |
-+ debug_tree(decl); |
12177 |
++ debug_gimple_stmt((gimple)stmt); |
12178 |
+ gcc_unreachable(); |
12179 |
+ } |
12180 |
+} |
12181 |
+ |
12182 |
-+// Find the function with the specified argument in the list |
12183 |
-+next_interesting_function_t get_global_next_interesting_function_entry(struct fn_raw_data *raw_data) |
12184 |
++// Handle potential next_interesting_function_t parent if its argument has an integer type |
12185 |
++static void collect_all_possible_size_overflow_fns(const_gimple stmt, tree start_var, unsigned int num) |
12186 |
+{ |
12187 |
-+ next_interesting_function_t cur_node, head; |
12188 |
++ next_interesting_function_t children_next_cnode, parent_next_cnode; |
12189 |
+ |
12190 |
-+ head = global_next_interesting_function[raw_data->hash]; |
12191 |
-+ for (cur_node = head; cur_node; cur_node = cur_node->next) { |
12192 |
-+ if (raw_data->marked != ASM_STMT_SO_MARK && cur_node->marked == ASM_STMT_SO_MARK) |
12193 |
++ // skip void return values |
12194 |
++ if (start_var == NULL_TREE) |
12195 |
++ return; |
12196 |
++ |
12197 |
++ if (skip_types(start_var)) |
12198 |
++ return; |
12199 |
++ |
12200 |
++ // handle intentional MARK_TURN_OFF |
12201 |
++ if (check_intentional_size_overflow_asm_and_attribute(start_var) == MARK_TURN_OFF) |
12202 |
++ return; |
12203 |
++ |
12204 |
++ parent_next_cnode = create_parent_next_cnode(stmt, num); |
12205 |
++ if (!parent_next_cnode) |
12206 |
++ return; |
12207 |
++ |
12208 |
++ children_next_cnode = search_next_functions(start_var, parent_next_cnode); |
12209 |
++ collect_data_for_execute(parent_next_cnode, children_next_cnode); |
12210 |
++} |
12211 |
++ |
12212 |
++static void collect_all_possible_size_overflow_fields_and_vars(const gassign *assign) |
12213 |
++{ |
12214 |
++ tree start_var, decl, lhs = gimple_assign_lhs(assign); |
12215 |
++ |
12216 |
++ if (VAR_P(lhs)) |
12217 |
++ decl = lhs; |
12218 |
++ else |
12219 |
++ decl = get_ref_field(lhs); |
12220 |
++ if (decl == NULL_TREE) |
12221 |
++ return; |
12222 |
++ |
12223 |
++ if (get_intentional_attr_type(decl) == MARK_TURN_OFF) |
12224 |
++ return; |
12225 |
++ |
12226 |
++ start_var = gimple_assign_rhs1(assign); |
12227 |
++ collect_all_possible_size_overflow_fns(assign, start_var, 0); |
12228 |
++ |
12229 |
++ start_var = gimple_assign_rhs2(assign); |
12230 |
++ collect_all_possible_size_overflow_fns(assign, start_var, 0); |
12231 |
++ |
12232 |
++#if BUILDING_GCC_VERSION >= 4006 |
12233 |
++ start_var = gimple_assign_rhs3(assign); |
12234 |
++ collect_all_possible_size_overflow_fns(assign, start_var, 0); |
12235 |
++#endif |
12236 |
++} |
12237 |
++ |
12238 |
++// Find potential next_interesting_function_t parents |
12239 |
++static void handle_cgraph_node(struct cgraph_node *node) |
12240 |
++{ |
12241 |
++ basic_block bb; |
12242 |
++ tree cur_fndecl = NODE_DECL(node); |
12243 |
++ |
12244 |
++ set_current_function_decl(cur_fndecl); |
12245 |
++ |
12246 |
++ FOR_EACH_BB_FN(bb, cfun) { |
12247 |
++ gimple_stmt_iterator gsi; |
12248 |
++ |
12249 |
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
12250 |
++ tree start_var; |
12251 |
++ gimple stmt = gsi_stmt(gsi); |
12252 |
++ |
12253 |
++ switch (gimple_code(stmt)) { |
12254 |
++ case GIMPLE_RETURN: { |
12255 |
++ const greturn *return_stmt = as_a_const_greturn(stmt); |
12256 |
++ |
12257 |
++ start_var = gimple_return_retval(return_stmt); |
12258 |
++ collect_all_possible_size_overflow_fns(return_stmt, start_var, 0); |
12259 |
++ break; |
12260 |
++ } |
12261 |
++ case GIMPLE_ASM: { |
12262 |
++ const gasm *asm_stmt = as_a_const_gasm(stmt); |
12263 |
++ |
12264 |
++ if (!is_size_overflow_insert_check_asm(asm_stmt)) |
12265 |
++ break; |
12266 |
++ start_var = get_size_overflow_asm_input(asm_stmt); |
12267 |
++ collect_all_possible_size_overflow_fns(asm_stmt, start_var, 0); |
12268 |
++ break; |
12269 |
++ } |
12270 |
++ case GIMPLE_CALL: { |
12271 |
++ unsigned int i, len; |
12272 |
++ const gcall *call = as_a_const_gcall(stmt); |
12273 |
++ tree fndecl = gimple_call_fndecl(call); |
12274 |
++ |
12275 |
++ if (fndecl != NULL_TREE && (DECL_BUILT_IN(fndecl) || DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL)) |
12276 |
++ break; |
12277 |
++ |
12278 |
++ len = gimple_call_num_args(call); |
12279 |
++ for (i = 0; i < len; i++) { |
12280 |
++ start_var = gimple_call_arg(call, i); |
12281 |
++ collect_all_possible_size_overflow_fns(call, start_var, i + 1); |
12282 |
++ } |
12283 |
++ break; |
12284 |
++ } |
12285 |
++ case GIMPLE_ASSIGN: |
12286 |
++ collect_all_possible_size_overflow_fields_and_vars(as_a_const_gassign(stmt)); |
12287 |
++ break; |
12288 |
++ default: |
12289 |
++ break; |
12290 |
++ } |
12291 |
++ } |
12292 |
++ } |
12293 |
++ |
12294 |
++ unset_current_function_decl(); |
12295 |
++} |
12296 |
++ |
12297 |
++/* Collect all potentially interesting function parameters and return values of integer types |
12298 |
++ * and store their data flow dependencies |
12299 |
++ */ |
12300 |
++static void size_overflow_generate_summary(void) |
12301 |
++{ |
12302 |
++ struct cgraph_node *node; |
12303 |
++ |
12304 |
++ size_overflow_register_hooks(); |
12305 |
++ |
12306 |
++ FOR_EACH_FUNCTION(node) { |
12307 |
++ if (is_valid_cgraph_node(node)) |
12308 |
++ handle_cgraph_node(node); |
12309 |
++ } |
12310 |
++} |
12311 |
++ |
12312 |
++static void size_overflow_function_insertion_hook(struct cgraph_node *node __unused, void *data __unused) |
12313 |
++{ |
12314 |
++ debug_cgraph_node(node); |
12315 |
++ gcc_unreachable(); |
12316 |
++} |
12317 |
++ |
12318 |
++/* Handle dst if src is in the global_next_interesting_function list. |
12319 |
++ * If src is a clone then dst inherits the orig_next_node of src otherwise |
12320 |
++ * src will become the orig_next_node of dst. |
12321 |
++ */ |
12322 |
++static void size_overflow_node_duplication_hook(struct cgraph_node *src, struct cgraph_node *dst, void *data __unused) |
12323 |
++{ |
12324 |
++ next_interesting_function_t head, cur; |
12325 |
++ struct fn_raw_data src_raw_data; |
12326 |
++ |
12327 |
++ src_raw_data.decl = NODE_DECL(src); |
12328 |
++ src_raw_data.decl_str = DECL_NAME_POINTER(src_raw_data.decl); |
12329 |
++ src_raw_data.context = get_decl_context(src_raw_data.decl); |
12330 |
++ if (!src_raw_data.context) |
12331 |
++ return; |
12332 |
++ |
12333 |
++ src_raw_data.num = NONE_ARGNUM; |
12334 |
++ src_raw_data.marked = NO_SO_MARK; |
12335 |
++ |
12336 |
++ head = get_global_next_interesting_function_entry_with_hash(&src_raw_data); |
12337 |
++ if (!head) |
12338 |
++ return; |
12339 |
++ |
12340 |
++ for (cur = head; cur; cur = cur->next) { |
12341 |
++ struct fn_raw_data dst_raw_data; |
12342 |
++ next_interesting_function_t orig_next_node, next_node; |
12343 |
++ |
12344 |
++ if (!compare_next_interesting_functions(cur, src_raw_data.decl_str, src_raw_data.context, src_raw_data.num)) |
12345 |
+ continue; |
12346 |
-+ if (compare_next_interesting_functions(cur_node, raw_data->decl_str, raw_data->context, raw_data->num)) |
12347 |
-+ return cur_node; |
12348 |
++ |
12349 |
++ dst_raw_data.decl = NODE_DECL(dst); |
12350 |
++ dst_raw_data.decl_str = cgraph_node_name(dst); |
12351 |
++ dst_raw_data.marked = cur->marked; |
12352 |
++ |
12353 |
++ if (!made_by_compiler(dst_raw_data.decl)) |
12354 |
++ break; |
12355 |
++ |
12356 |
++ // For clones use the original node instead |
12357 |
++ if (cur->orig_next_node) |
12358 |
++ orig_next_node = cur->orig_next_node; |
12359 |
++ else |
12360 |
++ orig_next_node = cur; |
12361 |
++ |
12362 |
++ dst_raw_data.num = get_correct_argnum_fndecl(src_raw_data.decl, dst_raw_data.decl, cur->num); |
12363 |
++ if (dst_raw_data.num == CANNOT_FIND_ARG) |
12364 |
++ continue; |
12365 |
++ |
12366 |
++ next_node = create_new_next_interesting_decl(&dst_raw_data, orig_next_node); |
12367 |
++ if (next_node) |
12368 |
++ add_to_global_next_interesting_function(next_node); |
12369 |
+ } |
12370 |
-+ return NULL; |
12371 |
+} |
12372 |
+ |
12373 |
-+next_interesting_function_t get_global_next_interesting_function_entry_with_hash(struct fn_raw_data *raw_data) |
12374 |
++void size_overflow_register_hooks(void) |
12375 |
+{ |
12376 |
-+ raw_data->hash = get_decl_hash(raw_data->decl, raw_data->decl_str); |
12377 |
-+ if (raw_data->hash == NO_HASH) |
12378 |
-+ return NULL; |
12379 |
++ static bool init_p = false; |
12380 |
+ |
12381 |
-+ raw_data->context = get_decl_context(raw_data->decl); |
12382 |
-+ if (!raw_data->context) |
12383 |
-+ return NULL; |
12384 |
-+ return get_global_next_interesting_function_entry(raw_data); |
12385 |
++ if (init_p) |
12386 |
++ return; |
12387 |
++ init_p = true; |
12388 |
++ |
12389 |
++ function_insertion_hook_holder = cgraph_add_function_insertion_hook(&size_overflow_function_insertion_hook, NULL); |
12390 |
++ node_duplication_hook_holder = cgraph_add_node_duplication_hook(&size_overflow_node_duplication_hook, NULL); |
12391 |
+} |
12392 |
+ |
12393 |
-+next_interesting_function_t create_new_next_interesting_entry(struct fn_raw_data *raw_data, next_interesting_function_t orig_next_node) |
12394 |
++static void set_yes_so_mark(next_interesting_function_t next_node) |
12395 |
+{ |
12396 |
-+ next_interesting_function_t new_node; |
12397 |
++ if (next_node->marked == NO_SO_MARK) { |
12398 |
++ next_node->marked = YES_SO_MARK; |
12399 |
++ global_changed = true; |
12400 |
++ } |
12401 |
++ // Mark the orig decl as well if it's a clone |
12402 |
++ if (next_node->orig_next_node && next_node->orig_next_node->marked == NO_SO_MARK) { |
12403 |
++ next_node->orig_next_node->marked = YES_SO_MARK; |
12404 |
++ global_changed = true; |
12405 |
++ } |
12406 |
++} |
12407 |
+ |
12408 |
-+ new_node = (next_interesting_function_t)xmalloc(sizeof(*new_node)); |
12409 |
-+ new_node->decl_name = xstrdup(raw_data->decl_str); |
12410 |
++// Determine whether node or orig node is part of a tracked data flow |
12411 |
++static bool marked_fn(next_interesting_function_t next_node) |
12412 |
++{ |
12413 |
++ bool is_marked_fn, is_marked_orig = false; |
12414 |
+ |
12415 |
-+ gcc_assert(raw_data->context); |
12416 |
-+ new_node->context = xstrdup(raw_data->context); |
12417 |
-+ new_node->hash = raw_data->hash; |
12418 |
-+ new_node->num = raw_data->num; |
12419 |
-+ new_node->next = NULL; |
12420 |
-+ new_node->children = NULL; |
12421 |
-+ new_node->marked = raw_data->marked; |
12422 |
-+ new_node->orig_next_node = orig_next_node; |
12423 |
-+ return new_node; |
12424 |
++ is_marked_fn = next_node->marked != NO_SO_MARK; |
12425 |
++ |
12426 |
++ if (next_node->orig_next_node) |
12427 |
++ is_marked_orig = next_node->orig_next_node->marked != NO_SO_MARK; |
12428 |
++ |
12429 |
++ return is_marked_fn || is_marked_orig; |
12430 |
+} |
12431 |
+ |
12432 |
-+// Ignore these functions to not explode coverage (+strncmp+fndecl+3+35130+) |
12433 |
-+static bool temporary_skip_these_functions(struct fn_raw_data *raw_data) |
12434 |
++// Determine whether node or orig node is in the hash table already |
12435 |
++static bool already_in_the_hashtable(next_interesting_function_t next_node) |
12436 |
+{ |
12437 |
-+ if (raw_data->hash == 35130 && !strcmp(raw_data->decl_str, "strncmp")) |
12438 |
-+ return true; |
12439 |
-+ if (raw_data->hash == 46193 && !strcmp(raw_data->decl_str, "strnlen")) |
12440 |
-+ return true; |
12441 |
-+ if (raw_data->hash == 43267 && !strcmp(raw_data->decl_str, "strncpy")) |
12442 |
-+ return true; |
12443 |
-+ if (raw_data->hash == 10300 && !strcmp(raw_data->decl_str, "strncpy_from_user")) |
12444 |
-+ return true; |
12445 |
-+ if (raw_data->hash == 26117 && !strcmp(raw_data->decl_str, "memchr")) |
12446 |
-+ return true; |
12447 |
-+ if (raw_data->hash == 16203 && !strcmp(raw_data->decl_str, "memchr_inv")) |
12448 |
-+ return true; |
12449 |
-+ if (raw_data->hash == 24269 && !strcmp(raw_data->decl_str, "memcmp")) |
12450 |
-+ return true; |
12451 |
-+ if (raw_data->hash == 60390 && !strcmp(raw_data->decl_str, "memcpy")) |
12452 |
-+ return true; |
12453 |
-+ if (raw_data->hash == 25040 && !strcmp(raw_data->decl_str, "memmove")) |
12454 |
-+ return true; |
12455 |
-+ if (raw_data->hash == 29763 && !strcmp(raw_data->decl_str, "memset")) |
12456 |
-+ return true; |
12457 |
-+ return false; |
12458 |
++ if (next_node->orig_next_node) |
12459 |
++ next_node = next_node->orig_next_node; |
12460 |
++ return get_size_overflow_hash_entry(next_node->hash, next_node->decl_name, next_node->context, next_node->num) != NULL; |
12461 |
+} |
12462 |
+ |
12463 |
-+// Create the main data structure |
12464 |
-+next_interesting_function_t create_new_next_interesting_decl(struct fn_raw_data *raw_data, next_interesting_function_t orig_next_node) |
12465 |
++// Propagate the size_overflow marks up the use-def chains |
12466 |
++static bool has_marked_child(next_interesting_function_t next_node) |
12467 |
+{ |
12468 |
-+ enum tree_code decl_code = TREE_CODE(raw_data->decl); |
12469 |
++ bool ret = false; |
12470 |
++ unsigned int i; |
12471 |
++ next_interesting_function_t child; |
12472 |
+ |
12473 |
-+ gcc_assert(decl_code == FIELD_DECL || decl_code == FUNCTION_DECL || decl_code == VAR_DECL); |
12474 |
++#if BUILDING_GCC_VERSION <= 4007 |
12475 |
++ if (VEC_empty(next_interesting_function_t, next_node->children)) |
12476 |
++ return false; |
12477 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, next_node->children, i, child) { |
12478 |
++#else |
12479 |
++ FOR_EACH_VEC_SAFE_ELT(next_node->children, i, child) { |
12480 |
++#endif |
12481 |
++ if (marked_fn(child) || already_in_the_hashtable(child)) |
12482 |
++ ret = true; |
12483 |
++ } |
12484 |
+ |
12485 |
-+ if (is_vararg(raw_data->decl, raw_data->num)) |
12486 |
-+ return NULL; |
12487 |
++ return ret; |
12488 |
++} |
12489 |
+ |
12490 |
-+ raw_data->hash = get_decl_hash(raw_data->decl, raw_data->decl_str); |
12491 |
-+ if (raw_data->hash == NO_HASH) |
12492 |
-+ return NULL; |
12493 |
-+ if (get_size_overflow_hash_entry_tree(raw_data->decl, raw_data->num, DISABLE_SIZE_OVERFLOW)) |
12494 |
-+ return NULL; |
12495 |
-+ if (temporary_skip_these_functions(raw_data)) |
12496 |
-+ return NULL; |
12497 |
++/* Set YES_SO_MARK on the function, its orig node and children if: |
12498 |
++ * * the function or its orig node or one of its children is in the hash table already |
12499 |
++ * * the function's orig node is marked with YES_SO_MARK or ASM_STMT_SO_MARK |
12500 |
++ * * one of the children is marked with YES_SO_MARK or ASM_STMT_SO_MARK |
12501 |
++ */ |
12502 |
++static bool set_fn_so_mark(next_interesting_function_t next_node) |
12503 |
++{ |
12504 |
++ bool so_fn, so_hashtable, so_child; |
12505 |
+ |
12506 |
-+ gcc_assert(raw_data->num <= MAX_PARAM); |
12507 |
-+ // Clones must have an orig_next_node |
12508 |
-+ gcc_assert(!made_by_compiler(raw_data->decl) || orig_next_node); |
12509 |
++ so_hashtable = already_in_the_hashtable(next_node); |
12510 |
++ so_fn = marked_fn(next_node); |
12511 |
++ so_child = has_marked_child(next_node); |
12512 |
+ |
12513 |
-+ raw_data->context = get_decl_context(raw_data->decl); |
12514 |
-+ if (!raw_data->context) |
12515 |
++ if (!so_fn && !so_hashtable && !so_child) |
12516 |
++ return false; |
12517 |
++ set_yes_so_mark(next_node); |
12518 |
++ return true; |
12519 |
++} |
12520 |
++ |
12521 |
++// Determine if any of the function pointer targets have data flow between the return value and one of the arguments |
12522 |
++static next_interesting_function_t get_same_not_ret_child(next_interesting_function_t parent) |
12523 |
++{ |
12524 |
++ unsigned int i; |
12525 |
++ next_interesting_function_t child; |
12526 |
++ |
12527 |
++#if BUILDING_GCC_VERSION <= 4007 |
12528 |
++ if (VEC_empty(next_interesting_function_t, parent->children)) |
12529 |
+ return NULL; |
12530 |
-+ return create_new_next_interesting_entry(raw_data, orig_next_node); |
12531 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
12532 |
++#else |
12533 |
++ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
12534 |
++#endif |
12535 |
++ if (child->num == 0) |
12536 |
++ continue; |
12537 |
++ if (strcmp(parent->decl_name, child->decl_name)) |
12538 |
++ continue; |
12539 |
++ if (!strcmp(child->context, "fndecl")) |
12540 |
++ return child; |
12541 |
++ } |
12542 |
++ return NULL; |
12543 |
+} |
12544 |
+ |
12545 |
-+void add_to_global_next_interesting_function(next_interesting_function_t new_entry) |
12546 |
++/* Trace a return value of function pointer type back to an argument via a concrete function |
12547 |
++ fnptr 0 && fn 0 && (fn 0 -> fn 2) => fnptr 2 */ |
12548 |
++static void search_missing_fptr_arg(next_interesting_function_t parent) |
12549 |
+{ |
12550 |
-+ next_interesting_function_t cur_global_head, cur_global, cur_global_end = NULL; |
12551 |
++ next_interesting_function_t child; |
12552 |
++ unsigned int i; |
12553 |
++#if BUILDING_GCC_VERSION <= 4007 |
12554 |
++ VEC(next_interesting_function_t, heap) *new_children = NULL; |
12555 |
++#else |
12556 |
++ vec<next_interesting_function_t, va_heap, vl_embed> *new_children = NULL; |
12557 |
++#endif |
12558 |
+ |
12559 |
-+ // new_entry is appended to the end of a list |
12560 |
-+ new_entry->next = NULL; |
12561 |
++ if (parent->num != 0) |
12562 |
++ return; |
12563 |
++ if (!strcmp(parent->context, "fndecl")) |
12564 |
++ return; |
12565 |
++ if (!strncmp(parent->context, "vardecl", sizeof("vardecl") - 1)) |
12566 |
++ return; |
12567 |
+ |
12568 |
-+ cur_global_head = global_next_interesting_function[new_entry->hash]; |
12569 |
-+ if (!cur_global_head) { |
12570 |
-+ global_next_interesting_function[new_entry->hash] = new_entry; |
12571 |
++ // fnptr 0 && fn 0 |
12572 |
++#if BUILDING_GCC_VERSION <= 4007 |
12573 |
++ if (VEC_empty(next_interesting_function_t, parent->children)) |
12574 |
+ return; |
12575 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
12576 |
++#else |
12577 |
++ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
12578 |
++#endif |
12579 |
++ next_interesting_function_t cur_next_node, tracked_fn; |
12580 |
++ |
12581 |
++ if (child->num != 0) |
12582 |
++ continue; |
12583 |
++ // (fn 0 -> fn 2) |
12584 |
++ tracked_fn = get_same_not_ret_child(child); |
12585 |
++ if (!tracked_fn) |
12586 |
++ continue; |
12587 |
++ |
12588 |
++ // fn 2 => fnptr 2 |
12589 |
++ for (cur_next_node = global_next_interesting_function[parent->hash]; cur_next_node; cur_next_node = cur_next_node->next) { |
12590 |
++ if (cur_next_node->num != tracked_fn->num) |
12591 |
++ continue; |
12592 |
++ |
12593 |
++ if (strcmp(parent->decl_name, cur_next_node->decl_name)) |
12594 |
++ continue; |
12595 |
++ |
12596 |
++ if (!has_next_interesting_function_vec(parent, cur_next_node)) { |
12597 |
++#if BUILDING_GCC_VERSION <= 4007 |
12598 |
++ VEC_safe_push(next_interesting_function_t, heap, new_children, cur_next_node); |
12599 |
++#else |
12600 |
++ vec_safe_push(new_children, cur_next_node); |
12601 |
++#endif |
12602 |
++ } |
12603 |
++ } |
12604 |
+ } |
12605 |
+ |
12606 |
++#if BUILDING_GCC_VERSION == 4005 |
12607 |
++ if (VEC_empty(next_interesting_function_t, new_children)) |
12608 |
++ return; |
12609 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, new_children, i, child) |
12610 |
++ VEC_safe_push(next_interesting_function_t, heap, parent->children, child); |
12611 |
++#elif BUILDING_GCC_VERSION <= 4007 |
12612 |
++ VEC_safe_splice(next_interesting_function_t, heap, parent->children, new_children); |
12613 |
++#else |
12614 |
++ vec_safe_splice(parent->children, new_children); |
12615 |
++#endif |
12616 |
++} |
12617 |
++ |
12618 |
++static void walk_so_marked_fns(next_interesting_function_set *visited, next_interesting_function_t parent, bool debug) |
12619 |
++{ |
12620 |
++ unsigned int i; |
12621 |
++ next_interesting_function_t child; |
12622 |
+ |
12623 |
-+ for (cur_global = cur_global_head; cur_global; cur_global = cur_global->next) { |
12624 |
-+ if (!cur_global->next) |
12625 |
-+ cur_global_end = cur_global; |
12626 |
++ gcc_assert(parent); |
12627 |
++ if (!set_fn_so_mark(parent)) |
12628 |
++ return; |
12629 |
+ |
12630 |
-+ if (compare_next_interesting_functions(cur_global, new_entry->decl_name, new_entry->context, new_entry->num)) |
12631 |
-+ return; |
12632 |
++#if BUILDING_GCC_VERSION <= 4007 |
12633 |
++ if (VEC_empty(next_interesting_function_t, parent->children)) |
12634 |
++ return; |
12635 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
12636 |
++#else |
12637 |
++ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
12638 |
++#endif |
12639 |
++ set_yes_so_mark(child); |
12640 |
++ |
12641 |
++ if (in_lto_p && debug == PRINT_DATA_FLOW) { |
12642 |
++ fprintf(stderr, " PARENT: decl: %s-%u context: %s %p\n", parent->decl_name, parent->num, parent->context, parent); |
12643 |
++ fprintf(stderr, " \tCHILD: decl: %s-%u context: %s %p\n", child->decl_name, child->num, child->context, child); |
12644 |
++ } |
12645 |
++ |
12646 |
++ if (!pointer_set_insert(visited, child)) |
12647 |
++ walk_so_marked_fns(visited, child, debug); |
12648 |
+ } |
12649 |
++} |
12650 |
+ |
12651 |
-+ gcc_assert(cur_global_end); |
12652 |
-+ cur_global_end->next = new_entry; |
12653 |
++// Do a depth-first recursive dump of the next_interesting_function_t children vector |
12654 |
++static void print_missing_functions(next_interesting_function_set *visited, next_interesting_function_t parent) |
12655 |
++{ |
12656 |
++ unsigned int i; |
12657 |
++ next_interesting_function_t child; |
12658 |
++ |
12659 |
++ gcc_assert(parent); |
12660 |
++ gcc_assert(parent->marked != NO_SO_MARK); |
12661 |
++ print_missing_function(parent); |
12662 |
++ |
12663 |
++#if BUILDING_GCC_VERSION <= 4007 |
12664 |
++ if (VEC_empty(next_interesting_function_t, parent->children)) |
12665 |
++ return; |
12666 |
++ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
12667 |
++#else |
12668 |
++ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
12669 |
++#endif |
12670 |
++ gcc_assert(child->marked != NO_SO_MARK); |
12671 |
++ if (!pointer_set_insert(visited, child)) |
12672 |
++ print_missing_functions(visited, child); |
12673 |
++ } |
12674 |
+} |
12675 |
+ |
12676 |
-+/* If the interesting function is a clone then find or create its original next_interesting_function_t node |
12677 |
-+ * and add it to global_next_interesting_function |
12678 |
++// Set YES_SO_MARK on functions that will be emitted into the hash table |
12679 |
++static void search_so_marked_fns(bool debug) |
12680 |
++{ |
12681 |
++ |
12682 |
++ unsigned int i; |
12683 |
++ next_interesting_function_set *visited; |
12684 |
++ next_interesting_function_t cur_global; |
12685 |
++ |
12686 |
++ visited = next_interesting_function_pointer_set_create(); |
12687 |
++ for (i = 0; i < GLOBAL_NIFN_LEN; i++) { |
12688 |
++ for (cur_global = global_next_interesting_function[i]; cur_global; cur_global = cur_global->next) { |
12689 |
++ if (cur_global->marked == NO_SO_MARK || pointer_set_insert(visited, cur_global)) |
12690 |
++ continue; |
12691 |
++ |
12692 |
++ if (in_lto_p && debug == PRINT_DATA_FLOW) |
12693 |
++ fprintf(stderr, "Data flow: decl: %s-%u context: %s %p\n", cur_global->decl_name, cur_global->num, cur_global->context, cur_global); |
12694 |
++ |
12695 |
++ walk_so_marked_fns(visited, cur_global, debug); |
12696 |
++ |
12697 |
++ if (in_lto_p && debug == PRINT_DATA_FLOW) |
12698 |
++ fprintf(stderr, "\n"); |
12699 |
++ } |
12700 |
++ } |
12701 |
++ pointer_set_destroy(visited); |
12702 |
++} |
12703 |
++ |
12704 |
++// Print functions missing from the hash table |
12705 |
++static void print_so_marked_fns(void) |
12706 |
++{ |
12707 |
++ unsigned int i; |
12708 |
++ next_interesting_function_set *visited; |
12709 |
++ next_interesting_function_t cur_global; |
12710 |
++ |
12711 |
++ visited = next_interesting_function_pointer_set_create(); |
12712 |
++ for (i = 0; i < GLOBAL_NIFN_LEN; i++) { |
12713 |
++ for (cur_global = global_next_interesting_function[i]; cur_global; cur_global = cur_global->next) { |
12714 |
++ if (cur_global->marked != NO_SO_MARK && !pointer_set_insert(visited, cur_global)) |
12715 |
++ print_missing_functions(visited, cur_global); |
12716 |
++ } |
12717 |
++ } |
12718 |
++ pointer_set_destroy(visited); |
12719 |
++} |
12720 |
++ |
12721 |
++void __attribute__((weak)) check_global_variables(next_interesting_function_t cur_global __unused) {} |
12722 |
++ |
12723 |
++// Print all missing interesting functions |
12724 |
++static unsigned int size_overflow_execute(void) |
12725 |
++{ |
12726 |
++ unsigned int i; |
12727 |
++ next_interesting_function_t cur_global; |
12728 |
++ |
12729 |
++ if (flag_lto && !in_lto_p) |
12730 |
++ return 0; |
12731 |
++ |
12732 |
++ // Collect vardecls and funtions reachable by function pointers |
12733 |
++ for (i = 0; i < GLOBAL_NIFN_LEN; i++) { |
12734 |
++ for (cur_global = global_next_interesting_function[i]; cur_global; cur_global = cur_global->next) { |
12735 |
++ check_global_variables(cur_global); |
12736 |
++ search_missing_fptr_arg(cur_global); |
12737 |
++ } |
12738 |
++ } |
12739 |
++ |
12740 |
++ search_so_marked_fns(PRINT_DATA_FLOW); |
12741 |
++ while (global_changed) { |
12742 |
++ global_changed = false; |
12743 |
++ search_so_marked_fns(NO_PRINT_DATA_FLOW); |
12744 |
++ } |
12745 |
++ |
12746 |
++ print_so_marked_fns(); |
12747 |
++ |
12748 |
++ if (in_lto_p) { |
12749 |
++ fprintf(stderr, "%s: SIZE_OVERFLOW EXECUTE\n", __func__); |
12750 |
++ print_global_next_interesting_functions(); |
12751 |
++ } |
12752 |
++ |
12753 |
++ return 0; |
12754 |
++} |
12755 |
++ |
12756 |
++// Omit the IPA/LTO callbacks until https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61311 gets fixed (license concerns) |
12757 |
++#if BUILDING_GCC_VERSION >= 4008 |
12758 |
++void __attribute__((weak)) size_overflow_write_summary(void) {} |
12759 |
++void __attribute__((weak)) size_overflow_write_optimization_summary(void) {} |
12760 |
++#elif BUILDING_GCC_VERSION >= 4006 |
12761 |
++void __attribute__((weak)) size_overflow_write_summary(cgraph_node_set set __unused, varpool_node_set vset __unused) {} |
12762 |
++void __attribute__((weak)) size_overflow_write_optimization_summary(cgraph_node_set set __unused, varpool_node_set vset __unused) {} |
12763 |
++#else |
12764 |
++void __attribute__((weak)) size_overflow_write_summary(cgraph_node_set set __unused) {} |
12765 |
++void __attribute__((weak)) size_overflow_write_optimization_summary(cgraph_node_set set __unused) {} |
12766 |
++#endif |
12767 |
++ |
12768 |
++void __attribute__((weak)) size_overflow_read_summary(void); |
12769 |
++void __attribute__((weak)) size_overflow_read_optimization_summary(void); |
12770 |
++ |
12771 |
++#define PASS_NAME size_overflow |
12772 |
++ |
12773 |
++#define NO_STMT_FIXUP |
12774 |
++#define NO_VARIABLE_TRANSFORM |
12775 |
++#define NO_GATE |
12776 |
++ |
12777 |
++#include "gcc-generate-ipa-pass.h" |
12778 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_misc.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_misc.c |
12779 |
+new file mode 100644 |
12780 |
+index 0000000..7f459ed |
12781 |
+--- /dev/null |
12782 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_misc.c |
12783 |
+@@ -0,0 +1,505 @@ |
12784 |
++/* |
12785 |
++ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
12786 |
++ * Licensed under the GPL v2, or (at your option) v3 |
12787 |
++ * |
12788 |
++ * Homepage: |
12789 |
++ * https://github.com/ephox-gcc-plugins/size_overflow |
12790 |
++ * |
12791 |
++ * Documentation: |
12792 |
++ * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
12793 |
++ * |
12794 |
++ * This plugin recomputes expressions of function arguments marked by a size_overflow attribute |
12795 |
++ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
12796 |
++ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
12797 |
++ * |
12798 |
++ * Usage: |
12799 |
++ * $ make |
12800 |
++ * $ make run |
12801 |
+ */ |
12802 |
-+static next_interesting_function_t create_orig_next_node_for_a_clone(struct fn_raw_data *clone_raw_data) |
12803 |
++ |
12804 |
++#include "size_overflow.h" |
12805 |
++ |
12806 |
++bool is_vararg(const_tree fn, unsigned int num) |
12807 |
+{ |
12808 |
-+ struct fn_raw_data orig_raw_data; |
12809 |
-+ next_interesting_function_t orig_next_node; |
12810 |
-+ enum tree_code decl_code; |
12811 |
++ tree arg_list; |
12812 |
+ |
12813 |
-+ orig_raw_data.decl = get_orig_fndecl(clone_raw_data->decl); |
12814 |
++ if (num == 0) |
12815 |
++ return false; |
12816 |
++ if (fn == NULL_TREE) |
12817 |
++ return false; |
12818 |
++ if (TREE_CODE(fn) != FUNCTION_DECL) |
12819 |
++ return false; |
12820 |
+ |
12821 |
-+ if (DECL_BUILT_IN(orig_raw_data.decl) || DECL_BUILT_IN_CLASS(orig_raw_data.decl) == BUILT_IN_NORMAL) |
12822 |
-+ return NULL; |
12823 |
++ arg_list = TYPE_ARG_TYPES(TREE_TYPE(fn)); |
12824 |
++ if (arg_list == NULL_TREE) |
12825 |
++ return false; |
12826 |
+ |
12827 |
-+ if (made_by_compiler(orig_raw_data.decl)) |
12828 |
-+ return NULL; |
12829 |
++ if (tree_last(arg_list) == void_list_node) |
12830 |
++ return false; |
12831 |
+ |
12832 |
-+ decl_code = TREE_CODE(orig_raw_data.decl); |
12833 |
-+ if (decl_code == FIELD_DECL || decl_code == VAR_DECL) |
12834 |
-+ orig_raw_data.num = clone_raw_data->num; |
12835 |
-+ else |
12836 |
-+ orig_raw_data.num = get_correct_argnum(clone_raw_data->decl, orig_raw_data.decl, clone_raw_data->num); |
12837 |
++ return num >= (unsigned int)list_length(arg_list); |
12838 |
++} |
12839 |
+ |
12840 |
-+ // Skip over ISRA.162 parm decls |
12841 |
-+ if (orig_raw_data.num == CANNOT_FIND_ARG) |
12842 |
-+ return NULL; |
12843 |
++// Extract the field decl from memory references |
12844 |
++tree get_ref_field(const_tree ref) |
12845 |
++{ |
12846 |
++ tree field; |
12847 |
+ |
12848 |
-+ orig_raw_data.decl_str = get_orig_decl_name(orig_raw_data.decl); |
12849 |
-+ orig_raw_data.marked = NO_SO_MARK; |
12850 |
-+ orig_next_node = get_global_next_interesting_function_entry_with_hash(&orig_raw_data); |
12851 |
-+ if (orig_next_node) |
12852 |
-+ return orig_next_node; |
12853 |
++ // TODO: handle nested memory references |
12854 |
++ switch (TREE_CODE(ref)) { |
12855 |
++ case ARRAY_REF: |
12856 |
++ return NULL_TREE; |
12857 |
++#if BUILDING_GCC_VERSION >= 4006 |
12858 |
++ case MEM_REF: |
12859 |
++#endif |
12860 |
++ case INDIRECT_REF: |
12861 |
++ field = TREE_OPERAND(ref, 0); |
12862 |
++ break; |
12863 |
++ case COMPONENT_REF: |
12864 |
++ field = TREE_OPERAND(ref, 1); |
12865 |
++ break; |
12866 |
++ default: |
12867 |
++ return NULL_TREE; |
12868 |
++ } |
12869 |
+ |
12870 |
-+ orig_raw_data.marked = clone_raw_data->marked; |
12871 |
-+ orig_next_node = create_new_next_interesting_decl(&orig_raw_data, NULL); |
12872 |
-+ if (!orig_next_node) |
12873 |
-+ return NULL; |
12874 |
++ // TODO |
12875 |
++ if (TREE_CODE(field) == SSA_NAME) |
12876 |
++ return NULL_TREE; |
12877 |
++ // TODO |
12878 |
++ if (TREE_CODE(field) != FIELD_DECL) |
12879 |
++ return NULL_TREE; |
12880 |
++ // TODO |
12881 |
++ if (TREE_CODE(field) == ADDR_EXPR) |
12882 |
++ return NULL_TREE; |
12883 |
+ |
12884 |
-+ add_to_global_next_interesting_function(orig_next_node); |
12885 |
-+ return orig_next_node; |
12886 |
++ return field; |
12887 |
+} |
12888 |
+ |
12889 |
-+// Find or create the next_interesting_function_t node for decl and num |
12890 |
-+next_interesting_function_t get_and_create_next_node_from_global_next_nodes(struct fn_raw_data *raw_data, next_interesting_function_t orig_next_node) |
12891 |
++const char *get_type_name_from_field(const_tree field_decl) |
12892 |
+{ |
12893 |
-+ next_interesting_function_t cur_next_cnode; |
12894 |
++ const_tree context, type_name; |
12895 |
+ |
12896 |
-+ if (DECL_NAME(raw_data->decl) == NULL_TREE) |
12897 |
++ if (TREE_CODE(field_decl) != FIELD_DECL) |
12898 |
+ return NULL; |
12899 |
-+ raw_data->decl_str = DECL_NAME_POINTER(raw_data->decl); |
12900 |
+ |
12901 |
-+ cur_next_cnode = get_global_next_interesting_function_entry_with_hash(raw_data); |
12902 |
-+ if (cur_next_cnode) |
12903 |
-+ goto out; |
12904 |
++ context = DECL_CONTEXT(field_decl); |
12905 |
++ // TODO |
12906 |
++ if (TREE_CODE(context) != RECORD_TYPE) |
12907 |
++ return NULL; |
12908 |
++ gcc_assert(TREE_CODE(context) == RECORD_TYPE); |
12909 |
++ type_name = TYPE_NAME(TYPE_MAIN_VARIANT(context)); |
12910 |
++ if (type_name == NULL_TREE) |
12911 |
++ return NULL; |
12912 |
+ |
12913 |
-+ if (!orig_next_node && made_by_compiler(raw_data->decl)) { |
12914 |
-+ orig_next_node = create_orig_next_node_for_a_clone(raw_data); |
12915 |
-+ if (!orig_next_node) |
12916 |
-+ return NULL; |
12917 |
++ if (TREE_CODE(type_name) == IDENTIFIER_NODE) |
12918 |
++ return IDENTIFIER_POINTER(type_name); |
12919 |
++ else if (TREE_CODE(type_name) == TYPE_DECL) |
12920 |
++ return DECL_NAME_POINTER(type_name); |
12921 |
++ |
12922 |
++ debug_tree(field_decl); |
12923 |
++ debug_tree(type_name); |
12924 |
++ gcc_unreachable(); |
12925 |
++} |
12926 |
++ |
12927 |
++// Was the function created by the compiler itself? |
12928 |
++bool made_by_compiler(const_tree decl) |
12929 |
++{ |
12930 |
++ enum tree_code decl_code; |
12931 |
++ struct cgraph_node *node; |
12932 |
++ |
12933 |
++ if (FUNCTION_PTR_P(decl)) |
12934 |
++ return false; |
12935 |
++ decl_code = TREE_CODE(decl); |
12936 |
++ if (decl_code == VAR_DECL || decl_code == FIELD_DECL) |
12937 |
++ return false; |
12938 |
++ |
12939 |
++ gcc_assert(decl_code == FUNCTION_DECL); |
12940 |
++ if (DECL_ABSTRACT_ORIGIN(decl) != NULL_TREE && DECL_ABSTRACT_ORIGIN(decl) != decl) |
12941 |
++ return true; |
12942 |
++ if (DECL_ARTIFICIAL(decl)) |
12943 |
++ return true; |
12944 |
++ |
12945 |
++ node = get_cnode(decl); |
12946 |
++ if (!node) |
12947 |
++ return false; |
12948 |
++ return node->clone_of != NULL; |
12949 |
++} |
12950 |
++ |
12951 |
++bool skip_types(const_tree var) |
12952 |
++{ |
12953 |
++ const_tree type; |
12954 |
++ |
12955 |
++ type = TREE_TYPE(var); |
12956 |
++ if (type == NULL_TREE) |
12957 |
++ return true; |
12958 |
++ |
12959 |
++ switch (TREE_CODE(type)) { |
12960 |
++ case INTEGER_TYPE: |
12961 |
++ case ENUMERAL_TYPE: |
12962 |
++ return false; |
12963 |
++ default: |
12964 |
++ return true; |
12965 |
+ } |
12966 |
++} |
12967 |
+ |
12968 |
-+ cur_next_cnode = create_new_next_interesting_decl(raw_data, orig_next_node); |
12969 |
-+ if (!cur_next_cnode) |
12970 |
++gimple get_fnptr_def_stmt(const_tree fn_ptr) |
12971 |
++{ |
12972 |
++ gimple def_stmt; |
12973 |
++ |
12974 |
++ gcc_assert(fn_ptr != NULL_TREE); |
12975 |
++ gcc_assert(FUNCTION_PTR_P(fn_ptr)); |
12976 |
++ |
12977 |
++ if (is_gimple_constant(fn_ptr)) |
12978 |
+ return NULL; |
12979 |
+ |
12980 |
-+ add_to_global_next_interesting_function(cur_next_cnode); |
12981 |
-+out: |
12982 |
-+ if (cur_next_cnode->marked != raw_data->marked && cur_next_cnode->marked != NO_SO_MARK) |
12983 |
-+ return cur_next_cnode; |
12984 |
++ def_stmt = get_def_stmt(fn_ptr); |
12985 |
++ gcc_assert(def_stmt); |
12986 |
++ return def_stmt; |
12987 |
++} |
12988 |
+ |
12989 |
-+ if (raw_data->marked != NO_SO_MARK && cur_next_cnode->marked == NO_SO_MARK) |
12990 |
-+ cur_next_cnode->marked = raw_data->marked; |
12991 |
++gimple get_def_stmt(const_tree node) |
12992 |
++{ |
12993 |
++ gcc_assert(node != NULL_TREE); |
12994 |
+ |
12995 |
-+ return cur_next_cnode; |
12996 |
++ if (TREE_CODE(node) != SSA_NAME) |
12997 |
++ return NULL; |
12998 |
++ return SSA_NAME_DEF_STMT(node); |
12999 |
+} |
13000 |
+ |
13001 |
-+static bool has_next_interesting_function_chain_node(next_interesting_function_t next_cnodes_head, struct fn_raw_data *raw_data) |
13002 |
++tree create_new_var(tree type) |
13003 |
+{ |
13004 |
-+ next_interesting_function_t cur_node; |
13005 |
-+ |
13006 |
-+ raw_data->decl_str = DECL_NAME_POINTER(raw_data->decl); |
13007 |
-+ raw_data->context = get_decl_context(raw_data->decl); |
13008 |
-+ // Ignore function if there is no context |
13009 |
-+ if (!raw_data->context) |
13010 |
-+ return true; |
13011 |
++ tree new_var = create_tmp_var(type, "cicus"); |
13012 |
+ |
13013 |
-+ for (cur_node = next_cnodes_head; cur_node; cur_node = cur_node->next) { |
13014 |
-+ if (compare_next_interesting_functions(cur_node, raw_data->decl_str, raw_data->context, raw_data->num)) |
13015 |
-+ return true; |
13016 |
-+ } |
13017 |
-+ return false; |
13018 |
++ add_referenced_var(new_var); |
13019 |
++ return new_var; |
13020 |
+} |
13021 |
+ |
13022 |
-+static void handle_function(struct walk_use_def_data *use_def_data, tree fndecl, const_tree arg) |
13023 |
++static bool skip_cast(tree dst_type, const_tree rhs, bool force) |
13024 |
+{ |
13025 |
-+ struct fn_raw_data raw_data; |
13026 |
-+ next_interesting_function_t orig_next_node, new_node; |
13027 |
++ const_gimple def_stmt = get_def_stmt(rhs); |
13028 |
+ |
13029 |
-+ gcc_assert(fndecl != NULL_TREE); |
13030 |
++ if (force) |
13031 |
++ return false; |
13032 |
+ |
13033 |
-+ // ignore builtins to not explode coverage (e.g., memcpy) |
13034 |
-+ if (DECL_BUILT_IN(fndecl) || DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL) |
13035 |
-+ return; |
13036 |
++ if (is_gimple_constant(rhs)) |
13037 |
++ return false; |
13038 |
+ |
13039 |
-+ if (get_intentional_attr_type(fndecl) == MARK_TURN_OFF) |
13040 |
-+ return; |
13041 |
++ if (!def_stmt || gimple_code(def_stmt) == GIMPLE_NOP) |
13042 |
++ return false; |
13043 |
+ |
13044 |
-+ raw_data.decl = fndecl; |
13045 |
-+ raw_data.decl_str = DECL_NAME_POINTER(fndecl); |
13046 |
-+ raw_data.marked = NO_SO_MARK; |
13047 |
++ if (!types_compatible_p(dst_type, TREE_TYPE(rhs))) |
13048 |
++ return false; |
13049 |
+ |
13050 |
-+ // convert arg into its position |
13051 |
-+ if (arg == NULL_TREE) |
13052 |
-+ raw_data.num = 0; |
13053 |
-+ else |
13054 |
-+ raw_data.num = find_arg_number_tree(arg, raw_data.decl); |
13055 |
-+ if (raw_data.num == CANNOT_FIND_ARG) |
13056 |
-+ return; |
13057 |
++ // DI type can be on 32 bit (from create_assign) but overflow type stays DI |
13058 |
++ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode)) |
13059 |
++ return false; |
13060 |
+ |
13061 |
-+ if (has_next_interesting_function_chain_node(use_def_data->next_cnodes_head, &raw_data)) |
13062 |
-+ return; |
13063 |
++ return true; |
13064 |
++} |
13065 |
+ |
13066 |
-+ if (made_by_compiler(raw_data.decl)) { |
13067 |
-+ orig_next_node = create_orig_next_node_for_a_clone(&raw_data); |
13068 |
-+ if (!orig_next_node) |
13069 |
-+ return; |
13070 |
-+ } else |
13071 |
-+ orig_next_node = NULL; |
13072 |
++tree cast_a_tree(tree type, tree var) |
13073 |
++{ |
13074 |
++ gcc_assert(type != NULL_TREE); |
13075 |
++ gcc_assert(var != NULL_TREE); |
13076 |
++ gcc_assert(fold_convertible_p(type, var)); |
13077 |
+ |
13078 |
-+ new_node = create_new_next_interesting_decl(&raw_data, orig_next_node); |
13079 |
-+ if (!new_node) |
13080 |
-+ return; |
13081 |
-+ new_node->next = use_def_data->next_cnodes_head; |
13082 |
-+ use_def_data->next_cnodes_head = new_node; |
13083 |
++ return fold_convert(type, var); |
13084 |
+} |
13085 |
+ |
13086 |
-+static void walk_use_def_next_functions_phi(struct walk_use_def_data *use_def_data, const_tree result) |
13087 |
++gimple build_cast_stmt(struct visited *visited, tree dst_type, tree rhs, tree lhs, gimple_stmt_iterator *gsi, bool before, bool force) |
13088 |
+{ |
13089 |
-+ gphi *phi = as_a_gphi(get_def_stmt(result)); |
13090 |
-+ unsigned int i, n = gimple_phi_num_args(phi); |
13091 |
++ gassign *assign; |
13092 |
++ gimple def_stmt; |
13093 |
+ |
13094 |
-+ pointer_set_insert(use_def_data->visited, phi); |
13095 |
-+ for (i = 0; i < n; i++) { |
13096 |
-+ tree arg = gimple_phi_arg_def(phi, i); |
13097 |
++ gcc_assert(dst_type != NULL_TREE && rhs != NULL_TREE); |
13098 |
++ gcc_assert(!is_gimple_constant(rhs)); |
13099 |
++ if (gsi_end_p(*gsi) && before == AFTER_STMT) |
13100 |
++ gcc_unreachable(); |
13101 |
+ |
13102 |
-+ walk_use_def_next_functions(use_def_data, arg); |
13103 |
++ def_stmt = get_def_stmt(rhs); |
13104 |
++ if (def_stmt && gimple_code(def_stmt) != GIMPLE_NOP && skip_cast(dst_type, rhs, force) && pointer_set_contains(visited->my_stmts, def_stmt)) |
13105 |
++ return def_stmt; |
13106 |
++ |
13107 |
++ if (lhs == CREATE_NEW_VAR) |
13108 |
++ lhs = create_new_var(dst_type); |
13109 |
++ |
13110 |
++ assign = gimple_build_assign(lhs, cast_a_tree(dst_type, rhs)); |
13111 |
++ |
13112 |
++ if (!gsi_end_p(*gsi)) { |
13113 |
++ location_t loc = gimple_location(gsi_stmt(*gsi)); |
13114 |
++ gimple_set_location(assign, loc); |
13115 |
+ } |
13116 |
++ |
13117 |
++ gimple_assign_set_lhs(assign, make_ssa_name(lhs, assign)); |
13118 |
++ |
13119 |
++ if (before) |
13120 |
++ gsi_insert_before(gsi, assign, GSI_NEW_STMT); |
13121 |
++ else |
13122 |
++ gsi_insert_after(gsi, assign, GSI_NEW_STMT); |
13123 |
++ update_stmt(assign); |
13124 |
++ return assign; |
13125 |
+} |
13126 |
+ |
13127 |
-+static void walk_use_def_next_functions_binary(struct walk_use_def_data *use_def_data, const_tree lhs) |
13128 |
++bool is_size_overflow_type(const_tree var) |
13129 |
+{ |
13130 |
-+ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); |
13131 |
-+ tree rhs1, rhs2; |
13132 |
++ const char *name; |
13133 |
++ const_tree type_name, type; |
13134 |
+ |
13135 |
-+ rhs1 = gimple_assign_rhs1(def_stmt); |
13136 |
-+ rhs2 = gimple_assign_rhs2(def_stmt); |
13137 |
++ if (var == NULL_TREE) |
13138 |
++ return false; |
13139 |
+ |
13140 |
-+ walk_use_def_next_functions(use_def_data, rhs1); |
13141 |
-+ walk_use_def_next_functions(use_def_data, rhs2); |
13142 |
-+} |
13143 |
++ type = TREE_TYPE(var); |
13144 |
++ type_name = TYPE_NAME(type); |
13145 |
++ if (type_name == NULL_TREE) |
13146 |
++ return false; |
13147 |
+ |
13148 |
-+static void walk_use_def_next_functions_unary(struct walk_use_def_data *use_def_data, const gassign *stmt) |
13149 |
-+{ |
13150 |
-+ tree rhs1 = gimple_assign_rhs1(stmt); |
13151 |
++ if (DECL_P(type_name)) |
13152 |
++ name = DECL_NAME_POINTER(type_name); |
13153 |
++ else |
13154 |
++ name = IDENTIFIER_POINTER(type_name); |
13155 |
+ |
13156 |
-+ walk_use_def_next_functions(use_def_data, rhs1); |
13157 |
++ if (!strncmp(name, "size_overflow_type", 18)) |
13158 |
++ return true; |
13159 |
++ return false; |
13160 |
+} |
13161 |
+ |
13162 |
-+void __attribute__((weak)) handle_function_ptr_ret(struct walk_use_def_data *use_def_data __unused, const_tree fn_ptr __unused) |
13163 |
++// Determine if a cloned function has all the original arguments |
13164 |
++static bool unchanged_arglist(struct cgraph_node *new_node, struct cgraph_node *old_node) |
13165 |
+{ |
13166 |
++ const_tree new_decl_list, old_decl_list; |
13167 |
++ |
13168 |
++ if (new_node->clone_of && new_node->clone.tree_map) |
13169 |
++ return !new_node->clone.args_to_skip; |
13170 |
++ |
13171 |
++ new_decl_list = DECL_ARGUMENTS(NODE_DECL(new_node)); |
13172 |
++ old_decl_list = DECL_ARGUMENTS(NODE_DECL(old_node)); |
13173 |
++ if (new_decl_list != NULL_TREE && old_decl_list != NULL_TREE) |
13174 |
++ gcc_assert(list_length(new_decl_list) == list_length(old_decl_list)); |
13175 |
++ |
13176 |
++ return true; |
13177 |
+} |
13178 |
+ |
13179 |
-+static void create_and_append_new_next_interesting_field_var_decl(struct walk_use_def_data *use_def_data, struct fn_raw_data *raw_data) |
13180 |
++unsigned int get_correct_argnum_fndecl(const_tree fndecl, const_tree correct_argnum_of_fndecl, unsigned int num) |
13181 |
+{ |
13182 |
-+ next_interesting_function_t new_node; |
13183 |
-+ |
13184 |
-+ if (raw_data->decl == NULL_TREE) |
13185 |
-+ return; |
13186 |
++ unsigned int new_num; |
13187 |
++ const_tree fndecl_arg; |
13188 |
++ tree fndecl_arglist = DECL_ARGUMENTS(fndecl); |
13189 |
++ const_tree arg, target_fndecl_arglist; |
13190 |
+ |
13191 |
-+ if (DECL_NAME(raw_data->decl) == NULL_TREE) |
13192 |
-+ return; |
13193 |
++ if (num == 0) |
13194 |
++ return num; |
13195 |
+ |
13196 |
-+ raw_data->decl_str = DECL_NAME_POINTER(raw_data->decl); |
13197 |
-+ raw_data->num = 0; |
13198 |
-+ raw_data->marked = NO_SO_MARK; |
13199 |
++ if (fndecl == correct_argnum_of_fndecl && !DECL_ARTIFICIAL(fndecl)) |
13200 |
++ return num; |
13201 |
++ else if (fndecl == correct_argnum_of_fndecl && DECL_ARTIFICIAL(fndecl)) |
13202 |
++ return CANNOT_FIND_ARG; |
13203 |
+ |
13204 |
-+ new_node = create_new_next_interesting_decl(raw_data, NULL); |
13205 |
-+ if (!new_node) |
13206 |
-+ return; |
13207 |
-+ new_node->next = use_def_data->next_cnodes_head; |
13208 |
-+ use_def_data->next_cnodes_head = new_node; |
13209 |
-+} |
13210 |
++ target_fndecl_arglist = DECL_ARGUMENTS(correct_argnum_of_fndecl); |
13211 |
++ if (fndecl_arglist == NULL_TREE || target_fndecl_arglist == NULL_TREE) |
13212 |
++ return CANNOT_FIND_ARG; |
13213 |
+ |
13214 |
-+static void handle_struct_fields(struct walk_use_def_data *use_def_data, const_tree node) |
13215 |
-+{ |
13216 |
-+ struct fn_raw_data raw_data; |
13217 |
++ fndecl_arg = chain_index(num - 1, fndecl_arglist); |
13218 |
++ if (fndecl_arg == NULL_TREE) |
13219 |
++ return CANNOT_FIND_ARG; |
13220 |
+ |
13221 |
-+ switch (TREE_CODE(node)) { |
13222 |
-+ case ARRAY_REF: |
13223 |
-+#if BUILDING_GCC_VERSION >= 4006 |
13224 |
-+ case MEM_REF: |
13225 |
-+#endif |
13226 |
-+ case INDIRECT_REF: |
13227 |
-+ case COMPONENT_REF: |
13228 |
-+ raw_data.decl = get_ref_field(node); |
13229 |
-+ break; |
13230 |
-+ // TODO |
13231 |
-+ case BIT_FIELD_REF: |
13232 |
-+ case VIEW_CONVERT_EXPR: |
13233 |
-+ case REALPART_EXPR: |
13234 |
-+ case IMAGPART_EXPR: |
13235 |
-+ return; |
13236 |
-+ default: |
13237 |
-+ debug_tree(node); |
13238 |
-+ gcc_unreachable(); |
13239 |
++ for (arg = target_fndecl_arglist, new_num = 1; arg; arg = TREE_CHAIN(arg), new_num++) { |
13240 |
++ if (arg == fndecl_arg || !strcmp(DECL_NAME_POINTER(arg), DECL_NAME_POINTER(fndecl_arg))) |
13241 |
++ return new_num; |
13242 |
+ } |
13243 |
+ |
13244 |
-+ if (get_intentional_attr_type(raw_data.decl) == MARK_TURN_OFF) |
13245 |
-+ return; |
13246 |
-+ |
13247 |
-+ create_and_append_new_next_interesting_field_var_decl(use_def_data, &raw_data); |
13248 |
++ return CANNOT_FIND_ARG; |
13249 |
+} |
13250 |
+ |
13251 |
-+static void handle_vardecl(struct walk_use_def_data *use_def_data, tree node) |
13252 |
++// Find the specified argument in the originally cloned function |
13253 |
++static unsigned int clone_argnum_on_orig(struct cgraph_node *new_node, struct cgraph_node *old_node, unsigned int clone_argnum) |
13254 |
+{ |
13255 |
-+ struct fn_raw_data raw_data; |
13256 |
++ bitmap args_to_skip; |
13257 |
++ unsigned int i, new_argnum = clone_argnum; |
13258 |
+ |
13259 |
-+ raw_data.decl = node; |
13260 |
-+ create_and_append_new_next_interesting_field_var_decl(use_def_data, &raw_data); |
13261 |
++ if (unchanged_arglist(new_node, old_node)) |
13262 |
++ return clone_argnum; |
13263 |
++ |
13264 |
++ gcc_assert(new_node->clone_of && new_node->clone.tree_map); |
13265 |
++ args_to_skip = new_node->clone.args_to_skip; |
13266 |
++ for (i = 0; i < clone_argnum; i++) { |
13267 |
++ if (bitmap_bit_p(args_to_skip, i)) |
13268 |
++ new_argnum++; |
13269 |
++ } |
13270 |
++ return new_argnum; |
13271 |
+} |
13272 |
+ |
13273 |
-+/* Find all functions that influence lhs |
13274 |
-+ * |
13275 |
-+ * Encountered functions are added to the children vector (next_interesting_function_t). |
13276 |
-+ */ |
13277 |
-+static void walk_use_def_next_functions(struct walk_use_def_data *use_def_data, tree lhs) |
13278 |
++// Find the specified argument in the clone |
13279 |
++static unsigned int orig_argnum_on_clone(struct cgraph_node *new_node, struct cgraph_node *old_node, unsigned int orig_argnum) |
13280 |
+{ |
13281 |
-+ enum tree_code code; |
13282 |
-+ const_gimple def_stmt; |
13283 |
++ bitmap args_to_skip; |
13284 |
++ unsigned int i, new_argnum = orig_argnum; |
13285 |
+ |
13286 |
-+ if (skip_types(lhs)) |
13287 |
-+ return; |
13288 |
++ if (unchanged_arglist(new_node, old_node)) |
13289 |
++ return orig_argnum; |
13290 |
+ |
13291 |
-+ if (VAR_P(lhs)) { |
13292 |
-+ handle_vardecl(use_def_data, lhs); |
13293 |
-+ return; |
13294 |
-+ } |
13295 |
++ gcc_assert(new_node->clone_of && new_node->clone.tree_map); |
13296 |
++ args_to_skip = new_node->clone.args_to_skip; |
13297 |
++ if (bitmap_bit_p(args_to_skip, orig_argnum - 1)) |
13298 |
++ // XXX torolni kellene a nodeot |
13299 |
++ return CANNOT_FIND_ARG; |
13300 |
+ |
13301 |
-+ code = TREE_CODE(lhs); |
13302 |
-+ if (code == PARM_DECL) { |
13303 |
-+ handle_function(use_def_data, current_function_decl, lhs); |
13304 |
-+ return; |
13305 |
++ for (i = 0; i < orig_argnum; i++) { |
13306 |
++ if (bitmap_bit_p(args_to_skip, i)) |
13307 |
++ new_argnum--; |
13308 |
+ } |
13309 |
++ return new_argnum; |
13310 |
++} |
13311 |
+ |
13312 |
-+ if (TREE_CODE_CLASS(code) == tcc_reference) { |
13313 |
-+ handle_struct_fields(use_def_data, lhs); |
13314 |
-+ return; |
13315 |
-+ } |
13316 |
++// Associate the argument between a clone and a cloned function |
13317 |
++static unsigned int get_correct_argnum_cnode(struct cgraph_node *node, struct cgraph_node *correct_argnum_of_node, unsigned int argnum) |
13318 |
++{ |
13319 |
++ bool node_clone, correct_argnum_of_node_clone; |
13320 |
++ const_tree correct_argnum_of_node_decl, node_decl; |
13321 |
+ |
13322 |
-+ if (code != SSA_NAME) |
13323 |
-+ return; |
13324 |
++ if (node == correct_argnum_of_node) |
13325 |
++ return argnum; |
13326 |
++ if (argnum == 0) |
13327 |
++ return argnum; |
13328 |
+ |
13329 |
-+ def_stmt = get_def_stmt(lhs); |
13330 |
-+ if (!def_stmt) |
13331 |
-+ return; |
13332 |
++ correct_argnum_of_node_decl = NODE_DECL(correct_argnum_of_node); |
13333 |
++ gcc_assert(correct_argnum_of_node_decl != NULL_TREE); |
13334 |
++ gcc_assert(correct_argnum_of_node && !DECL_ARTIFICIAL(correct_argnum_of_node_decl)); |
13335 |
+ |
13336 |
-+ if (pointer_set_insert(use_def_data->visited, def_stmt)) |
13337 |
-+ return; |
13338 |
++ if (node) { |
13339 |
++ node_decl = NODE_DECL(node); |
13340 |
++ gcc_assert(!DECL_ARTIFICIAL(node_decl)); |
13341 |
++ node_clone = made_by_compiler(node_decl); |
13342 |
++ } else { |
13343 |
++ node_decl = NULL_TREE; |
13344 |
++ node_clone = false; |
13345 |
++ } |
13346 |
+ |
13347 |
-+ switch (gimple_code(def_stmt)) { |
13348 |
-+ case GIMPLE_NOP: |
13349 |
-+ walk_use_def_next_functions(use_def_data, SSA_NAME_VAR(lhs)); |
13350 |
-+ return; |
13351 |
-+ case GIMPLE_ASM: |
13352 |
-+ if (!is_size_overflow_asm(def_stmt)) |
13353 |
-+ return; |
13354 |
-+ walk_use_def_next_functions(use_def_data, get_size_overflow_asm_input(as_a_const_gasm(def_stmt))); |
13355 |
-+ return; |
13356 |
-+ case GIMPLE_CALL: { |
13357 |
-+ tree fndecl = gimple_call_fndecl(def_stmt); |
13358 |
++ if (correct_argnum_of_node_decl == node_decl) |
13359 |
++ return argnum; |
13360 |
+ |
13361 |
-+ if (fndecl != NULL_TREE) { |
13362 |
-+ handle_function(use_def_data, fndecl, NULL_TREE); |
13363 |
-+ return; |
13364 |
-+ } |
13365 |
-+ fndecl = gimple_call_fn(def_stmt); |
13366 |
-+ handle_function_ptr_ret(use_def_data, fndecl); |
13367 |
-+ return; |
13368 |
-+ } |
13369 |
-+ case GIMPLE_PHI: |
13370 |
-+ walk_use_def_next_functions_phi(use_def_data, lhs); |
13371 |
-+ return; |
13372 |
-+ case GIMPLE_ASSIGN: |
13373 |
-+ switch (gimple_num_ops(def_stmt)) { |
13374 |
-+ case 2: |
13375 |
-+ walk_use_def_next_functions_unary(use_def_data, as_a_const_gassign(def_stmt)); |
13376 |
-+ return; |
13377 |
-+ case 3: |
13378 |
-+ walk_use_def_next_functions_binary(use_def_data, lhs); |
13379 |
-+ return; |
13380 |
-+ } |
13381 |
-+ default: |
13382 |
-+ debug_gimple_stmt((gimple)def_stmt); |
13383 |
-+ error("%s: unknown gimple code", __func__); |
13384 |
-+ gcc_unreachable(); |
13385 |
++ correct_argnum_of_node_clone = made_by_compiler(correct_argnum_of_node_decl); |
13386 |
++ // the original decl is lost if both nodes are clones |
13387 |
++ if (node_clone && correct_argnum_of_node_clone) { |
13388 |
++ gcc_assert(unchanged_arglist(node, correct_argnum_of_node)); |
13389 |
++ return argnum; |
13390 |
+ } |
13391 |
++ |
13392 |
++ if (node_clone && !correct_argnum_of_node_clone) |
13393 |
++ return clone_argnum_on_orig(correct_argnum_of_node, node, argnum); |
13394 |
++ else if (!node_clone && correct_argnum_of_node_clone) |
13395 |
++ return orig_argnum_on_clone(correct_argnum_of_node, node, argnum); |
13396 |
++ |
13397 |
++ if (node) |
13398 |
++ debug_tree(NODE_DECL(node)); |
13399 |
++ debug_tree(correct_argnum_of_node_decl); |
13400 |
++ gcc_unreachable(); |
13401 |
+} |
13402 |
+ |
13403 |
-+// Start the search for next_interesting_function_t children based on the (next_interesting_function_t) parent node |
13404 |
-+static next_interesting_function_t search_next_functions(tree node, next_interesting_function_t parent) |
13405 |
++unsigned int get_correct_argnum(const_tree decl, const_tree correct_argnum_of_decl, unsigned int argnum) |
13406 |
+{ |
13407 |
-+ struct walk_use_def_data use_def_data; |
13408 |
++ struct cgraph_node *node, *correct_argnum_of_node; |
13409 |
+ |
13410 |
-+ use_def_data.parent = parent; |
13411 |
-+ use_def_data.next_cnodes_head = NULL; |
13412 |
-+ use_def_data.visited = pointer_set_create(); |
13413 |
++ gcc_assert(decl != NULL_TREE); |
13414 |
++ gcc_assert(correct_argnum_of_decl != NULL_TREE); |
13415 |
+ |
13416 |
-+ walk_use_def_next_functions(&use_def_data, node); |
13417 |
++ correct_argnum_of_node = get_cnode(correct_argnum_of_decl); |
13418 |
++ if (!correct_argnum_of_node || DECL_ARTIFICIAL(decl) || DECL_ARTIFICIAL(correct_argnum_of_decl)) |
13419 |
++ return get_correct_argnum_fndecl(decl, correct_argnum_of_decl, argnum); |
13420 |
+ |
13421 |
-+ pointer_set_destroy(use_def_data.visited); |
13422 |
-+ return use_def_data.next_cnodes_head; |
13423 |
++ node = get_cnode(decl); |
13424 |
++ return get_correct_argnum_cnode(node, correct_argnum_of_node, argnum); |
13425 |
+} |
13426 |
+ |
13427 |
-+// True if child already exists in the next_interesting_function_t children vector |
13428 |
-+bool has_next_interesting_function_vec(next_interesting_function_t target, next_interesting_function_t next_node) |
13429 |
++// Find the original cloned function |
13430 |
++tree get_orig_fndecl(const_tree clone_fndecl) |
13431 |
+{ |
13432 |
-+ unsigned int i; |
13433 |
-+ next_interesting_function_t cur; |
13434 |
++ struct cgraph_node *node; |
13435 |
+ |
13436 |
-+ gcc_assert(next_node); |
13437 |
-+ // handle recursion |
13438 |
-+ if (!strcmp(target->decl_name, next_node->decl_name) && target->num == next_node->num) |
13439 |
-+ return true; |
13440 |
++ gcc_assert(TREE_CODE(clone_fndecl) == FUNCTION_DECL); |
13441 |
+ |
13442 |
-+#if BUILDING_GCC_VERSION <= 4007 |
13443 |
-+ if (VEC_empty(next_interesting_function_t, target->children)) |
13444 |
-+ return false; |
13445 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, target->children, i, cur) { |
13446 |
-+#else |
13447 |
-+ FOR_EACH_VEC_SAFE_ELT(target->children, i, cur) { |
13448 |
-+#endif |
13449 |
-+ if (compare_next_interesting_functions(cur, next_node->decl_name, next_node->context, next_node->num)) |
13450 |
-+ return true; |
13451 |
-+ } |
13452 |
-+ return false; |
13453 |
++ if (DECL_ABSTRACT_ORIGIN(clone_fndecl)) |
13454 |
++ return CONST_CAST_TREE(DECL_ABSTRACT_ORIGIN(clone_fndecl)); |
13455 |
++ node = get_cnode(clone_fndecl); |
13456 |
++ if (!node) |
13457 |
++ return CONST_CAST_TREE(clone_fndecl); |
13458 |
++ |
13459 |
++ while (node->clone_of) |
13460 |
++ node = node->clone_of; |
13461 |
++ if (!made_by_compiler(NODE_DECL(node))) |
13462 |
++ return NODE_DECL(node); |
13463 |
++ // Return the cloned decl because it is needed for the transform callback |
13464 |
++ return CONST_CAST_TREE(clone_fndecl); |
13465 |
+} |
13466 |
+ |
13467 |
-+void push_child(next_interesting_function_t parent, next_interesting_function_t child) |
13468 |
++static tree get_interesting_fndecl_from_stmt(const gcall *stmt) |
13469 |
+{ |
13470 |
-+ if (!has_next_interesting_function_vec(parent, child)) { |
13471 |
-+#if BUILDING_GCC_VERSION <= 4007 |
13472 |
-+ VEC_safe_push(next_interesting_function_t, heap, parent->children, child); |
13473 |
-+#else |
13474 |
-+ vec_safe_push(parent->children, child); |
13475 |
-+#endif |
13476 |
-+ } |
13477 |
++ if (gimple_call_num_args(stmt) == 0) |
13478 |
++ return NULL_TREE; |
13479 |
++ return gimple_call_fndecl(stmt); |
13480 |
+} |
13481 |
+ |
13482 |
-+void __attribute__((weak)) check_local_variables(next_interesting_function_t next_node __unused) {} |
13483 |
-+ |
13484 |
-+// Add children to parent and global_next_interesting_function |
13485 |
-+static void collect_data_for_execute(next_interesting_function_t parent, next_interesting_function_t children) |
13486 |
++tree get_interesting_orig_fndecl_from_stmt(const gcall *stmt) |
13487 |
+{ |
13488 |
-+ next_interesting_function_t cur = children; |
13489 |
-+ |
13490 |
-+ gcc_assert(parent); |
13491 |
-+ |
13492 |
-+ while (cur) { |
13493 |
-+ struct fn_raw_data child_raw_data; |
13494 |
-+ next_interesting_function_t next, child; |
13495 |
-+ |
13496 |
-+ next = cur->next; |
13497 |
++ tree fndecl; |
13498 |
+ |
13499 |
-+ child_raw_data.decl_str = cur->decl_name; |
13500 |
-+ child_raw_data.context = cur->context; |
13501 |
-+ child_raw_data.hash = cur->hash; |
13502 |
-+ child_raw_data.num = cur->num; |
13503 |
-+ child_raw_data.marked = NO_SO_MARK; |
13504 |
-+ child = get_global_next_interesting_function_entry(&child_raw_data); |
13505 |
-+ if (!child) { |
13506 |
-+ add_to_global_next_interesting_function(cur); |
13507 |
-+ child = cur; |
13508 |
-+ } |
13509 |
++ fndecl = get_interesting_fndecl_from_stmt(stmt); |
13510 |
++ if (fndecl == NULL_TREE) |
13511 |
++ return NULL_TREE; |
13512 |
++ return get_orig_fndecl(fndecl); |
13513 |
++} |
13514 |
+ |
13515 |
-+ check_local_variables(child); |
13516 |
++void set_dominance_info(void) |
13517 |
++{ |
13518 |
++ calculate_dominance_info(CDI_DOMINATORS); |
13519 |
++ calculate_dominance_info(CDI_POST_DOMINATORS); |
13520 |
++} |
13521 |
+ |
13522 |
-+ push_child(parent, child); |
13523 |
++void unset_dominance_info(void) |
13524 |
++{ |
13525 |
++ free_dominance_info(CDI_DOMINATORS); |
13526 |
++ free_dominance_info(CDI_POST_DOMINATORS); |
13527 |
++} |
13528 |
+ |
13529 |
-+ cur = next; |
13530 |
-+ } |
13531 |
++void set_current_function_decl(tree fndecl) |
13532 |
++{ |
13533 |
++ gcc_assert(fndecl != NULL_TREE); |
13534 |
+ |
13535 |
-+ check_local_variables(parent); |
13536 |
++ push_cfun(DECL_STRUCT_FUNCTION(fndecl)); |
13537 |
++#if BUILDING_GCC_VERSION <= 4007 |
13538 |
++ current_function_decl = fndecl; |
13539 |
++#endif |
13540 |
++ set_dominance_info(); |
13541 |
+} |
13542 |
+ |
13543 |
-+next_interesting_function_t __attribute__((weak)) get_and_create_next_node_from_global_next_nodes_fnptr(const_tree fn_ptr __unused, struct fn_raw_data *raw_data __unused) |
13544 |
++void unset_current_function_decl(void) |
13545 |
+{ |
13546 |
-+ return NULL; |
13547 |
++ unset_dominance_info(); |
13548 |
++#if BUILDING_GCC_VERSION <= 4007 |
13549 |
++ current_function_decl = NULL_TREE; |
13550 |
++#endif |
13551 |
++ pop_cfun(); |
13552 |
+} |
13553 |
+ |
13554 |
-+static next_interesting_function_t create_parent_next_cnode(const_gimple stmt, unsigned int num) |
13555 |
++bool is_valid_cgraph_node(struct cgraph_node *node) |
13556 |
+{ |
13557 |
-+ struct fn_raw_data raw_data; |
13558 |
-+ |
13559 |
-+ raw_data.num = num; |
13560 |
-+ raw_data.marked = NO_SO_MARK; |
13561 |
++ if (cgraph_function_body_availability(node) == AVAIL_NOT_AVAILABLE) |
13562 |
++ return false; |
13563 |
++ if (node->thunk.thunk_p || node->alias) |
13564 |
++ return false; |
13565 |
++ return true; |
13566 |
++} |
13567 |
+ |
13568 |
++tree get_lhs(const_gimple stmt) |
13569 |
++{ |
13570 |
+ switch (gimple_code(stmt)) { |
13571 |
-+ case GIMPLE_ASM: |
13572 |
-+ raw_data.decl = current_function_decl; |
13573 |
-+ raw_data.marked = ASM_STMT_SO_MARK; |
13574 |
-+ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
13575 |
++ case GIMPLE_ASSIGN: |
13576 |
+ case GIMPLE_CALL: |
13577 |
-+ raw_data.decl = gimple_call_fndecl(stmt); |
13578 |
-+ if (raw_data.decl != NULL_TREE) |
13579 |
-+ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
13580 |
-+ raw_data.decl = gimple_call_fn(stmt); |
13581 |
-+ return get_and_create_next_node_from_global_next_nodes_fnptr(raw_data.decl, &raw_data); |
13582 |
-+ case GIMPLE_RETURN: |
13583 |
-+ raw_data.decl = current_function_decl; |
13584 |
-+ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
13585 |
-+ case GIMPLE_ASSIGN: { |
13586 |
-+ tree lhs = gimple_assign_lhs(stmt); |
13587 |
-+ |
13588 |
-+ if (VAR_P(lhs)) |
13589 |
-+ raw_data.decl = lhs; |
13590 |
-+ else |
13591 |
-+ raw_data.decl = get_ref_field(lhs); |
13592 |
-+ if (raw_data.decl == NULL_TREE) |
13593 |
-+ return NULL; |
13594 |
-+ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
13595 |
-+ } |
13596 |
++ return gimple_get_lhs(stmt); |
13597 |
++ case GIMPLE_PHI: |
13598 |
++ return gimple_phi_result(stmt); |
13599 |
+ default: |
13600 |
+ debug_gimple_stmt((gimple)stmt); |
13601 |
+ gcc_unreachable(); |
13602 |
+ } |
13603 |
+} |
13604 |
+ |
13605 |
-+// Handle potential next_interesting_function_t parent if its argument has an integer type |
13606 |
-+static void collect_all_possible_size_overflow_fns(const_gimple stmt, tree start_var, unsigned int num) |
13607 |
-+{ |
13608 |
-+ next_interesting_function_t children_next_cnode, parent_next_cnode; |
13609 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_plugin.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_plugin.c |
13610 |
+new file mode 100644 |
13611 |
+index 0000000..3f8f032 |
13612 |
+--- /dev/null |
13613 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_plugin.c |
13614 |
+@@ -0,0 +1,290 @@ |
13615 |
++/* |
13616 |
++ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
13617 |
++ * Licensed under the GPL v2, or (at your option) v3 |
13618 |
++ * |
13619 |
++ * Homepage: |
13620 |
++ * https://github.com/ephox-gcc-plugins/size_overflow |
13621 |
++ * |
13622 |
++ * Documentation: |
13623 |
++ * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
13624 |
++ * |
13625 |
++ * This plugin recomputes expressions of function arguments marked by a size_overflow attribute |
13626 |
++ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
13627 |
++ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
13628 |
++ * |
13629 |
++ * Usage: |
13630 |
++ * $ make |
13631 |
++ * $ make run |
13632 |
++ */ |
13633 |
+ |
13634 |
-+ // skip void return values |
13635 |
-+ if (start_var == NULL_TREE) |
13636 |
-+ return; |
13637 |
++#include "size_overflow.h" |
13638 |
+ |
13639 |
-+ if (skip_types(start_var)) |
13640 |
-+ return; |
13641 |
++int plugin_is_GPL_compatible; |
13642 |
+ |
13643 |
-+ // handle intentional MARK_TURN_OFF |
13644 |
-+ if (check_intentional_size_overflow_asm_and_attribute(start_var) == MARK_TURN_OFF) |
13645 |
-+ return; |
13646 |
++tree report_size_overflow_decl; |
13647 |
+ |
13648 |
-+ parent_next_cnode = create_parent_next_cnode(stmt, num); |
13649 |
-+ if (!parent_next_cnode) |
13650 |
-+ return; |
13651 |
++tree size_overflow_type_HI; |
13652 |
++tree size_overflow_type_SI; |
13653 |
++tree size_overflow_type_DI; |
13654 |
++tree size_overflow_type_TI; |
13655 |
+ |
13656 |
-+ children_next_cnode = search_next_functions(start_var, parent_next_cnode); |
13657 |
-+ collect_data_for_execute(parent_next_cnode, children_next_cnode); |
13658 |
-+} |
13659 |
++static struct plugin_info size_overflow_plugin_info = { |
13660 |
++ .version = "20160521", |
13661 |
++ .help = "no-size-overflow\tturn off size overflow checking\n", |
13662 |
++}; |
13663 |
+ |
13664 |
-+static void collect_all_possible_size_overflow_fields_and_vars(const gassign *assign) |
13665 |
++static tree handle_size_overflow_attribute(tree *node, tree __unused name, tree args, int __unused flags, bool *no_add_attrs) |
13666 |
+{ |
13667 |
-+ tree start_var, decl, lhs = gimple_assign_lhs(assign); |
13668 |
-+ |
13669 |
-+ if (VAR_P(lhs)) |
13670 |
-+ decl = lhs; |
13671 |
-+ else |
13672 |
-+ decl = get_ref_field(lhs); |
13673 |
-+ if (decl == NULL_TREE) |
13674 |
-+ return; |
13675 |
++ unsigned int arg_count; |
13676 |
++ enum tree_code code = TREE_CODE(*node); |
13677 |
+ |
13678 |
-+ if (get_intentional_attr_type(decl) == MARK_TURN_OFF) |
13679 |
-+ return; |
13680 |
++ switch (code) { |
13681 |
++ case FUNCTION_DECL: |
13682 |
++ arg_count = type_num_arguments(TREE_TYPE(*node)); |
13683 |
++ break; |
13684 |
++ case FUNCTION_TYPE: |
13685 |
++ case METHOD_TYPE: |
13686 |
++ arg_count = type_num_arguments(*node); |
13687 |
++ break; |
13688 |
++ default: |
13689 |
++ *no_add_attrs = true; |
13690 |
++ debug_tree(*node); |
13691 |
++ error("%s: %qE attribute only applies to functions", __func__, name); |
13692 |
++ return NULL_TREE; |
13693 |
++ } |
13694 |
+ |
13695 |
-+ start_var = gimple_assign_rhs1(assign); |
13696 |
-+ collect_all_possible_size_overflow_fns(assign, start_var, 0); |
13697 |
++ for (; args; args = TREE_CHAIN(args)) { |
13698 |
++ int cur_val; |
13699 |
++ tree position = TREE_VALUE(args); |
13700 |
+ |
13701 |
-+ start_var = gimple_assign_rhs2(assign); |
13702 |
-+ collect_all_possible_size_overflow_fns(assign, start_var, 0); |
13703 |
++ if (TREE_CODE(position) != INTEGER_CST) { |
13704 |
++ error("%s: parameter isn't an integer", __func__); |
13705 |
++ debug_tree(args); |
13706 |
++ *no_add_attrs = true; |
13707 |
++ return NULL_TREE; |
13708 |
++ } |
13709 |
+ |
13710 |
-+#if BUILDING_GCC_VERSION >= 4006 |
13711 |
-+ start_var = gimple_assign_rhs3(assign); |
13712 |
-+ collect_all_possible_size_overflow_fns(assign, start_var, 0); |
13713 |
-+#endif |
13714 |
++ cur_val = tree_to_shwi(position); |
13715 |
++ if (cur_val < 0 || arg_count < (unsigned int)cur_val) { |
13716 |
++ error("%s: parameter %d is outside range.", __func__, cur_val); |
13717 |
++ *no_add_attrs = true; |
13718 |
++ return NULL_TREE; |
13719 |
++ } |
13720 |
++ } |
13721 |
++ return NULL_TREE; |
13722 |
+} |
13723 |
+ |
13724 |
-+// Find potential next_interesting_function_t parents |
13725 |
-+static void handle_cgraph_node(struct cgraph_node *node) |
13726 |
++static tree handle_intentional_overflow_attribute(tree *node, tree __unused name, tree args, int __unused flags, bool *no_add_attrs) |
13727 |
+{ |
13728 |
-+ basic_block bb; |
13729 |
-+ tree cur_fndecl = NODE_DECL(node); |
13730 |
-+ |
13731 |
-+ set_current_function_decl(cur_fndecl); |
13732 |
-+ |
13733 |
-+ FOR_EACH_BB_FN(bb, cfun) { |
13734 |
-+ gimple_stmt_iterator gsi; |
13735 |
-+ |
13736 |
-+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
13737 |
-+ tree start_var; |
13738 |
-+ gimple stmt = gsi_stmt(gsi); |
13739 |
++ unsigned int arg_count; |
13740 |
++ HOST_WIDE_INT s_first_arg; |
13741 |
++ enum tree_code code = TREE_CODE(*node); |
13742 |
+ |
13743 |
-+ switch (gimple_code(stmt)) { |
13744 |
-+ case GIMPLE_RETURN: { |
13745 |
-+ const greturn *return_stmt = as_a_const_greturn(stmt); |
13746 |
++ switch (code) { |
13747 |
++ case FUNCTION_DECL: |
13748 |
++ arg_count = type_num_arguments(TREE_TYPE(*node)); |
13749 |
++ break; |
13750 |
++ case FUNCTION_TYPE: |
13751 |
++ case METHOD_TYPE: |
13752 |
++ arg_count = type_num_arguments(*node); |
13753 |
++ break; |
13754 |
++ case VAR_DECL: |
13755 |
++ case FIELD_DECL: |
13756 |
++ return NULL_TREE; |
13757 |
++ default: |
13758 |
++ *no_add_attrs = true; |
13759 |
++ debug_tree(*node); |
13760 |
++ error("%qE attribute only applies to functions, fields or vars", name); |
13761 |
++ return NULL_TREE; |
13762 |
++ } |
13763 |
+ |
13764 |
-+ start_var = gimple_return_retval(return_stmt); |
13765 |
-+ collect_all_possible_size_overflow_fns(return_stmt, start_var, 0); |
13766 |
-+ break; |
13767 |
-+ } |
13768 |
-+ case GIMPLE_ASM: { |
13769 |
-+ const gasm *asm_stmt = as_a_const_gasm(stmt); |
13770 |
++ s_first_arg = tree_to_shwi(TREE_VALUE(args)); |
13771 |
++ if (s_first_arg == -1) |
13772 |
++ return NULL_TREE; |
13773 |
++ if (s_first_arg < -1) |
13774 |
++ error("%s: parameter %d is outside range.", __func__, (int)s_first_arg); |
13775 |
+ |
13776 |
-+ if (!is_size_overflow_insert_check_asm(asm_stmt)) |
13777 |
-+ break; |
13778 |
-+ start_var = get_size_overflow_asm_input(asm_stmt); |
13779 |
-+ collect_all_possible_size_overflow_fns(asm_stmt, start_var, 0); |
13780 |
-+ break; |
13781 |
-+ } |
13782 |
-+ case GIMPLE_CALL: { |
13783 |
-+ unsigned int i, len; |
13784 |
-+ const gcall *call = as_a_const_gcall(stmt); |
13785 |
-+ tree fndecl = gimple_call_fndecl(call); |
13786 |
++ for (; args; args = TREE_CHAIN(args)) { |
13787 |
++ unsigned int cur_val; |
13788 |
+ |
13789 |
-+ if (fndecl != NULL_TREE && (DECL_BUILT_IN(fndecl) || DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL)) |
13790 |
-+ break; |
13791 |
++ if (TREE_CODE(TREE_VALUE(args)) != INTEGER_CST) { |
13792 |
++ error("%s: parameter isn't an integer", __func__); |
13793 |
++ debug_tree(args); |
13794 |
++ *no_add_attrs = true; |
13795 |
++ return NULL_TREE; |
13796 |
++ } |
13797 |
+ |
13798 |
-+ len = gimple_call_num_args(call); |
13799 |
-+ for (i = 0; i < len; i++) { |
13800 |
-+ start_var = gimple_call_arg(call, i); |
13801 |
-+ collect_all_possible_size_overflow_fns(call, start_var, i + 1); |
13802 |
-+ } |
13803 |
-+ break; |
13804 |
-+ } |
13805 |
-+ case GIMPLE_ASSIGN: |
13806 |
-+ collect_all_possible_size_overflow_fields_and_vars(as_a_const_gassign(stmt)); |
13807 |
-+ break; |
13808 |
-+ default: |
13809 |
-+ break; |
13810 |
-+ } |
13811 |
++ cur_val = (unsigned int)tree_to_uhwi(TREE_VALUE(args)); |
13812 |
++ if (cur_val > arg_count ) { |
13813 |
++ error("%s: parameter %u is outside range. (arg_count: %u)", __func__, cur_val, arg_count); |
13814 |
++ *no_add_attrs = true; |
13815 |
++ return NULL_TREE; |
13816 |
+ } |
13817 |
+ } |
13818 |
-+ |
13819 |
-+ unset_current_function_decl(); |
13820 |
++ return NULL_TREE; |
13821 |
+} |
13822 |
+ |
13823 |
-+/* Collect all potentially interesting function parameters and return values of integer types |
13824 |
-+ * and store their data flow dependencies |
13825 |
-+ */ |
13826 |
-+static void size_overflow_generate_summary(void) |
13827 |
++static struct attribute_spec size_overflow_attr = { |
13828 |
++ .name = "size_overflow", |
13829 |
++ .min_length = 1, |
13830 |
++ .max_length = -1, |
13831 |
++ .decl_required = true, |
13832 |
++ .type_required = false, |
13833 |
++ .function_type_required = false, |
13834 |
++ .handler = handle_size_overflow_attribute, |
13835 |
++#if BUILDING_GCC_VERSION >= 4007 |
13836 |
++ .affects_type_identity = false |
13837 |
++#endif |
13838 |
++}; |
13839 |
++ |
13840 |
++static struct attribute_spec intentional_overflow_attr = { |
13841 |
++ .name = "intentional_overflow", |
13842 |
++ .min_length = 1, |
13843 |
++ .max_length = -1, |
13844 |
++ .decl_required = true, |
13845 |
++ .type_required = false, |
13846 |
++ .function_type_required = false, |
13847 |
++ .handler = handle_intentional_overflow_attribute, |
13848 |
++#if BUILDING_GCC_VERSION >= 4007 |
13849 |
++ .affects_type_identity = false |
13850 |
++#endif |
13851 |
++}; |
13852 |
++ |
13853 |
++static void register_attributes(void __unused *event_data, void __unused *data) |
13854 |
+{ |
13855 |
-+ struct cgraph_node *node; |
13856 |
++ register_attribute(&size_overflow_attr); |
13857 |
++ register_attribute(&intentional_overflow_attr); |
13858 |
++} |
13859 |
+ |
13860 |
-+ size_overflow_register_hooks(); |
13861 |
++static tree create_typedef(tree type, const char* ident) |
13862 |
++{ |
13863 |
++ tree new_type, decl; |
13864 |
+ |
13865 |
-+ FOR_EACH_FUNCTION(node) { |
13866 |
-+ if (is_valid_cgraph_node(node)) |
13867 |
-+ handle_cgraph_node(node); |
13868 |
-+ } |
13869 |
++ new_type = build_variant_type_copy(type); |
13870 |
++ decl = build_decl(BUILTINS_LOCATION, TYPE_DECL, get_identifier(ident), new_type); |
13871 |
++ DECL_ORIGINAL_TYPE(decl) = type; |
13872 |
++ TYPE_NAME(new_type) = decl; |
13873 |
++ return new_type; |
13874 |
+} |
13875 |
+ |
13876 |
-+static void size_overflow_function_insertion_hook(struct cgraph_node *node __unused, void *data __unused) |
13877 |
++// Create the noreturn report_size_overflow() function decl. |
13878 |
++static void size_overflow_start_unit(void __unused *gcc_data, void __unused *user_data) |
13879 |
+{ |
13880 |
-+ debug_cgraph_node(node); |
13881 |
-+ gcc_unreachable(); |
13882 |
++ tree const_char_ptr_type_node; |
13883 |
++ tree fntype; |
13884 |
++ |
13885 |
++ const_char_ptr_type_node = build_pointer_type(build_type_variant(char_type_node, 1, 0)); |
13886 |
++ |
13887 |
++ size_overflow_type_HI = create_typedef(intHI_type_node, "size_overflow_type_HI"); |
13888 |
++ size_overflow_type_SI = create_typedef(intSI_type_node, "size_overflow_type_SI"); |
13889 |
++ size_overflow_type_DI = create_typedef(intDI_type_node, "size_overflow_type_DI"); |
13890 |
++ size_overflow_type_TI = create_typedef(intTI_type_node, "size_overflow_type_TI"); |
13891 |
++ |
13892 |
++ // void report_size_overflow(const char *loc_file, unsigned int loc_line, const char *current_func, const char *ssa_var) |
13893 |
++ fntype = build_function_type_list(void_type_node, |
13894 |
++ const_char_ptr_type_node, |
13895 |
++ unsigned_type_node, |
13896 |
++ const_char_ptr_type_node, |
13897 |
++ const_char_ptr_type_node, |
13898 |
++ NULL_TREE); |
13899 |
++ report_size_overflow_decl = build_fn_decl("report_size_overflow", fntype); |
13900 |
++ |
13901 |
++ DECL_ASSEMBLER_NAME(report_size_overflow_decl); |
13902 |
++ TREE_PUBLIC(report_size_overflow_decl) = 1; |
13903 |
++ DECL_EXTERNAL(report_size_overflow_decl) = 1; |
13904 |
++ DECL_ARTIFICIAL(report_size_overflow_decl) = 1; |
13905 |
++// TREE_THIS_VOLATILE(report_size_overflow_decl) = 1; |
13906 |
++// !!! |
13907 |
++ DECL_PRESERVE_P(report_size_overflow_decl) = 1; |
13908 |
++ DECL_UNINLINABLE(report_size_overflow_decl) = 1; |
13909 |
++ TREE_USED(report_size_overflow_decl) = 1; |
13910 |
++ TREE_NOTHROW(report_size_overflow_decl) = 1; |
13911 |
+} |
13912 |
+ |
13913 |
-+/* Handle dst if src is in the global_next_interesting_function list. |
13914 |
-+ * If src is a clone then dst inherits the orig_next_node of src otherwise |
13915 |
-+ * src will become the orig_next_node of dst. |
13916 |
-+ */ |
13917 |
-+static void size_overflow_node_duplication_hook(struct cgraph_node *src, struct cgraph_node *dst, void *data __unused) |
13918 |
++static bool disable_ubsan_si_overflow_gate(void) |
13919 |
+{ |
13920 |
-+ next_interesting_function_t head, cur; |
13921 |
-+ struct fn_raw_data src_raw_data; |
13922 |
++#if BUILDING_GCC_VERSION >= 4009 |
13923 |
++ flag_sanitize &= ~SANITIZE_SI_OVERFLOW; |
13924 |
++#endif |
13925 |
++ return true; |
13926 |
++} |
13927 |
+ |
13928 |
-+ src_raw_data.decl = NODE_DECL(src); |
13929 |
-+ src_raw_data.decl_str = DECL_NAME_POINTER(src_raw_data.decl); |
13930 |
-+ src_raw_data.context = get_decl_context(src_raw_data.decl); |
13931 |
-+ if (!src_raw_data.context) |
13932 |
-+ return; |
13933 |
++#define PASS_NAME disable_ubsan_si_overflow |
13934 |
+ |
13935 |
-+ src_raw_data.num = NONE_ARGNUM; |
13936 |
-+ src_raw_data.marked = NO_SO_MARK; |
13937 |
++#define NO_EXECUTE |
13938 |
+ |
13939 |
-+ head = get_global_next_interesting_function_entry_with_hash(&src_raw_data); |
13940 |
-+ if (!head) |
13941 |
-+ return; |
13942 |
++#include "gcc-generate-gimple-pass.h" |
13943 |
+ |
13944 |
-+ for (cur = head; cur; cur = cur->next) { |
13945 |
-+ struct fn_raw_data dst_raw_data; |
13946 |
-+ next_interesting_function_t orig_next_node, next_node; |
13947 |
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
13948 |
++{ |
13949 |
++ int i; |
13950 |
++ const char * const plugin_name = plugin_info->base_name; |
13951 |
++ const int argc = plugin_info->argc; |
13952 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
13953 |
++ bool enable = true; |
13954 |
++ struct register_pass_info insert_size_overflow_asm_pass_info; |
13955 |
++ struct register_pass_info size_overflow_pass_info; |
13956 |
++#if BUILDING_GCC_VERSION >= 4009 |
13957 |
++ struct register_pass_info disable_ubsan_si_overflow_pass_info; |
13958 |
++#endif |
13959 |
+ |
13960 |
-+ if (!compare_next_interesting_functions(cur, src_raw_data.decl_str, src_raw_data.context, src_raw_data.num)) |
13961 |
-+ continue; |
13962 |
++ static const struct ggc_root_tab gt_ggc_r_gt_size_overflow[] = { |
13963 |
++ { |
13964 |
++ .base = &report_size_overflow_decl, |
13965 |
++ .nelt = 1, |
13966 |
++ .stride = sizeof(report_size_overflow_decl), |
13967 |
++ .cb = >_ggc_mx_tree_node, |
13968 |
++ .pchw = >_pch_nx_tree_node |
13969 |
++ }, |
13970 |
++ LAST_GGC_ROOT_TAB |
13971 |
++ }; |
13972 |
+ |
13973 |
-+ dst_raw_data.decl = NODE_DECL(dst); |
13974 |
-+ dst_raw_data.decl_str = cgraph_node_name(dst); |
13975 |
-+ dst_raw_data.marked = cur->marked; |
13976 |
++ insert_size_overflow_asm_pass_info.pass = make_insert_size_overflow_asm_pass(); |
13977 |
++ insert_size_overflow_asm_pass_info.reference_pass_name = "ssa"; |
13978 |
++ insert_size_overflow_asm_pass_info.ref_pass_instance_number = 1; |
13979 |
++ insert_size_overflow_asm_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
13980 |
+ |
13981 |
-+ if (!made_by_compiler(dst_raw_data.decl)) |
13982 |
-+ break; |
13983 |
++ size_overflow_pass_info.pass = make_size_overflow_pass(); |
13984 |
++ size_overflow_pass_info.reference_pass_name = "inline"; |
13985 |
++ size_overflow_pass_info.ref_pass_instance_number = 1; |
13986 |
++ size_overflow_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
13987 |
+ |
13988 |
-+ // For clones use the original node instead |
13989 |
-+ if (cur->orig_next_node) |
13990 |
-+ orig_next_node = cur->orig_next_node; |
13991 |
-+ else |
13992 |
-+ orig_next_node = cur; |
13993 |
++ if (!plugin_default_version_check(version, &gcc_version)) { |
13994 |
++ error(G_("incompatible gcc/plugin versions")); |
13995 |
++ return 1; |
13996 |
++ } |
13997 |
+ |
13998 |
-+ dst_raw_data.num = get_correct_argnum_fndecl(src_raw_data.decl, dst_raw_data.decl, cur->num); |
13999 |
-+ if (dst_raw_data.num == CANNOT_FIND_ARG) |
14000 |
++ for (i = 0; i < argc; ++i) { |
14001 |
++ if (!strcmp(argv[i].key, "no-size-overflow")) { |
14002 |
++ enable = false; |
14003 |
+ continue; |
14004 |
++ } |
14005 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
14006 |
++ } |
14007 |
+ |
14008 |
-+ next_node = create_new_next_interesting_decl(&dst_raw_data, orig_next_node); |
14009 |
-+ if (next_node) |
14010 |
-+ add_to_global_next_interesting_function(next_node); |
14011 |
++ register_callback(plugin_name, PLUGIN_INFO, NULL, &size_overflow_plugin_info); |
14012 |
++ if (enable) { |
14013 |
++#if BUILDING_GCC_VERSION >= 4009 |
14014 |
++ if (flag_sanitize & SANITIZE_SI_OVERFLOW) { |
14015 |
++ error(G_("ubsan SANITIZE_SI_OVERFLOW option is unsupported")); |
14016 |
++ return 1; |
14017 |
++ } |
14018 |
++#endif |
14019 |
++ register_callback(plugin_name, PLUGIN_START_UNIT, &size_overflow_start_unit, NULL); |
14020 |
++ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_size_overflow); |
14021 |
++#if BUILDING_GCC_VERSION >= 4009 |
14022 |
++ flag_sanitize |= SANITIZE_SI_OVERFLOW; |
14023 |
++ disable_ubsan_si_overflow_pass_info.pass = make_disable_ubsan_si_overflow_pass(); |
14024 |
++ disable_ubsan_si_overflow_pass_info.reference_pass_name = "ubsan"; |
14025 |
++ disable_ubsan_si_overflow_pass_info.ref_pass_instance_number = 1; |
14026 |
++ disable_ubsan_si_overflow_pass_info.pos_op = PASS_POS_REPLACE; |
14027 |
++ |
14028 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &disable_ubsan_si_overflow_pass_info); |
14029 |
++#endif |
14030 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &insert_size_overflow_asm_pass_info); |
14031 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &size_overflow_pass_info); |
14032 |
+ } |
14033 |
++ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
14034 |
++ |
14035 |
++ return 0; |
14036 |
+} |
14037 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_plugin_hash.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_plugin_hash.c |
14038 |
+new file mode 100644 |
14039 |
+index 0000000..87af656 |
14040 |
+--- /dev/null |
14041 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_plugin_hash.c |
14042 |
+@@ -0,0 +1,352 @@ |
14043 |
++/* |
14044 |
++ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
14045 |
++ * Licensed under the GPL v2, or (at your option) v3 |
14046 |
++ * |
14047 |
++ * Homepage: |
14048 |
++ * https://github.com/ephox-gcc-plugins/size_overflow |
14049 |
++ * |
14050 |
++ * Documentation: |
14051 |
++ * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
14052 |
++ * |
14053 |
++ * This plugin recomputes expressions of function arguments marked by a size_overflow attribute |
14054 |
++ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
14055 |
++ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
14056 |
++ * |
14057 |
++ * Usage: |
14058 |
++ * $ make |
14059 |
++ * $ make run |
14060 |
++ */ |
14061 |
+ |
14062 |
-+void size_overflow_register_hooks(void) |
14063 |
-+{ |
14064 |
-+ static bool init_p = false; |
14065 |
++#include "size_overflow.h" |
14066 |
+ |
14067 |
-+ if (init_p) |
14068 |
-+ return; |
14069 |
-+ init_p = true; |
14070 |
++#include "size_overflow_hash.h" |
14071 |
++#include "disable_size_overflow_hash.h" |
14072 |
++#include "size_overflow_hash_aux.h" |
14073 |
+ |
14074 |
-+ function_insertion_hook_holder = cgraph_add_function_insertion_hook(&size_overflow_function_insertion_hook, NULL); |
14075 |
-+ node_duplication_hook_holder = cgraph_add_node_duplication_hook(&size_overflow_node_duplication_hook, NULL); |
14076 |
++static const_tree get_function_type(const_tree decl) |
14077 |
++{ |
14078 |
++ if (FUNCTION_PTR_P(decl)) |
14079 |
++ return TREE_TYPE(TREE_TYPE(decl)); |
14080 |
++ gcc_assert(TREE_CODE(decl) == FUNCTION_DECL); |
14081 |
++ return TREE_TYPE(decl); |
14082 |
+} |
14083 |
+ |
14084 |
-+static void set_yes_so_mark(next_interesting_function_t next_node) |
14085 |
++static unsigned char get_tree_code(const_tree type) |
14086 |
+{ |
14087 |
-+ if (next_node->marked == NO_SO_MARK) { |
14088 |
-+ next_node->marked = YES_SO_MARK; |
14089 |
-+ global_changed = true; |
14090 |
++ switch (TREE_CODE(type)) { |
14091 |
++ case ARRAY_TYPE: |
14092 |
++ return 0; |
14093 |
++ case BOOLEAN_TYPE: |
14094 |
++ return 1; |
14095 |
++ case ENUMERAL_TYPE: |
14096 |
++ return 2; |
14097 |
++ case FUNCTION_TYPE: |
14098 |
++ return 3; |
14099 |
++ case INTEGER_TYPE: |
14100 |
++ return 4; |
14101 |
++ case POINTER_TYPE: |
14102 |
++ return 5; |
14103 |
++ case RECORD_TYPE: |
14104 |
++ return 6; |
14105 |
++ case UNION_TYPE: |
14106 |
++ return 7; |
14107 |
++ case VOID_TYPE: |
14108 |
++ return 8; |
14109 |
++ case REAL_TYPE: |
14110 |
++ return 9; |
14111 |
++ case VECTOR_TYPE: |
14112 |
++ return 10; |
14113 |
++ case REFERENCE_TYPE: |
14114 |
++ return 11; |
14115 |
++ case OFFSET_TYPE: |
14116 |
++ return 12; |
14117 |
++ case COMPLEX_TYPE: |
14118 |
++ return 13; |
14119 |
++ default: |
14120 |
++ debug_tree(type); |
14121 |
++ gcc_unreachable(); |
14122 |
+ } |
14123 |
-+ // Mark the orig decl as well if it's a clone |
14124 |
-+ if (next_node->orig_next_node && next_node->orig_next_node->marked == NO_SO_MARK) { |
14125 |
-+ next_node->orig_next_node->marked = YES_SO_MARK; |
14126 |
-+ global_changed = true; |
14127 |
++} |
14128 |
++ |
14129 |
++// http://www.team5150.com/~andrew/noncryptohashzoo2~/CrapWow.html |
14130 |
++static unsigned int CrapWow(const char *key, unsigned int len, unsigned int seed) |
14131 |
++{ |
14132 |
++#define cwfold( a, b, lo, hi ) { p = (unsigned int)(a) * (unsigned long long)(b); lo ^= (unsigned int)p; hi ^= (unsigned int)(p >> 32); } |
14133 |
++#define cwmixa( in ) { cwfold( in, m, k, h ); } |
14134 |
++#define cwmixb( in ) { cwfold( in, n, h, k ); } |
14135 |
++ |
14136 |
++ unsigned int m = 0x57559429; |
14137 |
++ unsigned int n = 0x5052acdb; |
14138 |
++ const unsigned int *key4 = (const unsigned int *)key; |
14139 |
++ unsigned int h = len; |
14140 |
++ unsigned int k = len + seed + n; |
14141 |
++ unsigned long long p; |
14142 |
++ |
14143 |
++ while (len >= 8) { |
14144 |
++ cwmixb(key4[0]) cwmixa(key4[1]) key4 += 2; |
14145 |
++ len -= 8; |
14146 |
++ } |
14147 |
++ if (len >= 4) { |
14148 |
++ cwmixb(key4[0]) key4 += 1; |
14149 |
++ len -= 4; |
14150 |
+ } |
14151 |
++ if (len) |
14152 |
++ cwmixa(key4[0] & ((1 << (len * 8)) - 1 )); |
14153 |
++ cwmixb(h ^ (k + n)); |
14154 |
++ return k ^ h; |
14155 |
++ |
14156 |
++#undef cwfold |
14157 |
++#undef cwmixa |
14158 |
++#undef cwmixb |
14159 |
+} |
14160 |
+ |
14161 |
-+// Determine whether node or orig node is part of a tracked data flow |
14162 |
-+static bool marked_fn(next_interesting_function_t next_node) |
14163 |
++static void set_hash(struct decl_hash *decl_hash_data) |
14164 |
+{ |
14165 |
-+ bool is_marked_fn, is_marked_orig = false; |
14166 |
-+ |
14167 |
-+ is_marked_fn = next_node->marked != NO_SO_MARK; |
14168 |
-+ |
14169 |
-+ if (next_node->orig_next_node) |
14170 |
-+ is_marked_orig = next_node->orig_next_node->marked != NO_SO_MARK; |
14171 |
++ unsigned int fn, type, codes, seed = 0; |
14172 |
+ |
14173 |
-+ return is_marked_fn || is_marked_orig; |
14174 |
++ fn = CrapWow(decl_hash_data->fn_name, strlen(decl_hash_data->fn_name), seed) & 0xffff; |
14175 |
++ codes = CrapWow((const char*)decl_hash_data->tree_codes, decl_hash_data->tree_codes_len, seed) & 0xffff; |
14176 |
++ type = CrapWow(decl_hash_data->context, strlen(decl_hash_data->context), 0) & 0xffff; |
14177 |
++ decl_hash_data->hash = type ^ fn ^ codes; |
14178 |
+} |
14179 |
+ |
14180 |
-+// Determine whether node or orig node is in the hash table already |
14181 |
-+static bool already_in_the_hashtable(next_interesting_function_t next_node) |
14182 |
++static void set_decl_type_codes(const_tree type, struct decl_hash *decl_hash_data) |
14183 |
+{ |
14184 |
-+ if (next_node->orig_next_node) |
14185 |
-+ next_node = next_node->orig_next_node; |
14186 |
-+ return get_size_overflow_hash_entry(next_node->hash, next_node->decl_name, next_node->context, next_node->num) != NULL; |
14187 |
++ gcc_assert(type != NULL_TREE); |
14188 |
++ gcc_assert(TREE_CODE_CLASS(TREE_CODE(type)) == tcc_type); |
14189 |
++ |
14190 |
++ while (type && decl_hash_data->tree_codes_len < CODES_LIMIT) { |
14191 |
++ decl_hash_data->tree_codes[decl_hash_data->tree_codes_len] = get_tree_code(type); |
14192 |
++ decl_hash_data->tree_codes_len++; |
14193 |
++ type = TREE_TYPE(type); |
14194 |
++ } |
14195 |
+} |
14196 |
+ |
14197 |
-+// Propagate the size_overflow marks up the use-def chains |
14198 |
-+static bool has_marked_child(next_interesting_function_t next_node) |
14199 |
++static void set_result_codes(const_tree node, struct decl_hash *decl_hash_data) |
14200 |
+{ |
14201 |
-+ bool ret = false; |
14202 |
-+ unsigned int i; |
14203 |
-+ next_interesting_function_t child; |
14204 |
++ const_tree result; |
14205 |
+ |
14206 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14207 |
-+ if (VEC_empty(next_interesting_function_t, next_node->children)) |
14208 |
-+ return false; |
14209 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, next_node->children, i, child) { |
14210 |
-+#else |
14211 |
-+ FOR_EACH_VEC_SAFE_ELT(next_node->children, i, child) { |
14212 |
-+#endif |
14213 |
-+ if (marked_fn(child) || already_in_the_hashtable(child)) |
14214 |
-+ ret = true; |
14215 |
++ gcc_assert(node != NULL_TREE); |
14216 |
++ |
14217 |
++ if (DECL_P(node)) { |
14218 |
++ result = DECL_RESULT(node); |
14219 |
++ if (result != NULL_TREE) |
14220 |
++ return set_decl_type_codes(TREE_TYPE(result), decl_hash_data); |
14221 |
++ return set_result_codes(TREE_TYPE(node), decl_hash_data); |
14222 |
+ } |
14223 |
+ |
14224 |
-+ return ret; |
14225 |
++ gcc_assert(TYPE_P(node)); |
14226 |
++ |
14227 |
++ if (TREE_CODE(node) == FUNCTION_TYPE) |
14228 |
++ return set_result_codes(TREE_TYPE(node), decl_hash_data); |
14229 |
++ |
14230 |
++ return set_decl_type_codes(node, decl_hash_data); |
14231 |
+} |
14232 |
+ |
14233 |
-+/* Set YES_SO_MARK on the function, its orig node and children if: |
14234 |
-+ * * the function or its orig node or one of its children is in the hash table already |
14235 |
-+ * * the function's orig node is marked with YES_SO_MARK or ASM_STMT_SO_MARK |
14236 |
-+ * * one of the children is marked with YES_SO_MARK or ASM_STMT_SO_MARK |
14237 |
-+ */ |
14238 |
-+static bool set_fn_so_mark(next_interesting_function_t next_node) |
14239 |
++static void set_decl_codes(struct decl_hash *decl_hash_data) |
14240 |
+{ |
14241 |
-+ bool so_fn, so_hashtable, so_child; |
14242 |
++ const_tree arg, type; |
14243 |
++ enum tree_code code; |
14244 |
+ |
14245 |
-+ so_hashtable = already_in_the_hashtable(next_node); |
14246 |
-+ so_fn = marked_fn(next_node); |
14247 |
-+ so_child = has_marked_child(next_node); |
14248 |
++ if (TREE_CODE(decl_hash_data->decl) == VAR_DECL || TREE_CODE(decl_hash_data->decl) == FIELD_DECL) { |
14249 |
++ set_decl_type_codes(TREE_TYPE(decl_hash_data->decl), decl_hash_data); |
14250 |
++ return; |
14251 |
++ } |
14252 |
+ |
14253 |
-+ if (!so_fn && !so_hashtable && !so_child) |
14254 |
-+ return false; |
14255 |
-+ set_yes_so_mark(next_node); |
14256 |
-+ return true; |
14257 |
++ type = get_function_type(decl_hash_data->decl); |
14258 |
++ code = TREE_CODE(type); |
14259 |
++ gcc_assert(code == FUNCTION_TYPE || code == METHOD_TYPE); |
14260 |
++ |
14261 |
++ if (FUNCTION_PTR_P(decl_hash_data->decl)) |
14262 |
++ set_result_codes(type, decl_hash_data); |
14263 |
++ else |
14264 |
++ set_result_codes(decl_hash_data->decl, decl_hash_data); |
14265 |
++ |
14266 |
++ for (arg = TYPE_ARG_TYPES(type); arg != NULL_TREE && decl_hash_data->tree_codes_len < CODES_LIMIT; arg = TREE_CHAIN(arg)) |
14267 |
++ set_decl_type_codes(TREE_VALUE(arg), decl_hash_data); |
14268 |
+} |
14269 |
+ |
14270 |
-+// Determine if any of the function pointer targets have data flow between the return value and one of the arguments |
14271 |
-+static next_interesting_function_t get_same_not_ret_child(next_interesting_function_t parent) |
14272 |
++static const struct size_overflow_hash *get_proper_hash_chain(const struct size_overflow_hash *entry, const char *func_name, const char *context) |
14273 |
+{ |
14274 |
-+ unsigned int i; |
14275 |
-+ next_interesting_function_t child; |
14276 |
-+ |
14277 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14278 |
-+ if (VEC_empty(next_interesting_function_t, parent->children)) |
14279 |
-+ return NULL; |
14280 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
14281 |
-+#else |
14282 |
-+ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
14283 |
-+#endif |
14284 |
-+ if (child->num == 0) |
14285 |
-+ continue; |
14286 |
-+ if (strcmp(parent->decl_name, child->decl_name)) |
14287 |
++ for (; entry; entry = entry->next) { |
14288 |
++ if (strcmp(entry->name, func_name)) |
14289 |
+ continue; |
14290 |
-+ if (!strcmp(child->context, "fndecl")) |
14291 |
-+ return child; |
14292 |
++ if (!strcmp(entry->context, context)) |
14293 |
++ return entry; |
14294 |
+ } |
14295 |
+ return NULL; |
14296 |
+} |
14297 |
+ |
14298 |
-+/* Trace a return value of function pointer type back to an argument via a concrete function |
14299 |
-+ fnptr 0 && fn 0 && (fn 0 -> fn 2) => fnptr 2 */ |
14300 |
-+static void search_missing_fptr_arg(next_interesting_function_t parent) |
14301 |
++unsigned int get_decl_hash(const_tree decl, const char *decl_name) |
14302 |
+{ |
14303 |
-+ next_interesting_function_t child; |
14304 |
-+ unsigned int i; |
14305 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14306 |
-+ VEC(next_interesting_function_t, heap) *new_children = NULL; |
14307 |
-+#else |
14308 |
-+ vec<next_interesting_function_t, va_heap, vl_embed> *new_children = NULL; |
14309 |
-+#endif |
14310 |
-+ |
14311 |
-+ if (parent->num != 0) |
14312 |
-+ return; |
14313 |
-+ if (!strcmp(parent->context, "fndecl")) |
14314 |
-+ return; |
14315 |
-+ if (!strncmp(parent->context, "vardecl", sizeof("vardecl") - 1)) |
14316 |
-+ return; |
14317 |
-+ |
14318 |
-+ // fnptr 0 && fn 0 |
14319 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14320 |
-+ if (VEC_empty(next_interesting_function_t, parent->children)) |
14321 |
-+ return; |
14322 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
14323 |
-+#else |
14324 |
-+ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
14325 |
-+#endif |
14326 |
-+ next_interesting_function_t cur_next_node, tracked_fn; |
14327 |
-+ |
14328 |
-+ if (child->num != 0) |
14329 |
-+ continue; |
14330 |
-+ // (fn 0 -> fn 2) |
14331 |
-+ tracked_fn = get_same_not_ret_child(child); |
14332 |
-+ if (!tracked_fn) |
14333 |
-+ continue; |
14334 |
++ struct decl_hash decl_hash_data; |
14335 |
++ enum tree_code code = TREE_CODE(decl); |
14336 |
+ |
14337 |
-+ // fn 2 => fnptr 2 |
14338 |
-+ for (cur_next_node = global_next_interesting_function[parent->hash]; cur_next_node; cur_next_node = cur_next_node->next) { |
14339 |
-+ if (cur_next_node->num != tracked_fn->num) |
14340 |
-+ continue; |
14341 |
++ gcc_assert(code == FIELD_DECL || code == FUNCTION_DECL || code == VAR_DECL); |
14342 |
+ |
14343 |
-+ if (strcmp(parent->decl_name, cur_next_node->decl_name)) |
14344 |
-+ continue; |
14345 |
++ // skip builtins __builtin_constant_p |
14346 |
++ if (code == FUNCTION_DECL && (DECL_BUILT_IN(decl) || DECL_BUILT_IN_CLASS(decl) == BUILT_IN_NORMAL)) |
14347 |
++ return NO_HASH; |
14348 |
+ |
14349 |
-+ if (!has_next_interesting_function_vec(parent, cur_next_node)) { |
14350 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14351 |
-+ VEC_safe_push(next_interesting_function_t, heap, new_children, cur_next_node); |
14352 |
-+#else |
14353 |
-+ vec_safe_push(new_children, cur_next_node); |
14354 |
-+#endif |
14355 |
-+ } |
14356 |
-+ } |
14357 |
-+ } |
14358 |
++ decl_hash_data.fn_name = decl_name; |
14359 |
++ decl_hash_data.decl = decl; |
14360 |
++ decl_hash_data.context = get_decl_context(decl); |
14361 |
++ if (!decl_hash_data.context) |
14362 |
++ return NO_HASH; |
14363 |
++ decl_hash_data.tree_codes_len = 0; |
14364 |
+ |
14365 |
-+#if BUILDING_GCC_VERSION == 4005 |
14366 |
-+ if (VEC_empty(next_interesting_function_t, new_children)) |
14367 |
-+ return; |
14368 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, new_children, i, child) |
14369 |
-+ VEC_safe_push(next_interesting_function_t, heap, parent->children, child); |
14370 |
-+#elif BUILDING_GCC_VERSION <= 4007 |
14371 |
-+ VEC_safe_splice(next_interesting_function_t, heap, parent->children, new_children); |
14372 |
-+#else |
14373 |
-+ vec_safe_splice(parent->children, new_children); |
14374 |
-+#endif |
14375 |
++ set_decl_codes(&decl_hash_data); |
14376 |
++ gcc_assert(decl_hash_data.tree_codes_len != 0); |
14377 |
++ set_hash(&decl_hash_data); |
14378 |
++ return decl_hash_data.hash; |
14379 |
+} |
14380 |
+ |
14381 |
-+static void walk_so_marked_fns(next_interesting_function_set *visited, next_interesting_function_t parent, bool debug) |
14382 |
++const char *get_orig_decl_name(const_tree decl) |
14383 |
+{ |
14384 |
-+ unsigned int i; |
14385 |
-+ next_interesting_function_t child; |
14386 |
++ const char *name; |
14387 |
++ unsigned int len; |
14388 |
++ const void *end; |
14389 |
++ const_tree orig_decl; |
14390 |
+ |
14391 |
-+ gcc_assert(parent); |
14392 |
-+ if (!set_fn_so_mark(parent)) |
14393 |
-+ return; |
14394 |
++ if (TREE_CODE(decl) == FUNCTION_DECL) |
14395 |
++ orig_decl = DECL_ORIGIN(decl); |
14396 |
++ else |
14397 |
++ orig_decl = decl; |
14398 |
+ |
14399 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14400 |
-+ if (VEC_empty(next_interesting_function_t, parent->children)) |
14401 |
-+ return; |
14402 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
14403 |
-+#else |
14404 |
-+ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
14405 |
-+#endif |
14406 |
-+ set_yes_so_mark(child); |
14407 |
++ len = DECL_NAME_LENGTH(orig_decl); |
14408 |
++ name = DECL_NAME_POINTER(orig_decl); |
14409 |
+ |
14410 |
-+ if (in_lto_p && debug == PRINT_DATA_FLOW) { |
14411 |
-+ fprintf(stderr, " PARENT: decl: %s-%u context: %s %p\n", parent->decl_name, parent->num, parent->context, parent); |
14412 |
-+ fprintf(stderr, " \tCHILD: decl: %s-%u context: %s %p\n", child->decl_name, child->num, child->context, child); |
14413 |
-+ } |
14414 |
++ /* Sometimes gcc loses the original cgraph node leaving only clones behind. |
14415 |
++ * In such cases we will extract the name from the clone and use it in the hash table |
14416 |
++ * without checking the parameter number on the original (unavailable) decl. |
14417 |
++ */ |
14418 |
+ |
14419 |
-+ if (!pointer_set_insert(visited, child)) |
14420 |
-+ walk_so_marked_fns(visited, child, debug); |
14421 |
++ if (made_by_compiler(orig_decl)) { |
14422 |
++ end = memchr(name, '.', len); |
14423 |
++ if (!end) |
14424 |
++ return xstrndup(name, len); |
14425 |
++ len = (long)end - (long)name; |
14426 |
++ gcc_assert(len > 0); |
14427 |
+ } |
14428 |
++ |
14429 |
++ return xstrndup(name, len); |
14430 |
+} |
14431 |
+ |
14432 |
-+// Do a depth-first recursive dump of the next_interesting_function_t children vector |
14433 |
-+static void print_missing_functions(next_interesting_function_set *visited, next_interesting_function_t parent) |
14434 |
++const struct size_overflow_hash *get_disable_size_overflow_hash_entry(unsigned int hash, const char *decl_name, const char *context, unsigned int argnum) |
14435 |
+{ |
14436 |
-+ unsigned int i; |
14437 |
-+ next_interesting_function_t child; |
14438 |
-+ |
14439 |
-+ gcc_assert(parent); |
14440 |
-+ gcc_assert(parent->marked != NO_SO_MARK); |
14441 |
-+ print_missing_function(parent); |
14442 |
++ const struct size_overflow_hash *entry, *entry_node; |
14443 |
+ |
14444 |
-+#if BUILDING_GCC_VERSION <= 4007 |
14445 |
-+ if (VEC_empty(next_interesting_function_t, parent->children)) |
14446 |
-+ return; |
14447 |
-+ FOR_EACH_VEC_ELT(next_interesting_function_t, parent->children, i, child) { |
14448 |
-+#else |
14449 |
-+ FOR_EACH_VEC_SAFE_ELT(parent->children, i, child) { |
14450 |
-+#endif |
14451 |
-+ gcc_assert(child->marked != NO_SO_MARK); |
14452 |
-+ if (!pointer_set_insert(visited, child)) |
14453 |
-+ print_missing_functions(visited, child); |
14454 |
-+ } |
14455 |
++ entry = disable_size_overflow_hash[hash]; |
14456 |
++ entry_node = get_proper_hash_chain(entry, decl_name, context); |
14457 |
++ if (entry_node && entry_node->param & (1U << argnum)) |
14458 |
++ return entry_node; |
14459 |
++ return NULL; |
14460 |
+} |
14461 |
+ |
14462 |
-+// Set YES_SO_MARK on functions that will be emitted into the hash table |
14463 |
-+static void search_so_marked_fns(bool debug) |
14464 |
++const struct size_overflow_hash *get_size_overflow_hash_entry(unsigned int hash, const char *decl_name, const char *context, unsigned int argnum) |
14465 |
+{ |
14466 |
++ const struct size_overflow_hash *entry, *entry_node; |
14467 |
+ |
14468 |
-+ unsigned int i; |
14469 |
-+ next_interesting_function_set *visited; |
14470 |
-+ next_interesting_function_t cur_global; |
14471 |
-+ |
14472 |
-+ visited = next_interesting_function_pointer_set_create(); |
14473 |
-+ for (i = 0; i < GLOBAL_NIFN_LEN; i++) { |
14474 |
-+ for (cur_global = global_next_interesting_function[i]; cur_global; cur_global = cur_global->next) { |
14475 |
-+ if (cur_global->marked == NO_SO_MARK || pointer_set_insert(visited, cur_global)) |
14476 |
-+ continue; |
14477 |
-+ |
14478 |
-+ if (in_lto_p && debug == PRINT_DATA_FLOW) |
14479 |
-+ fprintf(stderr, "Data flow: decl: %s-%u context: %s %p\n", cur_global->decl_name, cur_global->num, cur_global->context, cur_global); |
14480 |
-+ |
14481 |
-+ walk_so_marked_fns(visited, cur_global, debug); |
14482 |
++ entry = size_overflow_hash[hash]; |
14483 |
++ entry_node = get_proper_hash_chain(entry, decl_name, context); |
14484 |
++ if (entry_node && entry_node->param & (1U << argnum)) |
14485 |
++ return entry_node; |
14486 |
+ |
14487 |
-+ if (in_lto_p && debug == PRINT_DATA_FLOW) |
14488 |
-+ fprintf(stderr, "\n"); |
14489 |
-+ } |
14490 |
-+ } |
14491 |
-+ pointer_set_destroy(visited); |
14492 |
++ entry = size_overflow_hash_aux[hash]; |
14493 |
++ entry_node = get_proper_hash_chain(entry, decl_name, context); |
14494 |
++ if (entry_node && entry_node->param & (1U << argnum)) |
14495 |
++ return entry_node; |
14496 |
++ return NULL; |
14497 |
+} |
14498 |
+ |
14499 |
-+// Print functions missing from the hash table |
14500 |
-+static void print_so_marked_fns(void) |
14501 |
++const struct size_overflow_hash *get_size_overflow_hash_entry_tree(const_tree fndecl, unsigned int argnum, bool hash_table) |
14502 |
+{ |
14503 |
-+ unsigned int i; |
14504 |
-+ next_interesting_function_set *visited; |
14505 |
-+ next_interesting_function_t cur_global; |
14506 |
++ const_tree orig_decl; |
14507 |
++ unsigned int orig_argnum, hash; |
14508 |
++ const char *decl_name, *context; |
14509 |
+ |
14510 |
-+ visited = next_interesting_function_pointer_set_create(); |
14511 |
-+ for (i = 0; i < GLOBAL_NIFN_LEN; i++) { |
14512 |
-+ for (cur_global = global_next_interesting_function[i]; cur_global; cur_global = cur_global->next) { |
14513 |
-+ if (cur_global->marked != NO_SO_MARK && !pointer_set_insert(visited, cur_global)) |
14514 |
-+ print_missing_functions(visited, cur_global); |
14515 |
-+ } |
14516 |
++ if (made_by_compiler(fndecl)) { |
14517 |
++ orig_decl = get_orig_fndecl(fndecl); |
14518 |
++ orig_argnum = get_correct_argnum(fndecl, orig_decl, argnum); |
14519 |
++ } else { |
14520 |
++ orig_decl = fndecl; |
14521 |
++ orig_argnum = argnum; |
14522 |
+ } |
14523 |
-+ pointer_set_destroy(visited); |
14524 |
-+} |
14525 |
+ |
14526 |
-+void __attribute__((weak)) check_global_variables(next_interesting_function_t cur_global __unused) {} |
14527 |
++ if (orig_argnum == CANNOT_FIND_ARG) |
14528 |
++ return NULL; |
14529 |
+ |
14530 |
-+// Print all missing interesting functions |
14531 |
-+static unsigned int size_overflow_execute(void) |
14532 |
-+{ |
14533 |
-+ unsigned int i; |
14534 |
-+ next_interesting_function_t cur_global; |
14535 |
++ decl_name = get_orig_decl_name(orig_decl); |
14536 |
++ hash = get_decl_hash(orig_decl, decl_name); |
14537 |
++ if (hash == NO_HASH) |
14538 |
++ return NULL; |
14539 |
+ |
14540 |
-+ if (flag_lto && !in_lto_p) |
14541 |
-+ return 0; |
14542 |
++ context = get_decl_context(orig_decl); |
14543 |
++ if (!context) |
14544 |
++ return NULL; |
14545 |
+ |
14546 |
-+ // Collect vardecls and funtions reachable by function pointers |
14547 |
-+ for (i = 0; i < GLOBAL_NIFN_LEN; i++) { |
14548 |
-+ for (cur_global = global_next_interesting_function[i]; cur_global; cur_global = cur_global->next) { |
14549 |
-+ check_global_variables(cur_global); |
14550 |
-+ search_missing_fptr_arg(cur_global); |
14551 |
-+ } |
14552 |
-+ } |
14553 |
++ if (hash_table == SIZE_OVERFLOW) |
14554 |
++ return get_size_overflow_hash_entry(hash, decl_name, context, orig_argnum); |
14555 |
++ return get_disable_size_overflow_hash_entry(hash, decl_name, context, orig_argnum); |
14556 |
++} |
14557 |
+ |
14558 |
-+ search_so_marked_fns(PRINT_DATA_FLOW); |
14559 |
-+ while (global_changed) { |
14560 |
-+ global_changed = false; |
14561 |
-+ search_so_marked_fns(NO_PRINT_DATA_FLOW); |
14562 |
-+ } |
14563 |
++unsigned int find_arg_number_tree(const_tree arg, const_tree func) |
14564 |
++{ |
14565 |
++ tree var; |
14566 |
++ unsigned int argnum = 1; |
14567 |
+ |
14568 |
-+ print_so_marked_fns(); |
14569 |
++ if (DECL_ARGUMENTS(func) == NULL_TREE) |
14570 |
++ return CANNOT_FIND_ARG; |
14571 |
+ |
14572 |
-+ if (in_lto_p) { |
14573 |
-+ fprintf(stderr, "%s: SIZE_OVERFLOW EXECUTE\n", __func__); |
14574 |
-+ print_global_next_interesting_functions(); |
14575 |
++ if (TREE_CODE(arg) == SSA_NAME) |
14576 |
++ arg = SSA_NAME_VAR(arg); |
14577 |
++ |
14578 |
++ for (var = DECL_ARGUMENTS(func); var; var = TREE_CHAIN(var), argnum++) { |
14579 |
++ if (!operand_equal_p(arg, var, 0) && strcmp(DECL_NAME_POINTER(var), DECL_NAME_POINTER(arg))) |
14580 |
++ continue; |
14581 |
++ if (!skip_types(var)) |
14582 |
++ return argnum; |
14583 |
+ } |
14584 |
+ |
14585 |
-+ return 0; |
14586 |
++ return CANNOT_FIND_ARG; |
14587 |
+} |
14588 |
+ |
14589 |
-+// Omit the IPA/LTO callbacks until https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61311 gets fixed (license concerns) |
14590 |
-+#if BUILDING_GCC_VERSION >= 4008 |
14591 |
-+void __attribute__((weak)) size_overflow_write_summary(void) {} |
14592 |
-+void __attribute__((weak)) size_overflow_write_optimization_summary(void) {} |
14593 |
-+#elif BUILDING_GCC_VERSION >= 4006 |
14594 |
-+void __attribute__((weak)) size_overflow_write_summary(cgraph_node_set set __unused, varpool_node_set vset __unused) {} |
14595 |
-+void __attribute__((weak)) size_overflow_write_optimization_summary(cgraph_node_set set __unused, varpool_node_set vset __unused) {} |
14596 |
-+#else |
14597 |
-+void __attribute__((weak)) size_overflow_write_summary(cgraph_node_set set __unused) {} |
14598 |
-+void __attribute__((weak)) size_overflow_write_optimization_summary(cgraph_node_set set __unused) {} |
14599 |
-+#endif |
14600 |
++const_tree get_attribute(const char* attr_name, const_tree decl) |
14601 |
++{ |
14602 |
++ const_tree attr = lookup_attribute(attr_name, DECL_ATTRIBUTES(decl)); |
14603 |
++ if (attr && TREE_VALUE(attr)) |
14604 |
++ return attr; |
14605 |
++ return NULL_TREE; |
14606 |
++} |
14607 |
+ |
14608 |
-+void __attribute__((weak)) size_overflow_read_summary(void); |
14609 |
-+void __attribute__((weak)) size_overflow_read_optimization_summary(void); |
14610 |
++/* Check if the function has a size_overflow attribute or it is in the size_overflow hash table. |
14611 |
++ * If the function is missing everywhere then print the missing message into stderr. |
14612 |
++ */ |
14613 |
++void print_missing_function(next_interesting_function_t node) |
14614 |
++{ |
14615 |
++ unsigned int argnum, hash; |
14616 |
++ const struct size_overflow_hash *entry; |
14617 |
++ const char *decl_name; |
14618 |
+ |
14619 |
-+#define PASS_NAME size_overflow |
14620 |
++ if (node->marked == ASM_STMT_SO_MARK) |
14621 |
++ return; |
14622 |
+ |
14623 |
-+#define NO_STMT_FIXUP |
14624 |
-+#define NO_VARIABLE_TRANSFORM |
14625 |
-+#define NO_GATE |
14626 |
++ if (node->orig_next_node) { |
14627 |
++ hash = node->orig_next_node->hash; |
14628 |
++ decl_name = node->orig_next_node->decl_name; |
14629 |
++ argnum = node->orig_next_node->num; |
14630 |
++ gcc_assert(!strcmp(node->context, node->orig_next_node->context)); |
14631 |
++ } else { |
14632 |
++ hash = node->hash; |
14633 |
++ decl_name = node->decl_name; |
14634 |
++ argnum = node->num; |
14635 |
++ } |
14636 |
+ |
14637 |
-+#include "gcc-generate-ipa-pass.h" |
14638 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_misc.c b/tools/gcc/size_overflow_plugin/size_overflow_misc.c |
14639 |
++ entry = get_size_overflow_hash_entry(hash, decl_name, node->context, argnum); |
14640 |
++ if (entry) |
14641 |
++ return; |
14642 |
++ |
14643 |
++ // inform() would be too slow |
14644 |
++ fprintf(stderr, "Function %s is missing from the size_overflow hash table +%s+%s+%u+%u+\n", decl_name, decl_name, node->context, argnum, hash); |
14645 |
++} |
14646 |
++ |
14647 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_transform.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_transform.c |
14648 |
new file mode 100644 |
14649 |
-index 0000000..7f459ed |
14650 |
+index 0000000..eebcf4c |
14651 |
--- /dev/null |
14652 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_misc.c |
14653 |
-@@ -0,0 +1,505 @@ |
14654 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_transform.c |
14655 |
+@@ -0,0 +1,743 @@ |
14656 |
+/* |
14657 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
14658 |
+ * Licensed under the GPL v2, or (at your option) v3 |
14659 |
@@ -208621,496 +207074,734 @@ index 0000000..7f459ed |
14660 |
+ |
14661 |
+#include "size_overflow.h" |
14662 |
+ |
14663 |
-+bool is_vararg(const_tree fn, unsigned int num) |
14664 |
++static tree cast_to_orig_type(struct visited *visited, gimple stmt, const_tree orig_node, tree new_node) |
14665 |
+{ |
14666 |
-+ tree arg_list; |
14667 |
++ gimple def_stmt; |
14668 |
++ const_gimple assign; |
14669 |
++ tree result, orig_type = TREE_TYPE(orig_node); |
14670 |
++ gimple_stmt_iterator gsi; |
14671 |
+ |
14672 |
-+ if (num == 0) |
14673 |
-+ return false; |
14674 |
-+ if (fn == NULL_TREE) |
14675 |
-+ return false; |
14676 |
-+ if (TREE_CODE(fn) != FUNCTION_DECL) |
14677 |
-+ return false; |
14678 |
++ if (gimple_code(stmt) != GIMPLE_PHI) { |
14679 |
++ gsi = gsi_for_stmt(stmt); |
14680 |
++ assign = build_cast_stmt(visited, orig_type, new_node, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); |
14681 |
++ return get_lhs(assign); |
14682 |
++ } |
14683 |
+ |
14684 |
-+ arg_list = TYPE_ARG_TYPES(TREE_TYPE(fn)); |
14685 |
-+ if (arg_list == NULL_TREE) |
14686 |
-+ return false; |
14687 |
++ def_stmt = get_def_stmt(new_node); |
14688 |
++ if (gimple_code(def_stmt) == GIMPLE_PHI) |
14689 |
++ gsi = gsi_after_labels(gimple_bb(def_stmt)); |
14690 |
++ else |
14691 |
++ gsi = gsi_for_stmt(def_stmt); |
14692 |
+ |
14693 |
-+ if (tree_last(arg_list) == void_list_node) |
14694 |
-+ return false; |
14695 |
++ result = gimple_phi_result(stmt); |
14696 |
++ assign = build_cast_stmt(visited, orig_type, new_node, SSA_NAME_VAR(result), &gsi, AFTER_STMT, false); |
14697 |
++ return get_lhs(assign); |
14698 |
++} |
14699 |
+ |
14700 |
-+ return num >= (unsigned int)list_length(arg_list); |
14701 |
++static void change_size_overflow_asm_input(gasm *stmt, tree new_input) |
14702 |
++{ |
14703 |
++ tree list; |
14704 |
++ |
14705 |
++ gcc_assert(is_size_overflow_insert_check_asm(stmt)); |
14706 |
++ |
14707 |
++ list = build_tree_list(NULL_TREE, build_string(3, "rm")); |
14708 |
++ list = chainon(NULL_TREE, build_tree_list(list, new_input)); |
14709 |
++ gimple_asm_set_input_op(stmt, 0, list); |
14710 |
+} |
14711 |
+ |
14712 |
-+// Extract the field decl from memory references |
14713 |
-+tree get_ref_field(const_tree ref) |
14714 |
++static void change_field_write_rhs(gassign *assign, const_tree orig_rhs, tree new_rhs) |
14715 |
+{ |
14716 |
-+ tree field; |
14717 |
++ const_tree rhs1, rhs2, rhs3 = NULL_TREE; |
14718 |
++ |
14719 |
++ rhs1 = gimple_assign_rhs1(assign); |
14720 |
++ if (rhs1 == orig_rhs) { |
14721 |
++ gimple_assign_set_rhs1(assign, new_rhs); |
14722 |
++ return; |
14723 |
++ } |
14724 |
++ |
14725 |
++ rhs2 = gimple_assign_rhs2(assign); |
14726 |
++ if (rhs2 == orig_rhs) { |
14727 |
++ gimple_assign_set_rhs2(assign, new_rhs); |
14728 |
++ return; |
14729 |
++ } |
14730 |
+ |
14731 |
-+ // TODO: handle nested memory references |
14732 |
-+ switch (TREE_CODE(ref)) { |
14733 |
-+ case ARRAY_REF: |
14734 |
-+ return NULL_TREE; |
14735 |
+#if BUILDING_GCC_VERSION >= 4006 |
14736 |
-+ case MEM_REF: |
14737 |
++ rhs3 = gimple_assign_rhs3(assign); |
14738 |
++ if (rhs3 == orig_rhs) { |
14739 |
++ gimple_assign_set_rhs3(assign, new_rhs); |
14740 |
++ return; |
14741 |
++ } |
14742 |
+#endif |
14743 |
-+ case INDIRECT_REF: |
14744 |
-+ field = TREE_OPERAND(ref, 0); |
14745 |
++ |
14746 |
++ debug_gimple_stmt(assign); |
14747 |
++ fprintf(stderr, "orig_rhs:\n"); |
14748 |
++ debug_tree(orig_rhs); |
14749 |
++ fprintf(stderr, "rhs1:\n"); |
14750 |
++ debug_tree(rhs1); |
14751 |
++ fprintf(stderr, "rhs2:\n"); |
14752 |
++ debug_tree(rhs2); |
14753 |
++ fprintf(stderr, "rhs3:\n"); |
14754 |
++ debug_tree(rhs3); |
14755 |
++ gcc_unreachable(); |
14756 |
++} |
14757 |
++ |
14758 |
++static void change_phi_arg(gphi *phi, tree new_node, unsigned int num) |
14759 |
++{ |
14760 |
++ unsigned int i; |
14761 |
++ location_t loc = gimple_location(phi); |
14762 |
++ |
14763 |
++ for (i = 0; i < gimple_phi_num_args(phi); i++) { |
14764 |
++ if (i == num) |
14765 |
++ add_phi_arg(phi, new_node, gimple_phi_arg_edge(phi, i), loc); |
14766 |
++ } |
14767 |
++} |
14768 |
++ |
14769 |
++static void change_orig_node(struct visited *visited, gimple stmt, const_tree orig_node, tree new_node, unsigned int num) |
14770 |
++{ |
14771 |
++ tree cast_lhs = cast_to_orig_type(visited, stmt, orig_node, new_node); |
14772 |
++ |
14773 |
++ switch (gimple_code(stmt)) { |
14774 |
++ case GIMPLE_RETURN: |
14775 |
++ gimple_return_set_retval(as_a_greturn(stmt), cast_lhs); |
14776 |
+ break; |
14777 |
-+ case COMPONENT_REF: |
14778 |
-+ field = TREE_OPERAND(ref, 1); |
14779 |
++ case GIMPLE_CALL: |
14780 |
++ gimple_call_set_arg(as_a_gcall(stmt), num - 1, cast_lhs); |
14781 |
++ break; |
14782 |
++ case GIMPLE_ASM: |
14783 |
++ change_size_overflow_asm_input(as_a_gasm(stmt), cast_lhs); |
14784 |
++ break; |
14785 |
++ case GIMPLE_ASSIGN: |
14786 |
++ change_field_write_rhs(as_a_gassign(stmt), orig_node, cast_lhs); |
14787 |
++ break; |
14788 |
++ case GIMPLE_PHI: |
14789 |
++ change_phi_arg(as_a_gphi(stmt), cast_lhs, num); |
14790 |
+ break; |
14791 |
+ default: |
14792 |
-+ return NULL_TREE; |
14793 |
++ debug_gimple_stmt(stmt); |
14794 |
++ gcc_unreachable(); |
14795 |
+ } |
14796 |
+ |
14797 |
-+ // TODO |
14798 |
-+ if (TREE_CODE(field) == SSA_NAME) |
14799 |
-+ return NULL_TREE; |
14800 |
-+ // TODO |
14801 |
-+ if (TREE_CODE(field) != FIELD_DECL) |
14802 |
-+ return NULL_TREE; |
14803 |
-+ // TODO |
14804 |
-+ if (TREE_CODE(field) == ADDR_EXPR) |
14805 |
-+ return NULL_TREE; |
14806 |
++ update_stmt(stmt); |
14807 |
++} |
14808 |
+ |
14809 |
-+ return field; |
14810 |
++// e.g., 3.8.2, 64, arch/x86/ia32/ia32_signal.c copy_siginfo_from_user32(): compat_ptr() u32 max |
14811 |
++static bool skip_asm_cast(const_tree arg) |
14812 |
++{ |
14813 |
++ gimple def_stmt = get_def_stmt(arg); |
14814 |
++ |
14815 |
++ if (!def_stmt || !gimple_assign_cast_p(def_stmt)) |
14816 |
++ return false; |
14817 |
++ |
14818 |
++ def_stmt = get_def_stmt(gimple_assign_rhs1(def_stmt)); |
14819 |
++ if (is_size_overflow_asm(def_stmt)) |
14820 |
++ return false; |
14821 |
++ return def_stmt && gimple_code(def_stmt) == GIMPLE_ASM; |
14822 |
+} |
14823 |
+ |
14824 |
-+const char *get_type_name_from_field(const_tree field_decl) |
14825 |
++static interesting_stmts_t create_interesting_stmts(interesting_stmts_t head, next_interesting_function_t next_node, tree orig_node, gimple first_stmt, unsigned int num) |
14826 |
+{ |
14827 |
-+ const_tree context, type_name; |
14828 |
++ interesting_stmts_t new_node; |
14829 |
+ |
14830 |
-+ if (TREE_CODE(field_decl) != FIELD_DECL) |
14831 |
-+ return NULL; |
14832 |
++ new_node = (interesting_stmts_t )xmalloc(sizeof(*new_node)); |
14833 |
++ new_node->first_stmt = first_stmt; |
14834 |
++ new_node->num = num; |
14835 |
++ new_node->orig_node = orig_node; |
14836 |
++ new_node->next = head; |
14837 |
++ new_node->next_node = next_node; |
14838 |
++ return new_node; |
14839 |
++} |
14840 |
+ |
14841 |
-+ context = DECL_CONTEXT(field_decl); |
14842 |
-+ // TODO |
14843 |
-+ if (TREE_CODE(context) != RECORD_TYPE) |
14844 |
-+ return NULL; |
14845 |
-+ gcc_assert(TREE_CODE(context) == RECORD_TYPE); |
14846 |
-+ type_name = TYPE_NAME(TYPE_MAIN_VARIANT(context)); |
14847 |
-+ if (type_name == NULL_TREE) |
14848 |
-+ return NULL; |
14849 |
++static void free_interesting_stmts(interesting_stmts_t head) |
14850 |
++{ |
14851 |
++ while (head) { |
14852 |
++ interesting_stmts_t cur = head->next; |
14853 |
++ free(head); |
14854 |
++ head = cur; |
14855 |
++ } |
14856 |
++} |
14857 |
+ |
14858 |
-+ if (TREE_CODE(type_name) == IDENTIFIER_NODE) |
14859 |
-+ return IDENTIFIER_POINTER(type_name); |
14860 |
-+ else if (TREE_CODE(type_name) == TYPE_DECL) |
14861 |
-+ return DECL_NAME_POINTER(type_name); |
14862 |
++/* This function calls the main recursion function (expand) that duplicates the stmts. Before that it checks the intentional_overflow attribute, |
14863 |
++ * it decides whether the duplication is necessary or not. After expand() it changes the orig node to the duplicated node |
14864 |
++ * in the original stmt (first stmt) and it inserts the overflow check for the arg of the callee or for the return value. |
14865 |
++ */ |
14866 |
++static interesting_stmts_t search_interesting_stmt(interesting_stmts_t head, next_interesting_function_t next_node, gimple first_stmt, tree orig_node, unsigned int num) |
14867 |
++{ |
14868 |
++ enum tree_code orig_code; |
14869 |
+ |
14870 |
-+ debug_tree(field_decl); |
14871 |
-+ debug_tree(type_name); |
14872 |
-+ gcc_unreachable(); |
14873 |
++ gcc_assert(orig_node != NULL_TREE); |
14874 |
++ |
14875 |
++ if (is_gimple_constant(orig_node)) |
14876 |
++ return head; |
14877 |
++ |
14878 |
++ orig_code = TREE_CODE(orig_node); |
14879 |
++ gcc_assert(orig_code != FIELD_DECL && orig_code != FUNCTION_DECL); |
14880 |
++ |
14881 |
++ if (skip_types(orig_node)) |
14882 |
++ return head; |
14883 |
++ |
14884 |
++ // find a defining marked caller argument or struct field for arg |
14885 |
++ if (check_intentional_size_overflow_asm_and_attribute(orig_node) != MARK_NO) |
14886 |
++ return head; |
14887 |
++ |
14888 |
++ if (skip_asm_cast(orig_node)) |
14889 |
++ return head; |
14890 |
++ |
14891 |
++ return create_interesting_stmts(head, next_node, orig_node, first_stmt, num); |
14892 |
+} |
14893 |
+ |
14894 |
-+// Was the function created by the compiler itself? |
14895 |
-+bool made_by_compiler(const_tree decl) |
14896 |
++static bool is_signed_error_code_const(const_tree node) |
14897 |
+{ |
14898 |
-+ enum tree_code decl_code; |
14899 |
-+ struct cgraph_node *node; |
14900 |
++ HOST_WIDE_INT constant = tree_to_shwi(node); |
14901 |
+ |
14902 |
-+ if (FUNCTION_PTR_P(decl)) |
14903 |
-+ return false; |
14904 |
-+ decl_code = TREE_CODE(decl); |
14905 |
-+ if (decl_code == VAR_DECL || decl_code == FIELD_DECL) |
14906 |
-+ return false; |
14907 |
++ return constant >= -4095 && constant <= -1; |
14908 |
++} |
14909 |
+ |
14910 |
-+ gcc_assert(decl_code == FUNCTION_DECL); |
14911 |
-+ if (DECL_ABSTRACT_ORIGIN(decl) != NULL_TREE && DECL_ABSTRACT_ORIGIN(decl) != decl) |
14912 |
-+ return true; |
14913 |
-+ if (DECL_ARTIFICIAL(decl)) |
14914 |
++static bool is_unsigned_error_code_const(const_tree node) |
14915 |
++{ |
14916 |
++ unsigned HOST_WIDE_INT constant = tree_to_uhwi(node); |
14917 |
++ |
14918 |
++ // ulong -4095 |
14919 |
++ if (constant >= 0xfffffffffffff001) |
14920 |
+ return true; |
14921 |
++ // uint -4095 |
14922 |
++ return constant >= 0xfffff001; |
14923 |
++} |
14924 |
+ |
14925 |
-+ node = get_cnode(decl); |
14926 |
-+ if (!node) |
14927 |
++static bool is_error_code_const(const_tree node) |
14928 |
++{ |
14929 |
++ enum machine_mode mode; |
14930 |
++ |
14931 |
++ if (!is_gimple_constant(node)) |
14932 |
+ return false; |
14933 |
-+ return node->clone_of != NULL; |
14934 |
++ mode = TYPE_MODE(TREE_TYPE(node)); |
14935 |
++ if (mode != SImode && mode != DImode) |
14936 |
++ return false; |
14937 |
++ |
14938 |
++ if (!TYPE_UNSIGNED(TREE_TYPE(node)) && is_signed_error_code_const(node)) |
14939 |
++ return true; |
14940 |
++ return TYPE_UNSIGNED(TREE_TYPE(node)) && is_unsigned_error_code_const(node); |
14941 |
+} |
14942 |
+ |
14943 |
-+bool skip_types(const_tree var) |
14944 |
++static bool has_error_code(gphi *phi) |
14945 |
+{ |
14946 |
-+ const_tree type; |
14947 |
++ unsigned int i, len = gimple_phi_num_args(phi); |
14948 |
+ |
14949 |
-+ type = TREE_TYPE(var); |
14950 |
-+ if (type == NULL_TREE) |
14951 |
-+ return true; |
14952 |
++ for (i = 0; i < len; i++) { |
14953 |
++ const_tree arg = gimple_phi_arg_def(phi, i); |
14954 |
+ |
14955 |
-+ switch (TREE_CODE(type)) { |
14956 |
-+ case INTEGER_TYPE: |
14957 |
-+ case ENUMERAL_TYPE: |
14958 |
-+ return false; |
14959 |
-+ default: |
14960 |
++ if (is_error_code_const(arg)) |
14961 |
+ return true; |
14962 |
+ } |
14963 |
++ |
14964 |
++ return false; |
14965 |
+} |
14966 |
+ |
14967 |
-+gimple get_fnptr_def_stmt(const_tree fn_ptr) |
14968 |
++static interesting_stmts_t search_interesting_rets(interesting_stmts_t head, next_interesting_function_t next_node_ret, greturn *ret) |
14969 |
+{ |
14970 |
-+ gimple def_stmt; |
14971 |
++ tree first_node; |
14972 |
+ |
14973 |
-+ gcc_assert(fn_ptr != NULL_TREE); |
14974 |
-+ gcc_assert(FUNCTION_PTR_P(fn_ptr)); |
14975 |
++ if (!next_node_ret || next_node_ret->marked == ASM_STMT_SO_MARK) |
14976 |
++ return head; |
14977 |
+ |
14978 |
-+ if (is_gimple_constant(fn_ptr)) |
14979 |
-+ return NULL; |
14980 |
++ first_node = gimple_return_retval(ret); |
14981 |
++ if (first_node == NULL_TREE) |
14982 |
++ return head; |
14983 |
+ |
14984 |
-+ def_stmt = get_def_stmt(fn_ptr); |
14985 |
-+ gcc_assert(def_stmt); |
14986 |
-+ return def_stmt; |
14987 |
++ return search_interesting_stmt(head, next_node_ret, ret, first_node, 0); |
14988 |
+} |
14989 |
+ |
14990 |
-+gimple get_def_stmt(const_tree node) |
14991 |
++static void handle_binary_assign(interesting_stmts_t expand_from, gassign *assign, tree rhs) |
14992 |
+{ |
14993 |
-+ gcc_assert(node != NULL_TREE); |
14994 |
++ tree new_node; |
14995 |
++ gimple def_orig_node; |
14996 |
+ |
14997 |
-+ if (TREE_CODE(node) != SSA_NAME) |
14998 |
-+ return NULL; |
14999 |
-+ return SSA_NAME_DEF_STMT(node); |
15000 |
++ new_node = expand(expand_from, rhs); |
15001 |
++ if (new_node == NULL_TREE) |
15002 |
++ return; |
15003 |
++ |
15004 |
++ def_orig_node = get_def_stmt(rhs); |
15005 |
++ if (pointer_set_contains(expand_from->visited->no_cast_check, def_orig_node)) |
15006 |
++ return; |
15007 |
++ change_orig_node(expand_from->visited, assign, rhs, new_node, 0); |
15008 |
++ check_size_overflow(expand_from, assign, TREE_TYPE(new_node), new_node, rhs, BEFORE_STMT); |
15009 |
+} |
15010 |
+ |
15011 |
-+tree create_new_var(tree type) |
15012 |
++static bool search_error_codes(gimple_set *visited_error_codes, interesting_stmts_t expand_from, tree lhs, bool error_code) |
15013 |
+{ |
15014 |
-+ tree new_var = create_tmp_var(type, "cicus"); |
15015 |
++ gimple def_stmt; |
15016 |
+ |
15017 |
-+ add_referenced_var(new_var); |
15018 |
-+ return new_var; |
15019 |
++ def_stmt = get_def_stmt(lhs); |
15020 |
++ if (!def_stmt || gimple_code(def_stmt) == GIMPLE_NOP) |
15021 |
++ return error_code; |
15022 |
++ |
15023 |
++ if (pointer_set_insert(visited_error_codes, def_stmt)) |
15024 |
++ return error_code; |
15025 |
++ |
15026 |
++ if (is_gimple_constant(lhs)) |
15027 |
++ return error_code; |
15028 |
++ if (skip_types(lhs)) |
15029 |
++ return is_error_code_const(lhs); |
15030 |
++ |
15031 |
++ switch (gimple_code(def_stmt)) { |
15032 |
++ case GIMPLE_CALL: |
15033 |
++ case GIMPLE_ASM: |
15034 |
++ return error_code; |
15035 |
++ case GIMPLE_ASSIGN: { |
15036 |
++ tree rhs1, rhs2; |
15037 |
++ gassign *assign = as_a_gassign(def_stmt); |
15038 |
++ |
15039 |
++ switch (gimple_num_ops(assign)) { |
15040 |
++ case 2: |
15041 |
++ return search_error_codes(visited_error_codes, expand_from, gimple_assign_rhs1(def_stmt), error_code); |
15042 |
++ case 3: |
15043 |
++ if (!error_code) |
15044 |
++ return error_code; |
15045 |
++ |
15046 |
++ /* Run stmt duplication from the binary assignment ops (rhs1 and rhs2) |
15047 |
++ * so that size_overflow checking skips the lhs of the last binary assignment |
15048 |
++ * before the error code PHI. |
15049 |
++ */ |
15050 |
++ rhs1 = gimple_assign_rhs1(assign); |
15051 |
++ handle_binary_assign(expand_from, assign, rhs1); |
15052 |
++ rhs2 = gimple_assign_rhs2(assign); |
15053 |
++ handle_binary_assign(expand_from, assign, rhs2); |
15054 |
++ return error_code; |
15055 |
++ } |
15056 |
++ gcc_unreachable(); |
15057 |
++ } |
15058 |
++ case GIMPLE_PHI: { |
15059 |
++ unsigned int i; |
15060 |
++ |
15061 |
++ error_code = has_error_code(as_a_gphi(def_stmt)); |
15062 |
++ for (i = 0; i < gimple_phi_num_args(def_stmt); i++) { |
15063 |
++ error_code = search_error_codes(visited_error_codes, expand_from, gimple_phi_arg_def(def_stmt, i), error_code); |
15064 |
++ } |
15065 |
++ return error_code; |
15066 |
++ } |
15067 |
++ default: |
15068 |
++ debug_gimple_stmt(def_stmt); |
15069 |
++ error("%s: unknown gimple code", __func__); |
15070 |
++ gcc_unreachable(); |
15071 |
++ } |
15072 |
+} |
15073 |
+ |
15074 |
-+static bool skip_cast(tree dst_type, const_tree rhs, bool force) |
15075 |
++static bool handle_error_codes(interesting_stmts_t expand_from) |
15076 |
+{ |
15077 |
-+ const_gimple def_stmt = get_def_stmt(rhs); |
15078 |
++ bool error_code; |
15079 |
++ gimple_set *visited_error_codes; |
15080 |
+ |
15081 |
-+ if (force) |
15082 |
++ // expand the data flow from a return stmt |
15083 |
++ if (expand_from->next_node->num != 0 || strcmp(expand_from->next_node->context, "fndecl")) |
15084 |
+ return false; |
15085 |
+ |
15086 |
-+ if (is_gimple_constant(rhs)) |
15087 |
-+ return false; |
15088 |
++ visited_error_codes = pointer_set_create(); |
15089 |
++ error_code = search_error_codes(visited_error_codes, expand_from, expand_from->orig_node, false); |
15090 |
++ pointer_set_destroy(visited_error_codes); |
15091 |
+ |
15092 |
-+ if (!def_stmt || gimple_code(def_stmt) == GIMPLE_NOP) |
15093 |
-+ return false; |
15094 |
++ return error_code; |
15095 |
++} |
15096 |
+ |
15097 |
-+ if (!types_compatible_p(dst_type, TREE_TYPE(rhs))) |
15098 |
-+ return false; |
15099 |
++static void handle_interesting_stmt(struct visited *visited, interesting_stmts_t head) |
15100 |
++{ |
15101 |
++ interesting_stmts_t cur; |
15102 |
+ |
15103 |
-+ // DI type can be on 32 bit (from create_assign) but overflow type stays DI |
15104 |
-+ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode)) |
15105 |
-+ return false; |
15106 |
++ for (cur = head; cur; cur = cur->next) { |
15107 |
++ tree new_node; |
15108 |
++ gimple orig_def_stmt; |
15109 |
+ |
15110 |
-+ return true; |
15111 |
++ cur->visited = visited; |
15112 |
++ if (handle_error_codes(cur)) |
15113 |
++ continue; |
15114 |
++ |
15115 |
++ new_node = expand(cur, cur->orig_node); |
15116 |
++ if (new_node == NULL_TREE) |
15117 |
++ continue; |
15118 |
++ |
15119 |
++ orig_def_stmt = get_def_stmt(cur->orig_node); |
15120 |
++ if (pointer_set_contains(visited->no_cast_check, orig_def_stmt)) |
15121 |
++ continue; |
15122 |
++ change_orig_node(visited, cur->first_stmt, cur->orig_node, new_node, cur->num); |
15123 |
++ check_size_overflow(cur, cur->first_stmt, TREE_TYPE(new_node), new_node, cur->orig_node, BEFORE_STMT); |
15124 |
++ } |
15125 |
+} |
15126 |
+ |
15127 |
-+tree cast_a_tree(tree type, tree var) |
15128 |
++static next_interesting_function_t get_interesting_function_next_node(tree decl, unsigned int num) |
15129 |
+{ |
15130 |
-+ gcc_assert(type != NULL_TREE); |
15131 |
-+ gcc_assert(var != NULL_TREE); |
15132 |
-+ gcc_assert(fold_convertible_p(type, var)); |
15133 |
++ next_interesting_function_t next_node; |
15134 |
++ const struct size_overflow_hash *so_hash; |
15135 |
++ struct fn_raw_data raw_data; |
15136 |
+ |
15137 |
-+ return fold_convert(type, var); |
15138 |
++ raw_data.decl = decl; |
15139 |
++ raw_data.decl_str = DECL_NAME_POINTER(decl); |
15140 |
++ raw_data.num = num; |
15141 |
++ raw_data.marked = YES_SO_MARK; |
15142 |
++ |
15143 |
++ next_node = get_global_next_interesting_function_entry_with_hash(&raw_data); |
15144 |
++ if (next_node && next_node->marked != NO_SO_MARK) |
15145 |
++ return next_node; |
15146 |
++ |
15147 |
++ so_hash = get_size_overflow_hash_entry_tree(raw_data.decl, raw_data.num, SIZE_OVERFLOW); |
15148 |
++ if (so_hash) |
15149 |
++ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
15150 |
++ return NULL; |
15151 |
+} |
15152 |
+ |
15153 |
-+gimple build_cast_stmt(struct visited *visited, tree dst_type, tree rhs, tree lhs, gimple_stmt_iterator *gsi, bool before, bool force) |
15154 |
++tree handle_fnptr_assign(const_gimple stmt) |
15155 |
+{ |
15156 |
-+ gassign *assign; |
15157 |
-+ gimple def_stmt; |
15158 |
++ tree field, rhs, op0; |
15159 |
++ const_tree op0_type; |
15160 |
++ enum tree_code rhs_code; |
15161 |
+ |
15162 |
-+ gcc_assert(dst_type != NULL_TREE && rhs != NULL_TREE); |
15163 |
-+ gcc_assert(!is_gimple_constant(rhs)); |
15164 |
-+ if (gsi_end_p(*gsi) && before == AFTER_STMT) |
15165 |
-+ gcc_unreachable(); |
15166 |
++ // TODO skip binary assignments for now (fs/sync.c _591 = __bpf_call_base + _590;) |
15167 |
++ if (gimple_num_ops(stmt) != 2) |
15168 |
++ return NULL_TREE; |
15169 |
+ |
15170 |
-+ def_stmt = get_def_stmt(rhs); |
15171 |
-+ if (def_stmt && gimple_code(def_stmt) != GIMPLE_NOP && skip_cast(dst_type, rhs, force) && pointer_set_contains(visited->my_stmts, def_stmt)) |
15172 |
-+ return def_stmt; |
15173 |
++ gcc_assert(gimple_num_ops(stmt) == 2); |
15174 |
++ // TODO skip asm_stmt for now |
15175 |
++ if (gimple_code(stmt) == GIMPLE_ASM) |
15176 |
++ return NULL_TREE; |
15177 |
++ rhs = gimple_assign_rhs1(stmt); |
15178 |
++ if (is_gimple_constant(rhs)) |
15179 |
++ return NULL_TREE; |
15180 |
+ |
15181 |
-+ if (lhs == CREATE_NEW_VAR) |
15182 |
-+ lhs = create_new_var(dst_type); |
15183 |
++ rhs_code = TREE_CODE(rhs); |
15184 |
++ if (rhs_code == VAR_DECL) |
15185 |
++ return rhs; |
15186 |
+ |
15187 |
-+ assign = gimple_build_assign(lhs, cast_a_tree(dst_type, rhs)); |
15188 |
++ switch (rhs_code) { |
15189 |
++ case ADDR_EXPR: |
15190 |
++ op0 = TREE_OPERAND(rhs, 0); |
15191 |
++ gcc_assert(TREE_CODE(op0) == FUNCTION_DECL); |
15192 |
++ return op0; |
15193 |
++ case COMPONENT_REF: |
15194 |
++ break; |
15195 |
++ // TODO skip array_ref for now |
15196 |
++ case ARRAY_REF: |
15197 |
++ return NULL_TREE; |
15198 |
++ // TODO skip ssa_name because it can lead to parm_decl |
15199 |
++ case SSA_NAME: |
15200 |
++ return NULL_TREE; |
15201 |
++ // TODO skip mem_ref and indirect_ref for now |
15202 |
++#if BUILDING_GCC_VERSION >= 4006 |
15203 |
++ case MEM_REF: |
15204 |
++#endif |
15205 |
++ case INDIRECT_REF: |
15206 |
++ return NULL_TREE; |
15207 |
++ default: |
15208 |
++ debug_tree(rhs); |
15209 |
++ debug_gimple_stmt((gimple)stmt); |
15210 |
++ gcc_unreachable(); |
15211 |
++ } |
15212 |
+ |
15213 |
-+ if (!gsi_end_p(*gsi)) { |
15214 |
-+ location_t loc = gimple_location(gsi_stmt(*gsi)); |
15215 |
-+ gimple_set_location(assign, loc); |
15216 |
++ op0 = TREE_OPERAND(rhs, 0); |
15217 |
++ switch (TREE_CODE(op0)) { |
15218 |
++ // TODO skip array_ref and parm_decl for now |
15219 |
++ case ARRAY_REF: |
15220 |
++ case PARM_DECL: |
15221 |
++ return NULL_TREE; |
15222 |
++ case COMPONENT_REF: |
15223 |
++#if BUILDING_GCC_VERSION >= 4006 |
15224 |
++ case MEM_REF: |
15225 |
++#endif |
15226 |
++ case INDIRECT_REF: |
15227 |
++ case VAR_DECL: |
15228 |
++ break; |
15229 |
++ default: |
15230 |
++ debug_tree(op0); |
15231 |
++ gcc_unreachable(); |
15232 |
+ } |
15233 |
+ |
15234 |
-+ gimple_assign_set_lhs(assign, make_ssa_name(lhs, assign)); |
15235 |
++ op0_type = TREE_TYPE(op0); |
15236 |
++ // TODO skip unions for now |
15237 |
++ if (TREE_CODE(op0_type) == UNION_TYPE) |
15238 |
++ return NULL_TREE; |
15239 |
++ gcc_assert(TREE_CODE(op0_type) == RECORD_TYPE); |
15240 |
+ |
15241 |
-+ if (before) |
15242 |
-+ gsi_insert_before(gsi, assign, GSI_NEW_STMT); |
15243 |
-+ else |
15244 |
-+ gsi_insert_after(gsi, assign, GSI_NEW_STMT); |
15245 |
-+ update_stmt(assign); |
15246 |
-+ return assign; |
15247 |
++ field = TREE_OPERAND(rhs, 1); |
15248 |
++ gcc_assert(TREE_CODE(field) == FIELD_DECL); |
15249 |
++ return field; |
15250 |
+} |
15251 |
+ |
15252 |
-+bool is_size_overflow_type(const_tree var) |
15253 |
++static tree get_fn_or_fnptr_decl(const gcall *call_stmt) |
15254 |
+{ |
15255 |
-+ const char *name; |
15256 |
-+ const_tree type_name, type; |
15257 |
-+ |
15258 |
-+ if (var == NULL_TREE) |
15259 |
-+ return false; |
15260 |
++ const_tree fnptr; |
15261 |
++ const_gimple def_stmt; |
15262 |
++ tree decl = gimple_call_fndecl(call_stmt); |
15263 |
+ |
15264 |
-+ type = TREE_TYPE(var); |
15265 |
-+ type_name = TYPE_NAME(type); |
15266 |
-+ if (type_name == NULL_TREE) |
15267 |
-+ return false; |
15268 |
++ if (decl != NULL_TREE) |
15269 |
++ return decl; |
15270 |
+ |
15271 |
-+ if (DECL_P(type_name)) |
15272 |
-+ name = DECL_NAME_POINTER(type_name); |
15273 |
-+ else |
15274 |
-+ name = IDENTIFIER_POINTER(type_name); |
15275 |
++ fnptr = gimple_call_fn(call_stmt); |
15276 |
++ if (fnptr == NULL_TREE) |
15277 |
++ return NULL_TREE; |
15278 |
+ |
15279 |
-+ if (!strncmp(name, "size_overflow_type", 18)) |
15280 |
-+ return true; |
15281 |
-+ return false; |
15282 |
++ // !!! assertot kell irni 0-ra, mert csak az lehet ott |
15283 |
++ if (is_gimple_constant(fnptr)) |
15284 |
++ return NULL_TREE; |
15285 |
++ def_stmt = get_fnptr_def_stmt(fnptr); |
15286 |
++ return handle_fnptr_assign(def_stmt); |
15287 |
+} |
15288 |
+ |
15289 |
-+// Determine if a cloned function has all the original arguments |
15290 |
-+static bool unchanged_arglist(struct cgraph_node *new_node, struct cgraph_node *old_node) |
15291 |
++// Start stmt duplication on marked function parameters |
15292 |
++static interesting_stmts_t search_interesting_calls(interesting_stmts_t head, gcall *call_stmt) |
15293 |
+{ |
15294 |
-+ const_tree new_decl_list, old_decl_list; |
15295 |
++ tree decl; |
15296 |
++ unsigned int i, len; |
15297 |
+ |
15298 |
-+ if (new_node->clone_of && new_node->clone.tree_map) |
15299 |
-+ return !new_node->clone.args_to_skip; |
15300 |
++ len = gimple_call_num_args(call_stmt); |
15301 |
++ if (len == 0) |
15302 |
++ return head; |
15303 |
+ |
15304 |
-+ new_decl_list = DECL_ARGUMENTS(NODE_DECL(new_node)); |
15305 |
-+ old_decl_list = DECL_ARGUMENTS(NODE_DECL(old_node)); |
15306 |
-+ if (new_decl_list != NULL_TREE && old_decl_list != NULL_TREE) |
15307 |
-+ gcc_assert(list_length(new_decl_list) == list_length(old_decl_list)); |
15308 |
++ decl = get_fn_or_fnptr_decl(call_stmt); |
15309 |
++ if (decl == NULL_TREE) |
15310 |
++ return head; |
15311 |
+ |
15312 |
-+ return true; |
15313 |
++ for (i = 0; i < len; i++) { |
15314 |
++ tree arg; |
15315 |
++ next_interesting_function_t next_node; |
15316 |
++ |
15317 |
++ arg = gimple_call_arg(call_stmt, i); |
15318 |
++ if (is_gimple_constant(arg)) |
15319 |
++ continue; |
15320 |
++ if (skip_types(arg)) |
15321 |
++ continue; |
15322 |
++ next_node = get_interesting_function_next_node(decl, i + 1); |
15323 |
++ if (next_node) |
15324 |
++ head = search_interesting_stmt(head, next_node, call_stmt, arg, i + 1); |
15325 |
++ } |
15326 |
++ |
15327 |
++ return head; |
15328 |
+} |
15329 |
+ |
15330 |
-+unsigned int get_correct_argnum_fndecl(const_tree fndecl, const_tree correct_argnum_of_fndecl, unsigned int num) |
15331 |
++// Find assignements to structure fields and vardecls |
15332 |
++static interesting_stmts_t search_interesting_structs_vardecls(interesting_stmts_t head, gassign *assign) |
15333 |
+{ |
15334 |
-+ unsigned int new_num; |
15335 |
-+ const_tree fndecl_arg; |
15336 |
-+ tree fndecl_arglist = DECL_ARGUMENTS(fndecl); |
15337 |
-+ const_tree arg, target_fndecl_arglist; |
15338 |
-+ |
15339 |
-+ if (num == 0) |
15340 |
-+ return num; |
15341 |
++ enum intentional_mark mark; |
15342 |
++ next_interesting_function_t next_node; |
15343 |
++ tree rhs1, rhs2, lhs, decl; |
15344 |
++#if BUILDING_GCC_VERSION >= 4006 |
15345 |
++ tree rhs3; |
15346 |
++#endif |
15347 |
+ |
15348 |
-+ if (fndecl == correct_argnum_of_fndecl && !DECL_ARTIFICIAL(fndecl)) |
15349 |
-+ return num; |
15350 |
-+ else if (fndecl == correct_argnum_of_fndecl && DECL_ARTIFICIAL(fndecl)) |
15351 |
-+ return CANNOT_FIND_ARG; |
15352 |
++ lhs = gimple_assign_lhs(assign); |
15353 |
+ |
15354 |
-+ target_fndecl_arglist = DECL_ARGUMENTS(correct_argnum_of_fndecl); |
15355 |
-+ if (fndecl_arglist == NULL_TREE || target_fndecl_arglist == NULL_TREE) |
15356 |
-+ return CANNOT_FIND_ARG; |
15357 |
++ if (VAR_P(lhs)) |
15358 |
++ decl = lhs; |
15359 |
++ else |
15360 |
++ decl = get_ref_field(lhs); |
15361 |
++ if (decl == NULL_TREE) |
15362 |
++ return head; |
15363 |
++ if (DECL_NAME(decl) == NULL_TREE) |
15364 |
++ return head; |
15365 |
+ |
15366 |
-+ fndecl_arg = chain_index(num - 1, fndecl_arglist); |
15367 |
-+ if (fndecl_arg == NULL_TREE) |
15368 |
-+ return CANNOT_FIND_ARG; |
15369 |
++ if (is_bitfield_unnamed_cast(decl, assign)) |
15370 |
++ return head; |
15371 |
+ |
15372 |
-+ for (arg = target_fndecl_arglist, new_num = 1; arg; arg = TREE_CHAIN(arg), new_num++) { |
15373 |
-+ if (arg == fndecl_arg || !strcmp(DECL_NAME_POINTER(arg), DECL_NAME_POINTER(fndecl_arg))) |
15374 |
-+ return new_num; |
15375 |
-+ } |
15376 |
++ next_node = get_interesting_function_next_node(decl, 0); |
15377 |
++ if (!next_node) |
15378 |
++ return head; |
15379 |
+ |
15380 |
-+ return CANNOT_FIND_ARG; |
15381 |
-+} |
15382 |
++ mark = get_intentional_attr_type(decl); |
15383 |
++ if (mark != MARK_NO) |
15384 |
++ return head; |
15385 |
+ |
15386 |
-+// Find the specified argument in the originally cloned function |
15387 |
-+static unsigned int clone_argnum_on_orig(struct cgraph_node *new_node, struct cgraph_node *old_node, unsigned int clone_argnum) |
15388 |
-+{ |
15389 |
-+ bitmap args_to_skip; |
15390 |
-+ unsigned int i, new_argnum = clone_argnum; |
15391 |
++ rhs1 = gimple_assign_rhs1(assign); |
15392 |
++ head = search_interesting_stmt(head, next_node, assign, rhs1, 0); |
15393 |
+ |
15394 |
-+ if (unchanged_arglist(new_node, old_node)) |
15395 |
-+ return clone_argnum; |
15396 |
++ rhs2 = gimple_assign_rhs2(assign); |
15397 |
++ if (rhs2) |
15398 |
++ head = search_interesting_stmt(head, next_node, assign, rhs2, 0); |
15399 |
+ |
15400 |
-+ gcc_assert(new_node->clone_of && new_node->clone.tree_map); |
15401 |
-+ args_to_skip = new_node->clone.args_to_skip; |
15402 |
-+ for (i = 0; i < clone_argnum; i++) { |
15403 |
-+ if (bitmap_bit_p(args_to_skip, i)) |
15404 |
-+ new_argnum++; |
15405 |
-+ } |
15406 |
-+ return new_argnum; |
15407 |
++#if BUILDING_GCC_VERSION >= 4006 |
15408 |
++ rhs3 = gimple_assign_rhs3(assign); |
15409 |
++ if (rhs3) |
15410 |
++ head = search_interesting_stmt(head, next_node, assign, rhs3, 0); |
15411 |
++#endif |
15412 |
++ return head; |
15413 |
+} |
15414 |
+ |
15415 |
-+// Find the specified argument in the clone |
15416 |
-+static unsigned int orig_argnum_on_clone(struct cgraph_node *new_node, struct cgraph_node *old_node, unsigned int orig_argnum) |
15417 |
++static next_interesting_function_t create_so_asm_next_interesting_function_node(const gasm *stmt) |
15418 |
+{ |
15419 |
-+ bitmap args_to_skip; |
15420 |
-+ unsigned int i, new_argnum = orig_argnum; |
15421 |
++ next_interesting_function_t next_node; |
15422 |
++ struct fn_raw_data raw_data; |
15423 |
+ |
15424 |
-+ if (unchanged_arglist(new_node, old_node)) |
15425 |
-+ return orig_argnum; |
15426 |
++ raw_data.decl = NULL_TREE; |
15427 |
++ raw_data.decl_str = gimple_asm_string(stmt); |
15428 |
++ raw_data.context = "attr"; |
15429 |
++ raw_data.hash = 0; |
15430 |
++ raw_data.num = 0; |
15431 |
++ raw_data.marked = ASM_STMT_SO_MARK; |
15432 |
+ |
15433 |
-+ gcc_assert(new_node->clone_of && new_node->clone.tree_map); |
15434 |
-+ args_to_skip = new_node->clone.args_to_skip; |
15435 |
-+ if (bitmap_bit_p(args_to_skip, orig_argnum - 1)) |
15436 |
-+ // XXX torolni kellene a nodeot |
15437 |
-+ return CANNOT_FIND_ARG; |
15438 |
++ next_node = get_global_next_interesting_function_entry(&raw_data); |
15439 |
++ if (next_node) |
15440 |
++ return next_node; |
15441 |
++ next_node = create_new_next_interesting_entry(&raw_data, NULL); |
15442 |
++ gcc_assert(next_node); |
15443 |
+ |
15444 |
-+ for (i = 0; i < orig_argnum; i++) { |
15445 |
-+ if (bitmap_bit_p(args_to_skip, i)) |
15446 |
-+ new_argnum--; |
15447 |
-+ } |
15448 |
-+ return new_argnum; |
15449 |
++ add_to_global_next_interesting_function(next_node); |
15450 |
++ return next_node; |
15451 |
+} |
15452 |
+ |
15453 |
-+// Associate the argument between a clone and a cloned function |
15454 |
-+static unsigned int get_correct_argnum_cnode(struct cgraph_node *node, struct cgraph_node *correct_argnum_of_node, unsigned int argnum) |
15455 |
++// Collect interesting stmts for duplication |
15456 |
++static void search_interesting_stmts(struct visited *visited) |
15457 |
+{ |
15458 |
-+ bool node_clone, correct_argnum_of_node_clone; |
15459 |
-+ const_tree correct_argnum_of_node_decl, node_decl; |
15460 |
++ basic_block bb; |
15461 |
++ next_interesting_function_t next_node_ret; |
15462 |
++ interesting_stmts_t head = NULL; |
15463 |
+ |
15464 |
-+ if (node == correct_argnum_of_node) |
15465 |
-+ return argnum; |
15466 |
-+ if (argnum == 0) |
15467 |
-+ return argnum; |
15468 |
++ next_node_ret = get_interesting_function_next_node(current_function_decl, 0); |
15469 |
+ |
15470 |
-+ correct_argnum_of_node_decl = NODE_DECL(correct_argnum_of_node); |
15471 |
-+ gcc_assert(correct_argnum_of_node_decl != NULL_TREE); |
15472 |
-+ gcc_assert(correct_argnum_of_node && !DECL_ARTIFICIAL(correct_argnum_of_node_decl)); |
15473 |
++ FOR_EACH_BB_FN(bb, cfun) { |
15474 |
++ gimple_stmt_iterator gsi; |
15475 |
+ |
15476 |
-+ if (node) { |
15477 |
-+ node_decl = NODE_DECL(node); |
15478 |
-+ gcc_assert(!DECL_ARTIFICIAL(node_decl)); |
15479 |
-+ node_clone = made_by_compiler(node_decl); |
15480 |
-+ } else { |
15481 |
-+ node_decl = NULL_TREE; |
15482 |
-+ node_clone = false; |
15483 |
-+ } |
15484 |
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
15485 |
++ gimple stmt = gsi_stmt(gsi); |
15486 |
+ |
15487 |
-+ if (correct_argnum_of_node_decl == node_decl) |
15488 |
-+ return argnum; |
15489 |
++ switch (gimple_code(stmt)) { |
15490 |
++ case GIMPLE_ASM: { |
15491 |
++ tree first_node; |
15492 |
++ next_interesting_function_t next_node; |
15493 |
++ const gasm *asm_stmt = as_a_gasm(stmt); |
15494 |
+ |
15495 |
-+ correct_argnum_of_node_clone = made_by_compiler(correct_argnum_of_node_decl); |
15496 |
-+ // the original decl is lost if both nodes are clones |
15497 |
-+ if (node_clone && correct_argnum_of_node_clone) { |
15498 |
-+ gcc_assert(unchanged_arglist(node, correct_argnum_of_node)); |
15499 |
-+ return argnum; |
15500 |
++ if (!is_size_overflow_insert_check_asm(asm_stmt)) |
15501 |
++ continue; |
15502 |
++ next_node = create_so_asm_next_interesting_function_node(asm_stmt); |
15503 |
++ first_node = get_size_overflow_asm_input(asm_stmt); |
15504 |
++ head = search_interesting_stmt(head, next_node, stmt, first_node, 0); |
15505 |
++ break; |
15506 |
++ } |
15507 |
++ case GIMPLE_RETURN: |
15508 |
++ head = search_interesting_rets(head, next_node_ret, as_a_greturn(stmt)); |
15509 |
++ break; |
15510 |
++ case GIMPLE_CALL: |
15511 |
++ head = search_interesting_calls(head, as_a_gcall(stmt)); |
15512 |
++ break; |
15513 |
++ case GIMPLE_ASSIGN: |
15514 |
++ /* !!! TODO LTO modeban nincs duplikalas a globalis valtozora, mert a tree mergek |
15515 |
++ * utan mar nem lehet megkulonboztetni attol a globalis valtozotol, aminek a scopeja csak a file |
15516 |
++ * igy a context nem vardecl lesz, hanem vardecl_filenev. De execute-ban kiirja, ha hianyzik a hash tablabol |
15517 |
++ * IPA-ban van duplikalas. |
15518 |
++ */ |
15519 |
++ head = search_interesting_structs_vardecls(head, as_a_gassign(stmt)); |
15520 |
++ break; |
15521 |
++ default: |
15522 |
++ break; |
15523 |
++ } |
15524 |
++ } |
15525 |
+ } |
15526 |
+ |
15527 |
-+ if (node_clone && !correct_argnum_of_node_clone) |
15528 |
-+ return clone_argnum_on_orig(correct_argnum_of_node, node, argnum); |
15529 |
-+ else if (!node_clone && correct_argnum_of_node_clone) |
15530 |
-+ return orig_argnum_on_clone(correct_argnum_of_node, node, argnum); |
15531 |
-+ |
15532 |
-+ if (node) |
15533 |
-+ debug_tree(NODE_DECL(node)); |
15534 |
-+ debug_tree(correct_argnum_of_node_decl); |
15535 |
-+ gcc_unreachable(); |
15536 |
++ handle_interesting_stmt(visited, head); |
15537 |
++ free_interesting_stmts(head); |
15538 |
+} |
15539 |
+ |
15540 |
-+unsigned int get_correct_argnum(const_tree decl, const_tree correct_argnum_of_decl, unsigned int argnum) |
15541 |
++static struct visited *create_visited(void) |
15542 |
+{ |
15543 |
-+ struct cgraph_node *node, *correct_argnum_of_node; |
15544 |
++ struct visited *new_node; |
15545 |
+ |
15546 |
-+ gcc_assert(decl != NULL_TREE); |
15547 |
-+ gcc_assert(correct_argnum_of_decl != NULL_TREE); |
15548 |
++ new_node = (struct visited *)xmalloc(sizeof(*new_node)); |
15549 |
++ new_node->stmts = pointer_set_create(); |
15550 |
++ new_node->my_stmts = pointer_set_create(); |
15551 |
++ new_node->skip_expr_casts = pointer_set_create(); |
15552 |
++ new_node->no_cast_check = pointer_set_create(); |
15553 |
++ return new_node; |
15554 |
++} |
15555 |
+ |
15556 |
-+ correct_argnum_of_node = get_cnode(correct_argnum_of_decl); |
15557 |
-+ if (!correct_argnum_of_node || DECL_ARTIFICIAL(decl) || DECL_ARTIFICIAL(correct_argnum_of_decl)) |
15558 |
-+ return get_correct_argnum_fndecl(decl, correct_argnum_of_decl, argnum); |
15559 |
++static void free_visited(struct visited *visited) |
15560 |
++{ |
15561 |
++ pointer_set_destroy(visited->stmts); |
15562 |
++ pointer_set_destroy(visited->my_stmts); |
15563 |
++ pointer_set_destroy(visited->skip_expr_casts); |
15564 |
++ pointer_set_destroy(visited->no_cast_check); |
15565 |
+ |
15566 |
-+ node = get_cnode(decl); |
15567 |
-+ return get_correct_argnum_cnode(node, correct_argnum_of_node, argnum); |
15568 |
++ free(visited); |
15569 |
+} |
15570 |
+ |
15571 |
-+// Find the original cloned function |
15572 |
-+tree get_orig_fndecl(const_tree clone_fndecl) |
15573 |
++// Remove the size_overflow asm stmt and create an assignment from the input and output of the asm |
15574 |
++static void replace_size_overflow_asm_with_assign(gasm *asm_stmt, tree lhs, tree rhs) |
15575 |
+{ |
15576 |
-+ struct cgraph_node *node; |
15577 |
++ gassign *assign; |
15578 |
++ gimple_stmt_iterator gsi; |
15579 |
+ |
15580 |
-+ gcc_assert(TREE_CODE(clone_fndecl) == FUNCTION_DECL); |
15581 |
++ // already removed |
15582 |
++ if (gimple_bb(asm_stmt) == NULL) |
15583 |
++ return; |
15584 |
++ gsi = gsi_for_stmt(asm_stmt); |
15585 |
+ |
15586 |
-+ if (DECL_ABSTRACT_ORIGIN(clone_fndecl)) |
15587 |
-+ return CONST_CAST_TREE(DECL_ABSTRACT_ORIGIN(clone_fndecl)); |
15588 |
-+ node = get_cnode(clone_fndecl); |
15589 |
-+ if (!node) |
15590 |
-+ return CONST_CAST_TREE(clone_fndecl); |
15591 |
++ assign = gimple_build_assign(lhs, rhs); |
15592 |
++ gsi_insert_before(&gsi, assign, GSI_SAME_STMT); |
15593 |
++ SSA_NAME_DEF_STMT(lhs) = assign; |
15594 |
+ |
15595 |
-+ while (node->clone_of) |
15596 |
-+ node = node->clone_of; |
15597 |
-+ if (!made_by_compiler(NODE_DECL(node))) |
15598 |
-+ return NODE_DECL(node); |
15599 |
-+ // Return the cloned decl because it is needed for the transform callback |
15600 |
-+ return CONST_CAST_TREE(clone_fndecl); |
15601 |
++ gsi_remove(&gsi, true); |
15602 |
+} |
15603 |
+ |
15604 |
-+static tree get_interesting_fndecl_from_stmt(const gcall *stmt) |
15605 |
++// Replace our asm stmts with assignments (they are no longer needed and may interfere with later optimizations) |
15606 |
++static void remove_size_overflow_asm(gimple stmt) |
15607 |
+{ |
15608 |
-+ if (gimple_call_num_args(stmt) == 0) |
15609 |
-+ return NULL_TREE; |
15610 |
-+ return gimple_call_fndecl(stmt); |
15611 |
-+} |
15612 |
++ gimple_stmt_iterator gsi; |
15613 |
++ tree input, output; |
15614 |
+ |
15615 |
-+tree get_interesting_orig_fndecl_from_stmt(const gcall *stmt) |
15616 |
-+{ |
15617 |
-+ tree fndecl; |
15618 |
++ if (!is_size_overflow_asm(stmt)) |
15619 |
++ return; |
15620 |
+ |
15621 |
-+ fndecl = get_interesting_fndecl_from_stmt(stmt); |
15622 |
-+ if (fndecl == NULL_TREE) |
15623 |
-+ return NULL_TREE; |
15624 |
-+ return get_orig_fndecl(fndecl); |
15625 |
-+} |
15626 |
++ if (gimple_asm_noutputs(as_a_gasm(stmt)) == 0) { |
15627 |
++ gsi = gsi_for_stmt(stmt); |
15628 |
+ |
15629 |
-+void set_dominance_info(void) |
15630 |
-+{ |
15631 |
-+ calculate_dominance_info(CDI_DOMINATORS); |
15632 |
-+ calculate_dominance_info(CDI_POST_DOMINATORS); |
15633 |
++ ipa_remove_stmt_references(cgraph_get_node(current_function_decl), stmt); |
15634 |
++ gsi_remove(&gsi, true); |
15635 |
++ return; |
15636 |
++ } |
15637 |
++ |
15638 |
++ input = gimple_asm_input_op(as_a_gasm(stmt), 0); |
15639 |
++ output = gimple_asm_output_op(as_a_gasm(stmt), 0); |
15640 |
++ replace_size_overflow_asm_with_assign(as_a_gasm(stmt), TREE_VALUE(output), TREE_VALUE(input)); |
15641 |
+} |
15642 |
+ |
15643 |
-+void unset_dominance_info(void) |
15644 |
++static void remove_all_size_overflow_asm(void) |
15645 |
+{ |
15646 |
-+ free_dominance_info(CDI_DOMINATORS); |
15647 |
-+ free_dominance_info(CDI_POST_DOMINATORS); |
15648 |
++ basic_block bb; |
15649 |
++ |
15650 |
++ FOR_EACH_BB_FN(bb, cfun) { |
15651 |
++ gimple_stmt_iterator si; |
15652 |
++ |
15653 |
++ for (si = gsi_start_bb(bb); !gsi_end_p(si); gsi_next(&si)) |
15654 |
++ remove_size_overflow_asm(gsi_stmt(si)); |
15655 |
++ } |
15656 |
+} |
15657 |
+ |
15658 |
-+void set_current_function_decl(tree fndecl) |
15659 |
++unsigned int size_overflow_function_transform(struct cgraph_node *node __unused) |
15660 |
+{ |
15661 |
-+ gcc_assert(fndecl != NULL_TREE); |
15662 |
++ struct visited *visited; |
15663 |
+ |
15664 |
-+ push_cfun(DECL_STRUCT_FUNCTION(fndecl)); |
15665 |
-+#if BUILDING_GCC_VERSION <= 4007 |
15666 |
-+ current_function_decl = fndecl; |
15667 |
++#if BUILDING_GCC_VERSION >= 4008 |
15668 |
++ if (dump_file) { |
15669 |
++ fprintf(dump_file, "BEFORE TRANSFORM -------------------------\n"); |
15670 |
++ size_overflow_dump_function(dump_file, node); |
15671 |
++ } |
15672 |
+#endif |
15673 |
++ visited = create_visited(); |
15674 |
+ set_dominance_info(); |
15675 |
-+} |
15676 |
+ |
15677 |
-+void unset_current_function_decl(void) |
15678 |
-+{ |
15679 |
-+ unset_dominance_info(); |
15680 |
-+#if BUILDING_GCC_VERSION <= 4007 |
15681 |
-+ current_function_decl = NULL_TREE; |
15682 |
-+#endif |
15683 |
-+ pop_cfun(); |
15684 |
-+} |
15685 |
++ search_interesting_stmts(visited); |
15686 |
+ |
15687 |
-+bool is_valid_cgraph_node(struct cgraph_node *node) |
15688 |
-+{ |
15689 |
-+ if (cgraph_function_body_availability(node) == AVAIL_NOT_AVAILABLE) |
15690 |
-+ return false; |
15691 |
-+ if (node->thunk.thunk_p || node->alias) |
15692 |
-+ return false; |
15693 |
-+ return true; |
15694 |
-+} |
15695 |
++ remove_all_size_overflow_asm(); |
15696 |
+ |
15697 |
-+tree get_lhs(const_gimple stmt) |
15698 |
-+{ |
15699 |
-+ switch (gimple_code(stmt)) { |
15700 |
-+ case GIMPLE_ASSIGN: |
15701 |
-+ case GIMPLE_CALL: |
15702 |
-+ return gimple_get_lhs(stmt); |
15703 |
-+ case GIMPLE_PHI: |
15704 |
-+ return gimple_phi_result(stmt); |
15705 |
-+ default: |
15706 |
-+ debug_gimple_stmt((gimple)stmt); |
15707 |
-+ gcc_unreachable(); |
15708 |
++ unset_dominance_info(); |
15709 |
++ free_visited(visited); |
15710 |
++ |
15711 |
++#if BUILDING_GCC_VERSION >= 4008 |
15712 |
++ if (dump_file) { |
15713 |
++ fprintf(dump_file, "AFTER TRANSFORM -------------------------\n"); |
15714 |
++ size_overflow_dump_function(dump_file, node); |
15715 |
+ } |
15716 |
++#endif |
15717 |
++ return TODO_dump_func | TODO_verify_stmts | TODO_remove_unused_locals | TODO_update_ssa_no_phi | TODO_ggc_collect | TODO_verify_flow; |
15718 |
+} |
15719 |
-+ |
15720 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin/size_overflow_plugin.c |
15721 |
+diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_transform_core.c b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_transform_core.c |
15722 |
new file mode 100644 |
15723 |
-index 0000000..3f8f032 |
15724 |
+index 0000000..062204a |
15725 |
--- /dev/null |
15726 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_plugin.c |
15727 |
-@@ -0,0 +1,290 @@ |
15728 |
++++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_transform_core.c |
15729 |
+@@ -0,0 +1,1025 @@ |
15730 |
+/* |
15731 |
+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
15732 |
+ * Licensed under the GPL v2, or (at your option) v3 |
15733 |
@@ -209132,3014 +207823,5055 @@ index 0000000..3f8f032 |
15734 |
+ |
15735 |
+#include "size_overflow.h" |
15736 |
+ |
15737 |
-+int plugin_is_GPL_compatible; |
15738 |
++#define MIN_CHECK true |
15739 |
++#define MAX_CHECK false |
15740 |
+ |
15741 |
-+tree report_size_overflow_decl; |
15742 |
++unsigned int call_count = 0; |
15743 |
+ |
15744 |
-+tree size_overflow_type_HI; |
15745 |
-+tree size_overflow_type_SI; |
15746 |
-+tree size_overflow_type_DI; |
15747 |
-+tree size_overflow_type_TI; |
15748 |
++tree get_size_overflow_type(struct visited *visited, const_gimple stmt, const_tree node) |
15749 |
++{ |
15750 |
++ const_tree type; |
15751 |
++ tree new_type; |
15752 |
+ |
15753 |
-+static struct plugin_info size_overflow_plugin_info = { |
15754 |
-+ .version = "20160521", |
15755 |
-+ .help = "no-size-overflow\tturn off size overflow checking\n", |
15756 |
-+}; |
15757 |
++ gcc_assert(node != NULL_TREE); |
15758 |
+ |
15759 |
-+static tree handle_size_overflow_attribute(tree *node, tree __unused name, tree args, int __unused flags, bool *no_add_attrs) |
15760 |
-+{ |
15761 |
-+ unsigned int arg_count; |
15762 |
-+ enum tree_code code = TREE_CODE(*node); |
15763 |
++ type = TREE_TYPE(node); |
15764 |
+ |
15765 |
-+ switch (code) { |
15766 |
-+ case FUNCTION_DECL: |
15767 |
-+ arg_count = type_num_arguments(TREE_TYPE(*node)); |
15768 |
++ if (pointer_set_contains(visited->my_stmts, stmt)) |
15769 |
++ return TREE_TYPE(node); |
15770 |
++ |
15771 |
++ switch (TYPE_MODE(type)) { |
15772 |
++ case QImode: |
15773 |
++ case HImode: |
15774 |
++ new_type = size_overflow_type_SI; |
15775 |
+ break; |
15776 |
-+ case FUNCTION_TYPE: |
15777 |
-+ case METHOD_TYPE: |
15778 |
-+ arg_count = type_num_arguments(*node); |
15779 |
++ case SImode: |
15780 |
++ new_type = size_overflow_type_DI; |
15781 |
++ break; |
15782 |
++ case DImode: |
15783 |
++ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode)) |
15784 |
++ new_type = TYPE_UNSIGNED(type) ? unsigned_intDI_type_node : intDI_type_node; |
15785 |
++ else |
15786 |
++ new_type = size_overflow_type_TI; |
15787 |
++ break; |
15788 |
++ case TImode: |
15789 |
++ gcc_assert(!TYPE_UNSIGNED(type)); |
15790 |
++ new_type = size_overflow_type_TI; |
15791 |
+ break; |
15792 |
+ default: |
15793 |
-+ *no_add_attrs = true; |
15794 |
-+ debug_tree(*node); |
15795 |
-+ error("%s: %qE attribute only applies to functions", __func__, name); |
15796 |
-+ return NULL_TREE; |
15797 |
++ debug_tree(node); |
15798 |
++ error("%s: unsupported gcc configuration (%qE).", __func__, current_function_decl); |
15799 |
++ gcc_unreachable(); |
15800 |
+ } |
15801 |
+ |
15802 |
-+ for (; args; args = TREE_CHAIN(args)) { |
15803 |
-+ int cur_val; |
15804 |
-+ tree position = TREE_VALUE(args); |
15805 |
++ if (TYPE_QUALS(type) != 0) |
15806 |
++ return build_qualified_type(new_type, TYPE_QUALS(type)); |
15807 |
++ return new_type; |
15808 |
++} |
15809 |
+ |
15810 |
-+ if (TREE_CODE(position) != INTEGER_CST) { |
15811 |
-+ error("%s: parameter isn't an integer", __func__); |
15812 |
-+ debug_tree(args); |
15813 |
-+ *no_add_attrs = true; |
15814 |
-+ return NULL_TREE; |
15815 |
-+ } |
15816 |
++tree cast_to_new_size_overflow_type(struct visited *visited, gimple stmt, tree rhs, tree size_overflow_type, bool before) |
15817 |
++{ |
15818 |
++ gimple_stmt_iterator gsi; |
15819 |
++ gimple new_stmt; |
15820 |
+ |
15821 |
-+ cur_val = tree_to_shwi(position); |
15822 |
-+ if (cur_val < 0 || arg_count < (unsigned int)cur_val) { |
15823 |
-+ error("%s: parameter %d is outside range.", __func__, cur_val); |
15824 |
-+ *no_add_attrs = true; |
15825 |
-+ return NULL_TREE; |
15826 |
-+ } |
15827 |
-+ } |
15828 |
-+ return NULL_TREE; |
15829 |
++ if (rhs == NULL_TREE) |
15830 |
++ return NULL_TREE; |
15831 |
++ |
15832 |
++ gsi = gsi_for_stmt(stmt); |
15833 |
++ new_stmt = build_cast_stmt(visited, size_overflow_type, rhs, CREATE_NEW_VAR, &gsi, before, false); |
15834 |
++ if (gimple_assign_cast_p(new_stmt)) |
15835 |
++ gimple_assign_set_rhs_code(new_stmt, CONVERT_EXPR); |
15836 |
++ pointer_set_insert(visited->my_stmts, new_stmt); |
15837 |
++ |
15838 |
++ return get_lhs(new_stmt); |
15839 |
+} |
15840 |
+ |
15841 |
-+static tree handle_intentional_overflow_attribute(tree *node, tree __unused name, tree args, int __unused flags, bool *no_add_attrs) |
15842 |
++tree create_assign(struct visited *visited, gimple oldstmt, tree rhs1, bool before) |
15843 |
+{ |
15844 |
-+ unsigned int arg_count; |
15845 |
-+ HOST_WIDE_INT s_first_arg; |
15846 |
-+ enum tree_code code = TREE_CODE(*node); |
15847 |
++ tree lhs, dst_type; |
15848 |
++ gimple_stmt_iterator gsi; |
15849 |
+ |
15850 |
-+ switch (code) { |
15851 |
-+ case FUNCTION_DECL: |
15852 |
-+ arg_count = type_num_arguments(TREE_TYPE(*node)); |
15853 |
++ if (rhs1 == NULL_TREE) { |
15854 |
++ debug_gimple_stmt(oldstmt); |
15855 |
++ error("%s: rhs1 is NULL_TREE", __func__); |
15856 |
++ gcc_unreachable(); |
15857 |
++ } |
15858 |
++ |
15859 |
++ switch (gimple_code(oldstmt)) { |
15860 |
++ case GIMPLE_ASM: |
15861 |
++ lhs = rhs1; |
15862 |
+ break; |
15863 |
-+ case FUNCTION_TYPE: |
15864 |
-+ case METHOD_TYPE: |
15865 |
-+ arg_count = type_num_arguments(*node); |
15866 |
++ case GIMPLE_CALL: |
15867 |
++ case GIMPLE_ASSIGN: |
15868 |
++ lhs = gimple_get_lhs(oldstmt); |
15869 |
+ break; |
15870 |
-+ case VAR_DECL: |
15871 |
-+ case FIELD_DECL: |
15872 |
-+ return NULL_TREE; |
15873 |
+ default: |
15874 |
-+ *no_add_attrs = true; |
15875 |
-+ debug_tree(*node); |
15876 |
-+ error("%qE attribute only applies to functions, fields or vars", name); |
15877 |
-+ return NULL_TREE; |
15878 |
++ debug_gimple_stmt(oldstmt); |
15879 |
++ gcc_unreachable(); |
15880 |
+ } |
15881 |
+ |
15882 |
-+ s_first_arg = tree_to_shwi(TREE_VALUE(args)); |
15883 |
-+ if (s_first_arg == -1) |
15884 |
-+ return NULL_TREE; |
15885 |
-+ if (s_first_arg < -1) |
15886 |
-+ error("%s: parameter %d is outside range.", __func__, (int)s_first_arg); |
15887 |
-+ |
15888 |
-+ for (; args; args = TREE_CHAIN(args)) { |
15889 |
-+ unsigned int cur_val; |
15890 |
-+ |
15891 |
-+ if (TREE_CODE(TREE_VALUE(args)) != INTEGER_CST) { |
15892 |
-+ error("%s: parameter isn't an integer", __func__); |
15893 |
-+ debug_tree(args); |
15894 |
-+ *no_add_attrs = true; |
15895 |
-+ return NULL_TREE; |
15896 |
-+ } |
15897 |
++ gsi = gsi_for_stmt(oldstmt); |
15898 |
++ pointer_set_insert(visited->stmts, oldstmt); |
15899 |
++ if (lookup_stmt_eh_lp(oldstmt) != 0) { |
15900 |
++ basic_block next_bb, cur_bb; |
15901 |
++ const_edge e; |
15902 |
+ |
15903 |
-+ cur_val = (unsigned int)tree_to_uhwi(TREE_VALUE(args)); |
15904 |
-+ if (cur_val > arg_count ) { |
15905 |
-+ error("%s: parameter %u is outside range. (arg_count: %u)", __func__, cur_val, arg_count); |
15906 |
-+ *no_add_attrs = true; |
15907 |
-+ return NULL_TREE; |
15908 |
-+ } |
15909 |
-+ } |
15910 |
-+ return NULL_TREE; |
15911 |
-+} |
15912 |
++ gcc_assert(before == false); |
15913 |
++ gcc_assert(stmt_can_throw_internal(oldstmt)); |
15914 |
++ gcc_assert(gimple_code(oldstmt) == GIMPLE_CALL); |
15915 |
++ gcc_assert(!gsi_end_p(gsi)); |
15916 |
+ |
15917 |
-+static struct attribute_spec size_overflow_attr = { |
15918 |
-+ .name = "size_overflow", |
15919 |
-+ .min_length = 1, |
15920 |
-+ .max_length = -1, |
15921 |
-+ .decl_required = true, |
15922 |
-+ .type_required = false, |
15923 |
-+ .function_type_required = false, |
15924 |
-+ .handler = handle_size_overflow_attribute, |
15925 |
-+#if BUILDING_GCC_VERSION >= 4007 |
15926 |
-+ .affects_type_identity = false |
15927 |
-+#endif |
15928 |
-+}; |
15929 |
++ cur_bb = gimple_bb(oldstmt); |
15930 |
++ next_bb = cur_bb->next_bb; |
15931 |
++ e = find_edge(cur_bb, next_bb); |
15932 |
++ gcc_assert(e != NULL); |
15933 |
++ gcc_assert(e->flags & EDGE_FALLTHRU); |
15934 |
+ |
15935 |
-+static struct attribute_spec intentional_overflow_attr = { |
15936 |
-+ .name = "intentional_overflow", |
15937 |
-+ .min_length = 1, |
15938 |
-+ .max_length = -1, |
15939 |
-+ .decl_required = true, |
15940 |
-+ .type_required = false, |
15941 |
-+ .function_type_required = false, |
15942 |
-+ .handler = handle_intentional_overflow_attribute, |
15943 |
-+#if BUILDING_GCC_VERSION >= 4007 |
15944 |
-+ .affects_type_identity = false |
15945 |
-+#endif |
15946 |
-+}; |
15947 |
++ gsi = gsi_after_labels(next_bb); |
15948 |
++ gcc_assert(!gsi_end_p(gsi)); |
15949 |
+ |
15950 |
-+static void register_attributes(void __unused *event_data, void __unused *data) |
15951 |
-+{ |
15952 |
-+ register_attribute(&size_overflow_attr); |
15953 |
-+ register_attribute(&intentional_overflow_attr); |
15954 |
-+} |
15955 |
++ before = true; |
15956 |
++ oldstmt = gsi_stmt(gsi); |
15957 |
++ } |
15958 |
+ |
15959 |
-+static tree create_typedef(tree type, const char* ident) |
15960 |
-+{ |
15961 |
-+ tree new_type, decl; |
15962 |
++ if (is_gimple_constant(rhs1) && TREE_CODE_CLASS(gimple_assign_rhs_code(oldstmt)) == tcc_comparison) |
15963 |
++ dst_type = get_size_overflow_type(visited, oldstmt, rhs1); |
15964 |
++ else |
15965 |
++ dst_type = get_size_overflow_type(visited, oldstmt, lhs); |
15966 |
+ |
15967 |
-+ new_type = build_variant_type_copy(type); |
15968 |
-+ decl = build_decl(BUILTINS_LOCATION, TYPE_DECL, get_identifier(ident), new_type); |
15969 |
-+ DECL_ORIGINAL_TYPE(decl) = type; |
15970 |
-+ TYPE_NAME(new_type) = decl; |
15971 |
-+ return new_type; |
15972 |
++ if (is_gimple_constant(rhs1)) |
15973 |
++ return cast_a_tree(dst_type, rhs1); |
15974 |
++ return cast_to_new_size_overflow_type(visited, oldstmt, rhs1, dst_type, before); |
15975 |
+} |
15976 |
+ |
15977 |
-+// Create the noreturn report_size_overflow() function decl. |
15978 |
-+static void size_overflow_start_unit(void __unused *gcc_data, void __unused *user_data) |
15979 |
++tree dup_assign(struct visited *visited, gassign *oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) |
15980 |
+{ |
15981 |
-+ tree const_char_ptr_type_node; |
15982 |
-+ tree fntype; |
15983 |
-+ |
15984 |
-+ const_char_ptr_type_node = build_pointer_type(build_type_variant(char_type_node, 1, 0)); |
15985 |
++ gassign *stmt; |
15986 |
++ gimple_stmt_iterator gsi; |
15987 |
++ tree size_overflow_type, new_var, lhs = gimple_assign_lhs(oldstmt); |
15988 |
+ |
15989 |
-+ size_overflow_type_HI = create_typedef(intHI_type_node, "size_overflow_type_HI"); |
15990 |
-+ size_overflow_type_SI = create_typedef(intSI_type_node, "size_overflow_type_SI"); |
15991 |
-+ size_overflow_type_DI = create_typedef(intDI_type_node, "size_overflow_type_DI"); |
15992 |
-+ size_overflow_type_TI = create_typedef(intTI_type_node, "size_overflow_type_TI"); |
15993 |
++ if (pointer_set_contains(visited->my_stmts, oldstmt)) |
15994 |
++ return lhs; |
15995 |
+ |
15996 |
-+ // void report_size_overflow(const char *loc_file, unsigned int loc_line, const char *current_func, const char *ssa_var) |
15997 |
-+ fntype = build_function_type_list(void_type_node, |
15998 |
-+ const_char_ptr_type_node, |
15999 |
-+ unsigned_type_node, |
16000 |
-+ const_char_ptr_type_node, |
16001 |
-+ const_char_ptr_type_node, |
16002 |
-+ NULL_TREE); |
16003 |
-+ report_size_overflow_decl = build_fn_decl("report_size_overflow", fntype); |
16004 |
++ if (gimple_num_ops(oldstmt) != 4 && rhs1 == NULL_TREE) { |
16005 |
++ rhs1 = gimple_assign_rhs1(oldstmt); |
16006 |
++ rhs1 = create_assign(visited, oldstmt, rhs1, BEFORE_STMT); |
16007 |
++ } |
16008 |
++ if (gimple_num_ops(oldstmt) == 3 && rhs2 == NULL_TREE) { |
16009 |
++ rhs2 = gimple_assign_rhs2(oldstmt); |
16010 |
++ rhs2 = create_assign(visited, oldstmt, rhs2, BEFORE_STMT); |
16011 |
++ } |
16012 |
+ |
16013 |
-+ DECL_ASSEMBLER_NAME(report_size_overflow_decl); |
16014 |
-+ TREE_PUBLIC(report_size_overflow_decl) = 1; |
16015 |
-+ DECL_EXTERNAL(report_size_overflow_decl) = 1; |
16016 |
-+ DECL_ARTIFICIAL(report_size_overflow_decl) = 1; |
16017 |
-+// TREE_THIS_VOLATILE(report_size_overflow_decl) = 1; |
16018 |
-+// !!! |
16019 |
-+ DECL_PRESERVE_P(report_size_overflow_decl) = 1; |
16020 |
-+ DECL_UNINLINABLE(report_size_overflow_decl) = 1; |
16021 |
-+ TREE_USED(report_size_overflow_decl) = 1; |
16022 |
-+ TREE_NOTHROW(report_size_overflow_decl) = 1; |
16023 |
-+} |
16024 |
++ stmt = as_a_gassign(gimple_copy(oldstmt)); |
16025 |
++ gimple_set_location(stmt, gimple_location(oldstmt)); |
16026 |
++ pointer_set_insert(visited->my_stmts, stmt); |
16027 |
+ |
16028 |
-+static bool disable_ubsan_si_overflow_gate(void) |
16029 |
-+{ |
16030 |
-+#if BUILDING_GCC_VERSION >= 4009 |
16031 |
-+ flag_sanitize &= ~SANITIZE_SI_OVERFLOW; |
16032 |
-+#endif |
16033 |
-+ return true; |
16034 |
-+} |
16035 |
++ if (gimple_assign_rhs_code(oldstmt) == WIDEN_MULT_EXPR) |
16036 |
++ gimple_assign_set_rhs_code(stmt, MULT_EXPR); |
16037 |
+ |
16038 |
-+#define PASS_NAME disable_ubsan_si_overflow |
16039 |
++ size_overflow_type = get_size_overflow_type(visited, oldstmt, node); |
16040 |
+ |
16041 |
-+#define NO_EXECUTE |
16042 |
++ new_var = create_new_var(size_overflow_type); |
16043 |
++ new_var = make_ssa_name(new_var, stmt); |
16044 |
++ gimple_assign_set_lhs(stmt, new_var); |
16045 |
+ |
16046 |
-+#include "gcc-generate-gimple-pass.h" |
16047 |
++ if (rhs1 != NULL_TREE) |
16048 |
++ gimple_assign_set_rhs1(stmt, rhs1); |
16049 |
+ |
16050 |
-+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
16051 |
-+{ |
16052 |
-+ int i; |
16053 |
-+ const char * const plugin_name = plugin_info->base_name; |
16054 |
-+ const int argc = plugin_info->argc; |
16055 |
-+ const struct plugin_argument * const argv = plugin_info->argv; |
16056 |
-+ bool enable = true; |
16057 |
-+ struct register_pass_info insert_size_overflow_asm_pass_info; |
16058 |
-+ struct register_pass_info size_overflow_pass_info; |
16059 |
-+#if BUILDING_GCC_VERSION >= 4009 |
16060 |
-+ struct register_pass_info disable_ubsan_si_overflow_pass_info; |
16061 |
++ if (rhs2 != NULL_TREE) |
16062 |
++ gimple_assign_set_rhs2(stmt, rhs2); |
16063 |
++#if BUILDING_GCC_VERSION >= 4006 |
16064 |
++ if (rhs3 != NULL_TREE) |
16065 |
++ gimple_assign_set_rhs3(stmt, rhs3); |
16066 |
+#endif |
16067 |
++ gimple_set_vuse(stmt, gimple_vuse(oldstmt)); |
16068 |
++ gimple_set_vdef(stmt, gimple_vdef(oldstmt)); |
16069 |
+ |
16070 |
-+ static const struct ggc_root_tab gt_ggc_r_gt_size_overflow[] = { |
16071 |
-+ { |
16072 |
-+ .base = &report_size_overflow_decl, |
16073 |
-+ .nelt = 1, |
16074 |
-+ .stride = sizeof(report_size_overflow_decl), |
16075 |
-+ .cb = >_ggc_mx_tree_node, |
16076 |
-+ .pchw = >_pch_nx_tree_node |
16077 |
-+ }, |
16078 |
-+ LAST_GGC_ROOT_TAB |
16079 |
-+ }; |
16080 |
++ gsi = gsi_for_stmt(oldstmt); |
16081 |
++ gsi_insert_after(&gsi, stmt, GSI_SAME_STMT); |
16082 |
++ update_stmt(stmt); |
16083 |
++ pointer_set_insert(visited->stmts, oldstmt); |
16084 |
++ return gimple_assign_lhs(stmt); |
16085 |
++} |
16086 |
+ |
16087 |
-+ insert_size_overflow_asm_pass_info.pass = make_insert_size_overflow_asm_pass(); |
16088 |
-+ insert_size_overflow_asm_pass_info.reference_pass_name = "ssa"; |
16089 |
-+ insert_size_overflow_asm_pass_info.ref_pass_instance_number = 1; |
16090 |
-+ insert_size_overflow_asm_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
16091 |
++static tree cast_parm_decl(struct visited *visited, tree phi_ssa_name, tree arg, tree size_overflow_type, basic_block bb) |
16092 |
++{ |
16093 |
++ const_gimple assign; |
16094 |
++ gimple_stmt_iterator gsi; |
16095 |
++ basic_block first_bb; |
16096 |
+ |
16097 |
-+ size_overflow_pass_info.pass = make_size_overflow_pass(); |
16098 |
-+ size_overflow_pass_info.reference_pass_name = "inline"; |
16099 |
-+ size_overflow_pass_info.ref_pass_instance_number = 1; |
16100 |
-+ size_overflow_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
16101 |
++ gcc_assert(SSA_NAME_IS_DEFAULT_DEF(arg)); |
16102 |
+ |
16103 |
-+ if (!plugin_default_version_check(version, &gcc_version)) { |
16104 |
-+ error(G_("incompatible gcc/plugin versions")); |
16105 |
-+ return 1; |
16106 |
++ if (bb->index == 0) { |
16107 |
++ first_bb = split_block_after_labels(ENTRY_BLOCK_PTR_FOR_FN(cfun))->dest; |
16108 |
++ gcc_assert(dom_info_available_p(CDI_DOMINATORS)); |
16109 |
++ set_immediate_dominator(CDI_DOMINATORS, first_bb, ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
16110 |
++ bb = first_bb; |
16111 |
+ } |
16112 |
+ |
16113 |
-+ for (i = 0; i < argc; ++i) { |
16114 |
-+ if (!strcmp(argv[i].key, "no-size-overflow")) { |
16115 |
-+ enable = false; |
16116 |
-+ continue; |
16117 |
-+ } |
16118 |
-+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
16119 |
-+ } |
16120 |
++ gsi = gsi_after_labels(bb); |
16121 |
++ assign = build_cast_stmt(visited, size_overflow_type, arg, phi_ssa_name, &gsi, BEFORE_STMT, false); |
16122 |
++ pointer_set_insert(visited->my_stmts, assign); |
16123 |
++ return get_lhs(assign); |
16124 |
++} |
16125 |
+ |
16126 |
-+ register_callback(plugin_name, PLUGIN_INFO, NULL, &size_overflow_plugin_info); |
16127 |
-+ if (enable) { |
16128 |
-+#if BUILDING_GCC_VERSION >= 4009 |
16129 |
-+ if (flag_sanitize & SANITIZE_SI_OVERFLOW) { |
16130 |
-+ error(G_("ubsan SANITIZE_SI_OVERFLOW option is unsupported")); |
16131 |
-+ return 1; |
16132 |
-+ } |
16133 |
-+#endif |
16134 |
-+ register_callback(plugin_name, PLUGIN_START_UNIT, &size_overflow_start_unit, NULL); |
16135 |
-+ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_size_overflow); |
16136 |
-+#if BUILDING_GCC_VERSION >= 4009 |
16137 |
-+ flag_sanitize |= SANITIZE_SI_OVERFLOW; |
16138 |
-+ disable_ubsan_si_overflow_pass_info.pass = make_disable_ubsan_si_overflow_pass(); |
16139 |
-+ disable_ubsan_si_overflow_pass_info.reference_pass_name = "ubsan"; |
16140 |
-+ disable_ubsan_si_overflow_pass_info.ref_pass_instance_number = 1; |
16141 |
-+ disable_ubsan_si_overflow_pass_info.pos_op = PASS_POS_REPLACE; |
16142 |
++static tree use_phi_ssa_name(struct visited *visited, tree ssa_name_var, tree new_arg) |
16143 |
++{ |
16144 |
++ gimple_stmt_iterator gsi; |
16145 |
++ const_gimple assign; |
16146 |
++ gimple def_stmt = get_def_stmt(new_arg); |
16147 |
+ |
16148 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &disable_ubsan_si_overflow_pass_info); |
16149 |
-+#endif |
16150 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &insert_size_overflow_asm_pass_info); |
16151 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &size_overflow_pass_info); |
16152 |
++ if (gimple_code(def_stmt) == GIMPLE_PHI) { |
16153 |
++ gsi = gsi_after_labels(gimple_bb(def_stmt)); |
16154 |
++ assign = build_cast_stmt(visited, TREE_TYPE(new_arg), new_arg, ssa_name_var, &gsi, BEFORE_STMT, true); |
16155 |
++ } else { |
16156 |
++ gsi = gsi_for_stmt(def_stmt); |
16157 |
++ assign = build_cast_stmt(visited, TREE_TYPE(new_arg), new_arg, ssa_name_var, &gsi, AFTER_STMT, true); |
16158 |
+ } |
16159 |
-+ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
16160 |
+ |
16161 |
-+ return 0; |
16162 |
++ pointer_set_insert(visited->my_stmts, assign); |
16163 |
++ return get_lhs(assign); |
16164 |
+} |
16165 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_plugin_hash.c b/tools/gcc/size_overflow_plugin/size_overflow_plugin_hash.c |
16166 |
-new file mode 100644 |
16167 |
-index 0000000..87af656 |
16168 |
---- /dev/null |
16169 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_plugin_hash.c |
16170 |
-@@ -0,0 +1,352 @@ |
16171 |
-+/* |
16172 |
-+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
16173 |
-+ * Licensed under the GPL v2, or (at your option) v3 |
16174 |
-+ * |
16175 |
-+ * Homepage: |
16176 |
-+ * https://github.com/ephox-gcc-plugins/size_overflow |
16177 |
-+ * |
16178 |
-+ * Documentation: |
16179 |
-+ * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
16180 |
-+ * |
16181 |
-+ * This plugin recomputes expressions of function arguments marked by a size_overflow attribute |
16182 |
-+ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
16183 |
-+ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
16184 |
-+ * |
16185 |
-+ * Usage: |
16186 |
-+ * $ make |
16187 |
-+ * $ make run |
16188 |
-+ */ |
16189 |
+ |
16190 |
-+#include "size_overflow.h" |
16191 |
++static tree cast_visited_phi_arg(struct visited *visited, tree ssa_name_var, tree arg, tree size_overflow_type) |
16192 |
++{ |
16193 |
++ basic_block bb; |
16194 |
++ gimple_stmt_iterator gsi; |
16195 |
++ const_gimple def_stmt; |
16196 |
++ const_gimple assign; |
16197 |
+ |
16198 |
-+#include "size_overflow_hash.h" |
16199 |
-+#include "disable_size_overflow_hash.h" |
16200 |
-+#include "size_overflow_hash_aux.h" |
16201 |
++ def_stmt = get_def_stmt(arg); |
16202 |
++ bb = gimple_bb(def_stmt); |
16203 |
++ gcc_assert(bb->index != 0); |
16204 |
++ gsi = gsi_after_labels(bb); |
16205 |
+ |
16206 |
-+static const_tree get_function_type(const_tree decl) |
16207 |
-+{ |
16208 |
-+ if (FUNCTION_PTR_P(decl)) |
16209 |
-+ return TREE_TYPE(TREE_TYPE(decl)); |
16210 |
-+ gcc_assert(TREE_CODE(decl) == FUNCTION_DECL); |
16211 |
-+ return TREE_TYPE(decl); |
16212 |
++ assign = build_cast_stmt(visited, size_overflow_type, arg, ssa_name_var, &gsi, BEFORE_STMT, false); |
16213 |
++ pointer_set_insert(visited->my_stmts, assign); |
16214 |
++ return get_lhs(assign); |
16215 |
+} |
16216 |
+ |
16217 |
-+static unsigned char get_tree_code(const_tree type) |
16218 |
++static tree create_new_phi_arg(struct visited *visited, tree ssa_name_var, tree new_arg, gphi *oldstmt, unsigned int i) |
16219 |
+{ |
16220 |
-+ switch (TREE_CODE(type)) { |
16221 |
-+ case ARRAY_TYPE: |
16222 |
-+ return 0; |
16223 |
-+ case BOOLEAN_TYPE: |
16224 |
-+ return 1; |
16225 |
-+ case ENUMERAL_TYPE: |
16226 |
-+ return 2; |
16227 |
-+ case FUNCTION_TYPE: |
16228 |
-+ return 3; |
16229 |
-+ case INTEGER_TYPE: |
16230 |
-+ return 4; |
16231 |
-+ case POINTER_TYPE: |
16232 |
-+ return 5; |
16233 |
-+ case RECORD_TYPE: |
16234 |
-+ return 6; |
16235 |
-+ case UNION_TYPE: |
16236 |
-+ return 7; |
16237 |
-+ case VOID_TYPE: |
16238 |
-+ return 8; |
16239 |
-+ case REAL_TYPE: |
16240 |
-+ return 9; |
16241 |
-+ case VECTOR_TYPE: |
16242 |
-+ return 10; |
16243 |
-+ case REFERENCE_TYPE: |
16244 |
-+ return 11; |
16245 |
-+ case OFFSET_TYPE: |
16246 |
-+ return 12; |
16247 |
-+ case COMPLEX_TYPE: |
16248 |
-+ return 13; |
16249 |
-+ default: |
16250 |
-+ debug_tree(type); |
16251 |
-+ gcc_unreachable(); |
16252 |
-+ } |
16253 |
-+} |
16254 |
++ tree size_overflow_type; |
16255 |
++ tree arg; |
16256 |
++ const_gimple def_stmt; |
16257 |
+ |
16258 |
-+// http://www.team5150.com/~andrew/noncryptohashzoo2~/CrapWow.html |
16259 |
-+static unsigned int CrapWow(const char *key, unsigned int len, unsigned int seed) |
16260 |
-+{ |
16261 |
-+#define cwfold( a, b, lo, hi ) { p = (unsigned int)(a) * (unsigned long long)(b); lo ^= (unsigned int)p; hi ^= (unsigned int)(p >> 32); } |
16262 |
-+#define cwmixa( in ) { cwfold( in, m, k, h ); } |
16263 |
-+#define cwmixb( in ) { cwfold( in, n, h, k ); } |
16264 |
++ if (new_arg != NULL_TREE && is_gimple_constant(new_arg)) |
16265 |
++ return new_arg; |
16266 |
+ |
16267 |
-+ unsigned int m = 0x57559429; |
16268 |
-+ unsigned int n = 0x5052acdb; |
16269 |
-+ const unsigned int *key4 = (const unsigned int *)key; |
16270 |
-+ unsigned int h = len; |
16271 |
-+ unsigned int k = len + seed + n; |
16272 |
-+ unsigned long long p; |
16273 |
++ arg = gimple_phi_arg_def(oldstmt, i); |
16274 |
++ def_stmt = get_def_stmt(arg); |
16275 |
++ gcc_assert(def_stmt != NULL); |
16276 |
++ size_overflow_type = get_size_overflow_type(visited, oldstmt, arg); |
16277 |
+ |
16278 |
-+ while (len >= 8) { |
16279 |
-+ cwmixb(key4[0]) cwmixa(key4[1]) key4 += 2; |
16280 |
-+ len -= 8; |
16281 |
-+ } |
16282 |
-+ if (len >= 4) { |
16283 |
-+ cwmixb(key4[0]) key4 += 1; |
16284 |
-+ len -= 4; |
16285 |
++ switch (gimple_code(def_stmt)) { |
16286 |
++ case GIMPLE_PHI: |
16287 |
++ return cast_visited_phi_arg(visited, ssa_name_var, arg, size_overflow_type); |
16288 |
++ case GIMPLE_NOP: { |
16289 |
++ basic_block bb; |
16290 |
++ |
16291 |
++ bb = gimple_phi_arg_edge(oldstmt, i)->src; |
16292 |
++ return cast_parm_decl(visited, ssa_name_var, arg, size_overflow_type, bb); |
16293 |
+ } |
16294 |
-+ if (len) |
16295 |
-+ cwmixa(key4[0] & ((1 << (len * 8)) - 1 )); |
16296 |
-+ cwmixb(h ^ (k + n)); |
16297 |
-+ return k ^ h; |
16298 |
++ case GIMPLE_ASM: { |
16299 |
++ gimple_stmt_iterator gsi; |
16300 |
++ const_gimple assign; |
16301 |
++ gimple stmt = get_def_stmt(arg); |
16302 |
+ |
16303 |
-+#undef cwfold |
16304 |
-+#undef cwmixa |
16305 |
-+#undef cwmixb |
16306 |
++ gsi = gsi_for_stmt(stmt); |
16307 |
++ assign = build_cast_stmt(visited, size_overflow_type, arg, ssa_name_var, &gsi, AFTER_STMT, false); |
16308 |
++ pointer_set_insert(visited->my_stmts, assign); |
16309 |
++ return get_lhs(assign); |
16310 |
++ } |
16311 |
++ default: |
16312 |
++ gcc_assert(new_arg != NULL_TREE); |
16313 |
++ gcc_assert(types_compatible_p(TREE_TYPE(new_arg), size_overflow_type)); |
16314 |
++ return use_phi_ssa_name(visited, ssa_name_var, new_arg); |
16315 |
++ } |
16316 |
+} |
16317 |
+ |
16318 |
-+static void set_hash(struct decl_hash *decl_hash_data) |
16319 |
++static gphi *overflow_create_phi_node(struct visited *visited, gphi *oldstmt, tree result) |
16320 |
+{ |
16321 |
-+ unsigned int fn, type, codes, seed = 0; |
16322 |
++ basic_block bb; |
16323 |
++ gphi *phi; |
16324 |
++ gimple_seq seq; |
16325 |
++ gimple_stmt_iterator gsi = gsi_for_stmt(oldstmt); |
16326 |
+ |
16327 |
-+ fn = CrapWow(decl_hash_data->fn_name, strlen(decl_hash_data->fn_name), seed) & 0xffff; |
16328 |
-+ codes = CrapWow((const char*)decl_hash_data->tree_codes, decl_hash_data->tree_codes_len, seed) & 0xffff; |
16329 |
-+ type = CrapWow(decl_hash_data->context, strlen(decl_hash_data->context), 0) & 0xffff; |
16330 |
-+ decl_hash_data->hash = type ^ fn ^ codes; |
16331 |
-+} |
16332 |
++ bb = gsi_bb(gsi); |
16333 |
+ |
16334 |
-+static void set_decl_type_codes(const_tree type, struct decl_hash *decl_hash_data) |
16335 |
-+{ |
16336 |
-+ gcc_assert(type != NULL_TREE); |
16337 |
-+ gcc_assert(TREE_CODE_CLASS(TREE_CODE(type)) == tcc_type); |
16338 |
++ if (result == NULL_TREE) { |
16339 |
++ tree old_result = gimple_phi_result(oldstmt); |
16340 |
++ tree size_overflow_type = get_size_overflow_type(visited, oldstmt, old_result); |
16341 |
+ |
16342 |
-+ while (type && decl_hash_data->tree_codes_len < CODES_LIMIT) { |
16343 |
-+ decl_hash_data->tree_codes[decl_hash_data->tree_codes_len] = get_tree_code(type); |
16344 |
-+ decl_hash_data->tree_codes_len++; |
16345 |
-+ type = TREE_TYPE(type); |
16346 |
++ result = create_new_var(size_overflow_type); |
16347 |
+ } |
16348 |
++ |
16349 |
++ phi = as_a_gphi(create_phi_node(result, bb)); |
16350 |
++ gimple_phi_set_result(phi, make_ssa_name(result, phi)); |
16351 |
++ seq = phi_nodes(bb); |
16352 |
++ gsi = gsi_last(seq); |
16353 |
++ gsi_remove(&gsi, false); |
16354 |
++ |
16355 |
++ gsi = gsi_for_stmt(oldstmt); |
16356 |
++ gsi_insert_after(&gsi, phi, GSI_NEW_STMT); |
16357 |
++ gimple_set_bb(phi, bb); |
16358 |
++ return phi; |
16359 |
+} |
16360 |
+ |
16361 |
-+static void set_result_codes(const_tree node, struct decl_hash *decl_hash_data) |
16362 |
++#if BUILDING_GCC_VERSION <= 4007 |
16363 |
++static tree create_new_phi_node(struct visited *visited, VEC(tree, heap) **args, tree ssa_name_var, gimple oldstmt) |
16364 |
++#else |
16365 |
++static tree create_new_phi_node(struct visited *visited, vec<tree, va_heap, vl_embed> *&args, tree ssa_name_var, gphi *oldstmt) |
16366 |
++#endif |
16367 |
+{ |
16368 |
-+ const_tree result; |
16369 |
-+ |
16370 |
-+ gcc_assert(node != NULL_TREE); |
16371 |
++ gphi *new_phi; |
16372 |
++ unsigned int i; |
16373 |
++ tree arg, result; |
16374 |
++ location_t loc = gimple_location(oldstmt); |
16375 |
+ |
16376 |
-+ if (DECL_P(node)) { |
16377 |
-+ result = DECL_RESULT(node); |
16378 |
-+ if (result != NULL_TREE) |
16379 |
-+ return set_decl_type_codes(TREE_TYPE(result), decl_hash_data); |
16380 |
-+ return set_result_codes(TREE_TYPE(node), decl_hash_data); |
16381 |
-+ } |
16382 |
++#if BUILDING_GCC_VERSION <= 4007 |
16383 |
++ gcc_assert(!VEC_empty(tree, *args)); |
16384 |
++#else |
16385 |
++ gcc_assert(!args->is_empty()); |
16386 |
++#endif |
16387 |
+ |
16388 |
-+ gcc_assert(TYPE_P(node)); |
16389 |
++ new_phi = overflow_create_phi_node(visited, oldstmt, ssa_name_var); |
16390 |
++ result = gimple_phi_result(new_phi); |
16391 |
++ ssa_name_var = SSA_NAME_VAR(result); |
16392 |
+ |
16393 |
-+ if (TREE_CODE(node) == FUNCTION_TYPE) |
16394 |
-+ return set_result_codes(TREE_TYPE(node), decl_hash_data); |
16395 |
++#if BUILDING_GCC_VERSION <= 4007 |
16396 |
++ FOR_EACH_VEC_ELT(tree, *args, i, arg) { |
16397 |
++#else |
16398 |
++ FOR_EACH_VEC_SAFE_ELT(args, i, arg) { |
16399 |
++#endif |
16400 |
++ arg = create_new_phi_arg(visited, ssa_name_var, arg, oldstmt, i); |
16401 |
++ add_phi_arg(new_phi, arg, gimple_phi_arg_edge(oldstmt, i), loc); |
16402 |
++ } |
16403 |
+ |
16404 |
-+ return set_decl_type_codes(node, decl_hash_data); |
16405 |
++#if BUILDING_GCC_VERSION <= 4007 |
16406 |
++ VEC_free(tree, heap, *args); |
16407 |
++#else |
16408 |
++ vec_free(args); |
16409 |
++#endif |
16410 |
++ update_stmt(new_phi); |
16411 |
++ pointer_set_insert(visited->my_stmts, new_phi); |
16412 |
++ return result; |
16413 |
+} |
16414 |
+ |
16415 |
-+static void set_decl_codes(struct decl_hash *decl_hash_data) |
16416 |
++static tree handle_phi(interesting_stmts_t expand_from, tree orig_result) |
16417 |
+{ |
16418 |
-+ const_tree arg, type; |
16419 |
-+ enum tree_code code; |
16420 |
++#if BUILDING_GCC_VERSION <= 4007 |
16421 |
++ VEC(tree, heap) *args = NULL; |
16422 |
++#else |
16423 |
++ vec<tree, va_heap, vl_embed> *args = NULL; |
16424 |
++#endif |
16425 |
++ unsigned int i, len; |
16426 |
++ tree ssa_name_var = NULL_TREE; |
16427 |
++ gphi *oldstmt = as_a_gphi(get_def_stmt(orig_result)); |
16428 |
+ |
16429 |
-+ if (TREE_CODE(decl_hash_data->decl) == VAR_DECL || TREE_CODE(decl_hash_data->decl) == FIELD_DECL) { |
16430 |
-+ set_decl_type_codes(TREE_TYPE(decl_hash_data->decl), decl_hash_data); |
16431 |
-+ return; |
16432 |
-+ } |
16433 |
++ len = gimple_phi_num_args(oldstmt); |
16434 |
++ pointer_set_insert(expand_from->visited->stmts, oldstmt); |
16435 |
++ for (i = 0; i < len; i++) { |
16436 |
++ tree arg, new_arg; |
16437 |
+ |
16438 |
-+ type = get_function_type(decl_hash_data->decl); |
16439 |
-+ code = TREE_CODE(type); |
16440 |
-+ gcc_assert(code == FUNCTION_TYPE || code == METHOD_TYPE); |
16441 |
++ arg = gimple_phi_arg_def(oldstmt, i); |
16442 |
++ new_arg = expand(expand_from, arg); |
16443 |
+ |
16444 |
-+ if (FUNCTION_PTR_P(decl_hash_data->decl)) |
16445 |
-+ set_result_codes(type, decl_hash_data); |
16446 |
-+ else |
16447 |
-+ set_result_codes(decl_hash_data->decl, decl_hash_data); |
16448 |
++ if (ssa_name_var == NULL_TREE && new_arg != NULL_TREE) |
16449 |
++ ssa_name_var = SSA_NAME_VAR(new_arg); |
16450 |
+ |
16451 |
-+ for (arg = TYPE_ARG_TYPES(type); arg != NULL_TREE && decl_hash_data->tree_codes_len < CODES_LIMIT; arg = TREE_CHAIN(arg)) |
16452 |
-+ set_decl_type_codes(TREE_VALUE(arg), decl_hash_data); |
16453 |
-+} |
16454 |
++ if (is_gimple_constant(arg)) { |
16455 |
++ tree size_overflow_type = get_size_overflow_type(expand_from->visited, oldstmt, arg); |
16456 |
+ |
16457 |
-+static const struct size_overflow_hash *get_proper_hash_chain(const struct size_overflow_hash *entry, const char *func_name, const char *context) |
16458 |
-+{ |
16459 |
-+ for (; entry; entry = entry->next) { |
16460 |
-+ if (strcmp(entry->name, func_name)) |
16461 |
-+ continue; |
16462 |
-+ if (!strcmp(entry->context, context)) |
16463 |
-+ return entry; |
16464 |
++ new_arg = cast_a_tree(size_overflow_type, arg); |
16465 |
++ } |
16466 |
++ |
16467 |
++#if BUILDING_GCC_VERSION <= 4007 |
16468 |
++ VEC_safe_push(tree, heap, args, new_arg); |
16469 |
++#else |
16470 |
++ vec_safe_push(args, new_arg); |
16471 |
++#endif |
16472 |
+ } |
16473 |
-+ return NULL; |
16474 |
++ |
16475 |
++#if BUILDING_GCC_VERSION <= 4007 |
16476 |
++ return create_new_phi_node(expand_from->visited, &args, ssa_name_var, oldstmt); |
16477 |
++#else |
16478 |
++ return create_new_phi_node(expand_from->visited, args, ssa_name_var, oldstmt); |
16479 |
++#endif |
16480 |
+} |
16481 |
+ |
16482 |
-+unsigned int get_decl_hash(const_tree decl, const char *decl_name) |
16483 |
++static tree create_cast_assign(struct visited *visited, gassign *stmt) |
16484 |
+{ |
16485 |
-+ struct decl_hash decl_hash_data; |
16486 |
-+ enum tree_code code = TREE_CODE(decl); |
16487 |
-+ |
16488 |
-+ gcc_assert(code == FIELD_DECL || code == FUNCTION_DECL || code == VAR_DECL); |
16489 |
-+ |
16490 |
-+ // skip builtins __builtin_constant_p |
16491 |
-+ if (code == FUNCTION_DECL && (DECL_BUILT_IN(decl) || DECL_BUILT_IN_CLASS(decl) == BUILT_IN_NORMAL)) |
16492 |
-+ return NO_HASH; |
16493 |
++ tree rhs1 = gimple_assign_rhs1(stmt); |
16494 |
++ tree lhs = gimple_assign_lhs(stmt); |
16495 |
++ const_tree rhs1_type = TREE_TYPE(rhs1); |
16496 |
++ const_tree lhs_type = TREE_TYPE(lhs); |
16497 |
+ |
16498 |
-+ decl_hash_data.fn_name = decl_name; |
16499 |
-+ decl_hash_data.decl = decl; |
16500 |
-+ decl_hash_data.context = get_decl_context(decl); |
16501 |
-+ if (!decl_hash_data.context) |
16502 |
-+ return NO_HASH; |
16503 |
-+ decl_hash_data.tree_codes_len = 0; |
16504 |
++ if (TYPE_UNSIGNED(rhs1_type) == TYPE_UNSIGNED(lhs_type)) |
16505 |
++ return create_assign(visited, stmt, lhs, AFTER_STMT); |
16506 |
+ |
16507 |
-+ set_decl_codes(&decl_hash_data); |
16508 |
-+ gcc_assert(decl_hash_data.tree_codes_len != 0); |
16509 |
-+ set_hash(&decl_hash_data); |
16510 |
-+ return decl_hash_data.hash; |
16511 |
++ return create_assign(visited, stmt, rhs1, AFTER_STMT); |
16512 |
+} |
16513 |
+ |
16514 |
-+const char *get_orig_decl_name(const_tree decl) |
16515 |
++static bool skip_lhs_cast_check(struct visited *visited, const gassign *stmt) |
16516 |
+{ |
16517 |
-+ const char *name; |
16518 |
-+ unsigned int len; |
16519 |
-+ const void *end; |
16520 |
-+ const_tree orig_decl; |
16521 |
-+ |
16522 |
-+ if (TREE_CODE(decl) == FUNCTION_DECL) |
16523 |
-+ orig_decl = DECL_ORIGIN(decl); |
16524 |
-+ else |
16525 |
-+ orig_decl = decl; |
16526 |
-+ |
16527 |
-+ len = DECL_NAME_LENGTH(orig_decl); |
16528 |
-+ name = DECL_NAME_POINTER(orig_decl); |
16529 |
++ const_tree rhs = gimple_assign_rhs1(stmt); |
16530 |
++ const_gimple def_stmt = get_def_stmt(rhs); |
16531 |
+ |
16532 |
-+ /* Sometimes gcc loses the original cgraph node leaving only clones behind. |
16533 |
-+ * In such cases we will extract the name from the clone and use it in the hash table |
16534 |
-+ * without checking the parameter number on the original (unavailable) decl. |
16535 |
-+ */ |
16536 |
++ // 3.8.2 kernel/futex_compat.c compat_exit_robust_list(): get_user() 64 ulong -> int (compat_long_t), int max |
16537 |
++ if (gimple_code(def_stmt) == GIMPLE_ASM) |
16538 |
++ return true; |
16539 |
+ |
16540 |
-+ if (made_by_compiler(orig_decl)) { |
16541 |
-+ end = memchr(name, '.', len); |
16542 |
-+ if (!end) |
16543 |
-+ return xstrndup(name, len); |
16544 |
-+ len = (long)end - (long)name; |
16545 |
-+ gcc_assert(len > 0); |
16546 |
++ if (is_const_plus_unsigned_signed_truncation(rhs)) { |
16547 |
++ pointer_set_insert(visited->no_cast_check, stmt); |
16548 |
++ return true; |
16549 |
+ } |
16550 |
+ |
16551 |
-+ return xstrndup(name, len); |
16552 |
++ return false; |
16553 |
+} |
16554 |
+ |
16555 |
-+const struct size_overflow_hash *get_disable_size_overflow_hash_entry(unsigned int hash, const char *decl_name, const char *context, unsigned int argnum) |
16556 |
++static tree create_string_param(tree string) |
16557 |
+{ |
16558 |
-+ const struct size_overflow_hash *entry, *entry_node; |
16559 |
++ tree i_type, a_type; |
16560 |
++ const int length = TREE_STRING_LENGTH(string); |
16561 |
+ |
16562 |
-+ entry = disable_size_overflow_hash[hash]; |
16563 |
-+ entry_node = get_proper_hash_chain(entry, decl_name, context); |
16564 |
-+ if (entry_node && entry_node->param & (1U << argnum)) |
16565 |
-+ return entry_node; |
16566 |
-+ return NULL; |
16567 |
++ gcc_assert(length > 0); |
16568 |
++ |
16569 |
++ i_type = build_index_type(build_int_cst(NULL_TREE, length - 1)); |
16570 |
++ a_type = build_array_type(char_type_node, i_type); |
16571 |
++ |
16572 |
++ TREE_TYPE(string) = a_type; |
16573 |
++ TREE_CONSTANT(string) = 1; |
16574 |
++ TREE_READONLY(string) = 1; |
16575 |
++ |
16576 |
++ return build1(ADDR_EXPR, ptr_type_node, string); |
16577 |
+} |
16578 |
+ |
16579 |
-+const struct size_overflow_hash *get_size_overflow_hash_entry(unsigned int hash, const char *decl_name, const char *context, unsigned int argnum) |
16580 |
++static void insert_cond(basic_block cond_bb, tree arg, enum tree_code cond_code, tree type_value) |
16581 |
+{ |
16582 |
-+ const struct size_overflow_hash *entry, *entry_node; |
16583 |
-+ |
16584 |
-+ entry = size_overflow_hash[hash]; |
16585 |
-+ entry_node = get_proper_hash_chain(entry, decl_name, context); |
16586 |
-+ if (entry_node && entry_node->param & (1U << argnum)) |
16587 |
-+ return entry_node; |
16588 |
++ gcond *cond_stmt; |
16589 |
++ gimple_stmt_iterator gsi = gsi_last_bb(cond_bb); |
16590 |
+ |
16591 |
-+ entry = size_overflow_hash_aux[hash]; |
16592 |
-+ entry_node = get_proper_hash_chain(entry, decl_name, context); |
16593 |
-+ if (entry_node && entry_node->param & (1U << argnum)) |
16594 |
-+ return entry_node; |
16595 |
-+ return NULL; |
16596 |
++ cond_stmt = gimple_build_cond(cond_code, arg, type_value, NULL_TREE, NULL_TREE); |
16597 |
++ gsi_insert_after(&gsi, cond_stmt, GSI_CONTINUE_LINKING); |
16598 |
++ update_stmt(cond_stmt); |
16599 |
+} |
16600 |
+ |
16601 |
-+const struct size_overflow_hash *get_size_overflow_hash_entry_tree(const_tree fndecl, unsigned int argnum, bool hash_table) |
16602 |
++static void insert_cond_result(interesting_stmts_t expand_from, basic_block bb_true, const_gimple stmt, const_tree arg, bool min) |
16603 |
+{ |
16604 |
-+ const_tree orig_decl; |
16605 |
-+ unsigned int orig_argnum, hash; |
16606 |
-+ const char *decl_name, *context; |
16607 |
++ gcall *func_stmt; |
16608 |
++ const_gimple def_stmt; |
16609 |
++ const_tree loc_line; |
16610 |
++ tree loc_file, ssa_name, current_func; |
16611 |
++ expanded_location xloc; |
16612 |
++ char *ssa_name_buf; |
16613 |
++ int len; |
16614 |
++ struct cgraph_edge *edge; |
16615 |
++ struct cgraph_node *report_node; |
16616 |
++ int frequency; |
16617 |
++ gimple_stmt_iterator gsi = gsi_start_bb(bb_true); |
16618 |
+ |
16619 |
-+ if (made_by_compiler(fndecl)) { |
16620 |
-+ orig_decl = get_orig_fndecl(fndecl); |
16621 |
-+ orig_argnum = get_correct_argnum(fndecl, orig_decl, argnum); |
16622 |
-+ } else { |
16623 |
-+ orig_decl = fndecl; |
16624 |
-+ orig_argnum = argnum; |
16625 |
-+ } |
16626 |
++ def_stmt = get_def_stmt(arg); |
16627 |
++ if (gimple_has_location(def_stmt)) |
16628 |
++ xloc = expand_location(gimple_location(def_stmt)); |
16629 |
++ else if (gimple_has_location(stmt)) |
16630 |
++ xloc = expand_location(gimple_location(stmt)); |
16631 |
++ else |
16632 |
++ xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl)); |
16633 |
+ |
16634 |
-+ if (orig_argnum == CANNOT_FIND_ARG) |
16635 |
-+ return NULL; |
16636 |
++ loc_line = build_int_cstu(unsigned_type_node, xloc.line); |
16637 |
+ |
16638 |
-+ decl_name = get_orig_decl_name(orig_decl); |
16639 |
-+ hash = get_decl_hash(orig_decl, decl_name); |
16640 |
-+ if (hash == NO_HASH) |
16641 |
-+ return NULL; |
16642 |
++ loc_file = build_string(strlen(xloc.file) + 1, xloc.file); |
16643 |
++ loc_file = create_string_param(loc_file); |
16644 |
+ |
16645 |
-+ context = get_decl_context(orig_decl); |
16646 |
-+ if (!context) |
16647 |
-+ return NULL; |
16648 |
++ current_func = build_string(DECL_NAME_LENGTH(current_function_decl) + 1, DECL_NAME_POINTER(current_function_decl)); |
16649 |
++ current_func = create_string_param(current_func); |
16650 |
+ |
16651 |
-+ if (hash_table == SIZE_OVERFLOW) |
16652 |
-+ return get_size_overflow_hash_entry(hash, decl_name, context, orig_argnum); |
16653 |
-+ return get_disable_size_overflow_hash_entry(hash, decl_name, context, orig_argnum); |
16654 |
++ gcc_assert(DECL_NAME(SSA_NAME_VAR(arg)) != NULL); |
16655 |
++ call_count++; |
16656 |
++ len = asprintf(&ssa_name_buf, "%s_%u %s, count: %u, decl: %s; num: %u; context: %s;\n", DECL_NAME_POINTER(SSA_NAME_VAR(arg)), SSA_NAME_VERSION(arg), min ? "min" : "max", call_count, expand_from->next_node->decl_name, expand_from->next_node->num, expand_from->next_node->context); |
16657 |
++ gcc_assert(len > 0); |
16658 |
++ ssa_name = build_string(len + 1, ssa_name_buf); |
16659 |
++ free(ssa_name_buf); |
16660 |
++ ssa_name = create_string_param(ssa_name); |
16661 |
++ |
16662 |
++ // void report_size_overflow(const char *file, unsigned int line, const char *func, const char *ssa_name) |
16663 |
++ func_stmt = as_a_gcall(gimple_build_call(report_size_overflow_decl, 4, loc_file, loc_line, current_func, ssa_name)); |
16664 |
++ gsi_insert_after(&gsi, func_stmt, GSI_CONTINUE_LINKING); |
16665 |
++ |
16666 |
++ report_node = cgraph_get_create_node(report_size_overflow_decl); |
16667 |
++ gcc_assert(report_node); |
16668 |
++ frequency = compute_call_stmt_bb_frequency(current_function_decl, bb_true); |
16669 |
++ |
16670 |
++ edge = cgraph_create_edge(get_cnode(current_function_decl), report_node, func_stmt, bb_true->count, frequency, bb_true->loop_depth); |
16671 |
++ gcc_assert(edge != NULL); |
16672 |
+} |
16673 |
+ |
16674 |
-+unsigned int find_arg_number_tree(const_tree arg, const_tree func) |
16675 |
++static void insert_check_size_overflow(interesting_stmts_t expand_from, gimple stmt, enum tree_code cond_code, tree arg, tree type_value, bool before, bool min) |
16676 |
+{ |
16677 |
-+ tree var; |
16678 |
-+ unsigned int argnum = 1; |
16679 |
++ basic_block cond_bb, join_bb, bb_true; |
16680 |
++ edge e; |
16681 |
++ gimple_stmt_iterator gsi = gsi_for_stmt(stmt); |
16682 |
+ |
16683 |
-+ if (DECL_ARGUMENTS(func) == NULL_TREE) |
16684 |
-+ return CANNOT_FIND_ARG; |
16685 |
++ cond_bb = gimple_bb(stmt); |
16686 |
++ if (before) |
16687 |
++ gsi_prev(&gsi); |
16688 |
++ if (gsi_end_p(gsi)) |
16689 |
++ e = split_block_after_labels(cond_bb); |
16690 |
++ else |
16691 |
++ e = split_block(cond_bb, gsi_stmt(gsi)); |
16692 |
++ cond_bb = e->src; |
16693 |
++ join_bb = e->dest; |
16694 |
++ e->flags = EDGE_FALSE_VALUE; |
16695 |
++ e->probability = REG_BR_PROB_BASE; |
16696 |
+ |
16697 |
-+ if (TREE_CODE(arg) == SSA_NAME) |
16698 |
-+ arg = SSA_NAME_VAR(arg); |
16699 |
++ bb_true = create_empty_bb(cond_bb); |
16700 |
++ make_edge(cond_bb, bb_true, EDGE_TRUE_VALUE); |
16701 |
++ make_edge(cond_bb, join_bb, EDGE_FALSE_VALUE); |
16702 |
++ make_edge(bb_true, join_bb, EDGE_FALLTHRU); |
16703 |
+ |
16704 |
-+ for (var = DECL_ARGUMENTS(func); var; var = TREE_CHAIN(var), argnum++) { |
16705 |
-+ if (!operand_equal_p(arg, var, 0) && strcmp(DECL_NAME_POINTER(var), DECL_NAME_POINTER(arg))) |
16706 |
-+ continue; |
16707 |
-+ if (!skip_types(var)) |
16708 |
-+ return argnum; |
16709 |
++ gcc_assert(dom_info_available_p(CDI_DOMINATORS)); |
16710 |
++ set_immediate_dominator(CDI_DOMINATORS, bb_true, cond_bb); |
16711 |
++ set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb); |
16712 |
++ |
16713 |
++ if (current_loops != NULL) { |
16714 |
++ gcc_assert(cond_bb->loop_father == join_bb->loop_father); |
16715 |
++ add_bb_to_loop(bb_true, cond_bb->loop_father); |
16716 |
+ } |
16717 |
+ |
16718 |
-+ return CANNOT_FIND_ARG; |
16719 |
-+} |
16720 |
++ insert_cond(cond_bb, arg, cond_code, type_value); |
16721 |
++ insert_cond_result(expand_from, bb_true, stmt, arg, min); |
16722 |
+ |
16723 |
-+const_tree get_attribute(const char* attr_name, const_tree decl) |
16724 |
-+{ |
16725 |
-+ const_tree attr = lookup_attribute(attr_name, DECL_ATTRIBUTES(decl)); |
16726 |
-+ if (attr && TREE_VALUE(attr)) |
16727 |
-+ return attr; |
16728 |
-+ return NULL_TREE; |
16729 |
++// print_the_code_insertions(stmt); |
16730 |
+} |
16731 |
+ |
16732 |
-+/* Check if the function has a size_overflow attribute or it is in the size_overflow hash table. |
16733 |
-+ * If the function is missing everywhere then print the missing message into stderr. |
16734 |
-+ */ |
16735 |
-+void print_missing_function(next_interesting_function_t node) |
16736 |
++void check_size_overflow(interesting_stmts_t expand_from, gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before) |
16737 |
+{ |
16738 |
-+ unsigned int argnum, hash; |
16739 |
-+ const struct size_overflow_hash *entry; |
16740 |
-+ const char *decl_name; |
16741 |
++ const_tree rhs_type = TREE_TYPE(rhs); |
16742 |
++ tree cast_rhs_type, type_max_type, type_min_type, type_max, type_min; |
16743 |
+ |
16744 |
-+ if (node->marked == ASM_STMT_SO_MARK) |
16745 |
++ if (pointer_set_contains(expand_from->visited->no_cast_check, stmt)) |
16746 |
+ return; |
16747 |
+ |
16748 |
-+ if (node->orig_next_node) { |
16749 |
-+ hash = node->orig_next_node->hash; |
16750 |
-+ decl_name = node->orig_next_node->decl_name; |
16751 |
-+ argnum = node->orig_next_node->num; |
16752 |
-+ gcc_assert(!strcmp(node->context, node->orig_next_node->context)); |
16753 |
-+ } else { |
16754 |
-+ hash = node->hash; |
16755 |
-+ decl_name = node->decl_name; |
16756 |
-+ argnum = node->num; |
16757 |
-+ } |
16758 |
++ gcc_assert(rhs_type != NULL_TREE); |
16759 |
++ if (TREE_CODE(rhs_type) == POINTER_TYPE) |
16760 |
++ return; |
16761 |
+ |
16762 |
-+ entry = get_size_overflow_hash_entry(hash, decl_name, node->context, argnum); |
16763 |
-+ if (entry) |
16764 |
++ gcc_assert(TREE_CODE(rhs_type) == INTEGER_TYPE || TREE_CODE(rhs_type) == ENUMERAL_TYPE); |
16765 |
++ |
16766 |
++ if (is_gimple_assign(stmt) && neg_short_add_intentional_overflow(as_a_gassign(stmt))) |
16767 |
+ return; |
16768 |
+ |
16769 |
-+ // inform() would be too slow |
16770 |
-+ fprintf(stderr, "Function %s is missing from the size_overflow hash table +%s+%s+%u+%u+\n", decl_name, decl_name, node->context, argnum, hash); |
16771 |
-+} |
16772 |
++ type_max = cast_a_tree(size_overflow_type, TYPE_MAX_VALUE(rhs_type)); |
16773 |
++ // typemax (-1) < typemin (0) |
16774 |
++ if (TREE_OVERFLOW(type_max)) |
16775 |
++ return; |
16776 |
+ |
16777 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_transform.c b/tools/gcc/size_overflow_plugin/size_overflow_transform.c |
16778 |
-new file mode 100644 |
16779 |
-index 0000000..eebcf4c |
16780 |
---- /dev/null |
16781 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_transform.c |
16782 |
-@@ -0,0 +1,743 @@ |
16783 |
-+/* |
16784 |
-+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
16785 |
-+ * Licensed under the GPL v2, or (at your option) v3 |
16786 |
-+ * |
16787 |
-+ * Homepage: |
16788 |
-+ * https://github.com/ephox-gcc-plugins/size_overflow |
16789 |
-+ * |
16790 |
-+ * Documentation: |
16791 |
-+ * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
16792 |
-+ * |
16793 |
-+ * This plugin recomputes expressions of function arguments marked by a size_overflow attribute |
16794 |
-+ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
16795 |
-+ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
16796 |
-+ * |
16797 |
-+ * Usage: |
16798 |
-+ * $ make |
16799 |
-+ * $ make run |
16800 |
-+ */ |
16801 |
++ type_min = cast_a_tree(size_overflow_type, TYPE_MIN_VALUE(rhs_type)); |
16802 |
+ |
16803 |
-+#include "size_overflow.h" |
16804 |
++ cast_rhs_type = TREE_TYPE(cast_rhs); |
16805 |
++ type_max_type = TREE_TYPE(type_max); |
16806 |
++ gcc_assert(types_compatible_p(cast_rhs_type, type_max_type)); |
16807 |
+ |
16808 |
-+static tree cast_to_orig_type(struct visited *visited, gimple stmt, const_tree orig_node, tree new_node) |
16809 |
++ insert_check_size_overflow(expand_from, stmt, GT_EXPR, cast_rhs, type_max, before, MAX_CHECK); |
16810 |
++ |
16811 |
++ // special case: get_size_overflow_type(), 32, u64->s |
16812 |
++ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode) && TYPE_UNSIGNED(size_overflow_type) && !TYPE_UNSIGNED(rhs_type)) |
16813 |
++ return; |
16814 |
++ |
16815 |
++ type_min_type = TREE_TYPE(type_min); |
16816 |
++ gcc_assert(types_compatible_p(type_max_type, type_min_type)); |
16817 |
++ insert_check_size_overflow(expand_from, stmt, LT_EXPR, cast_rhs, type_min, before, MIN_CHECK); |
16818 |
++} |
16819 |
++ |
16820 |
++static tree get_my_stmt_lhs(struct visited *visited, gimple stmt) |
16821 |
+{ |
16822 |
-+ gimple def_stmt; |
16823 |
-+ const_gimple assign; |
16824 |
-+ tree result, orig_type = TREE_TYPE(orig_node); |
16825 |
+ gimple_stmt_iterator gsi; |
16826 |
++ gimple next_stmt = NULL; |
16827 |
+ |
16828 |
-+ if (gimple_code(stmt) != GIMPLE_PHI) { |
16829 |
-+ gsi = gsi_for_stmt(stmt); |
16830 |
-+ assign = build_cast_stmt(visited, orig_type, new_node, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); |
16831 |
-+ return get_lhs(assign); |
16832 |
-+ } |
16833 |
++ gsi = gsi_for_stmt(stmt); |
16834 |
+ |
16835 |
-+ def_stmt = get_def_stmt(new_node); |
16836 |
-+ if (gimple_code(def_stmt) == GIMPLE_PHI) |
16837 |
-+ gsi = gsi_after_labels(gimple_bb(def_stmt)); |
16838 |
-+ else |
16839 |
-+ gsi = gsi_for_stmt(def_stmt); |
16840 |
++ do { |
16841 |
++ gsi_next(&gsi); |
16842 |
++ next_stmt = gsi_stmt(gsi); |
16843 |
+ |
16844 |
-+ result = gimple_phi_result(stmt); |
16845 |
-+ assign = build_cast_stmt(visited, orig_type, new_node, SSA_NAME_VAR(result), &gsi, AFTER_STMT, false); |
16846 |
-+ return get_lhs(assign); |
16847 |
-+} |
16848 |
++ if (gimple_code(stmt) == GIMPLE_PHI && !pointer_set_contains(visited->my_stmts, next_stmt)) |
16849 |
++ return NULL_TREE; |
16850 |
+ |
16851 |
-+static void change_size_overflow_asm_input(gasm *stmt, tree new_input) |
16852 |
-+{ |
16853 |
-+ tree list; |
16854 |
++ if (pointer_set_contains(visited->my_stmts, next_stmt) && !pointer_set_contains(visited->skip_expr_casts, next_stmt)) |
16855 |
++ break; |
16856 |
+ |
16857 |
-+ gcc_assert(is_size_overflow_insert_check_asm(stmt)); |
16858 |
++ gcc_assert(pointer_set_contains(visited->my_stmts, next_stmt)); |
16859 |
++ } while (!gsi_end_p(gsi)); |
16860 |
+ |
16861 |
-+ list = build_tree_list(NULL_TREE, build_string(3, "rm")); |
16862 |
-+ list = chainon(NULL_TREE, build_tree_list(list, new_input)); |
16863 |
-+ gimple_asm_set_input_op(stmt, 0, list); |
16864 |
++ gcc_assert(next_stmt); |
16865 |
++ return get_lhs(next_stmt); |
16866 |
+} |
16867 |
+ |
16868 |
-+static void change_field_write_rhs(gassign *assign, const_tree orig_rhs, tree new_rhs) |
16869 |
++/* When the result of the negation is cast to a signed type then move |
16870 |
++ * the size_overflow cast check before negation. |
16871 |
++ * ssa: |
16872 |
++ * unsigned _588 |
16873 |
++ * _588 = _587 >> 12; |
16874 |
++ * _589 = -_588; |
16875 |
++ * _590 = (long int) _589; |
16876 |
++ */ |
16877 |
++static bool handle_unsigned_neg_or_bit_not(interesting_stmts_t expand_from, const gassign *stmt) |
16878 |
+{ |
16879 |
-+ const_tree rhs1, rhs2, rhs3 = NULL_TREE; |
16880 |
++ gimple def_neg_stmt, neg_stmt; |
16881 |
++ tree lhs, new_neg_rhs; |
16882 |
++ const_tree rhs, neg_rhs; |
16883 |
++ enum tree_code rhs_code; |
16884 |
+ |
16885 |
-+ rhs1 = gimple_assign_rhs1(assign); |
16886 |
-+ if (rhs1 == orig_rhs) { |
16887 |
-+ gimple_assign_set_rhs1(assign, new_rhs); |
16888 |
-+ return; |
16889 |
-+ } |
16890 |
++ rhs = gimple_assign_rhs1(stmt); |
16891 |
++ lhs = gimple_assign_lhs(stmt); |
16892 |
++ if (TYPE_UNSIGNED(TREE_TYPE(lhs)) || !TYPE_UNSIGNED(TREE_TYPE(rhs))) |
16893 |
++ return false; |
16894 |
+ |
16895 |
-+ rhs2 = gimple_assign_rhs2(assign); |
16896 |
-+ if (rhs2 == orig_rhs) { |
16897 |
-+ gimple_assign_set_rhs2(assign, new_rhs); |
16898 |
-+ return; |
16899 |
-+ } |
16900 |
++ neg_stmt = get_def_stmt(rhs); |
16901 |
++ if (!neg_stmt || !is_gimple_assign(neg_stmt)) |
16902 |
++ return false; |
16903 |
+ |
16904 |
-+#if BUILDING_GCC_VERSION >= 4006 |
16905 |
-+ rhs3 = gimple_assign_rhs3(assign); |
16906 |
-+ if (rhs3 == orig_rhs) { |
16907 |
-+ gimple_assign_set_rhs3(assign, new_rhs); |
16908 |
-+ return; |
16909 |
-+ } |
16910 |
-+#endif |
16911 |
++ rhs_code = gimple_assign_rhs_code(neg_stmt); |
16912 |
++ if (rhs_code != BIT_NOT_EXPR && rhs_code != NEGATE_EXPR) |
16913 |
++ return false; |
16914 |
+ |
16915 |
-+ debug_gimple_stmt(assign); |
16916 |
-+ fprintf(stderr, "orig_rhs:\n"); |
16917 |
-+ debug_tree(orig_rhs); |
16918 |
-+ fprintf(stderr, "rhs1:\n"); |
16919 |
-+ debug_tree(rhs1); |
16920 |
-+ fprintf(stderr, "rhs2:\n"); |
16921 |
-+ debug_tree(rhs2); |
16922 |
-+ fprintf(stderr, "rhs3:\n"); |
16923 |
-+ debug_tree(rhs3); |
16924 |
-+ gcc_unreachable(); |
16925 |
++ neg_rhs = gimple_assign_rhs1(neg_stmt); |
16926 |
++ def_neg_stmt = get_def_stmt(neg_rhs); |
16927 |
++ if (!def_neg_stmt) |
16928 |
++ return false; |
16929 |
++ |
16930 |
++ new_neg_rhs = get_my_stmt_lhs(expand_from->visited, def_neg_stmt); |
16931 |
++ check_size_overflow(expand_from, neg_stmt, TREE_TYPE(new_neg_rhs), new_neg_rhs, lhs, BEFORE_STMT); |
16932 |
++ pointer_set_insert(expand_from->visited->no_cast_check, stmt); |
16933 |
++ return true; |
16934 |
+} |
16935 |
+ |
16936 |
-+static void change_phi_arg(gphi *phi, tree new_node, unsigned int num) |
16937 |
++static tree create_cast_overflow_check(interesting_stmts_t expand_from, tree new_rhs1, gassign *stmt) |
16938 |
+{ |
16939 |
-+ unsigned int i; |
16940 |
-+ location_t loc = gimple_location(phi); |
16941 |
++ bool cast_lhs, cast_rhs; |
16942 |
++ tree lhs = gimple_assign_lhs(stmt); |
16943 |
++ tree rhs = gimple_assign_rhs1(stmt); |
16944 |
++ const_tree lhs_type = TREE_TYPE(lhs); |
16945 |
++ const_tree rhs_type = TREE_TYPE(rhs); |
16946 |
++ enum machine_mode lhs_mode = TYPE_MODE(lhs_type); |
16947 |
++ enum machine_mode rhs_mode = TYPE_MODE(rhs_type); |
16948 |
++ unsigned int lhs_size = GET_MODE_BITSIZE(lhs_mode); |
16949 |
++ unsigned int rhs_size = GET_MODE_BITSIZE(rhs_mode); |
16950 |
+ |
16951 |
-+ for (i = 0; i < gimple_phi_num_args(phi); i++) { |
16952 |
-+ if (i == num) |
16953 |
-+ add_phi_arg(phi, new_node, gimple_phi_arg_edge(phi, i), loc); |
16954 |
++ static bool check_lhs[3][4] = { |
16955 |
++ // ss su us uu |
16956 |
++ { false, true, true, false }, // lhs > rhs |
16957 |
++ { false, false, false, false }, // lhs = rhs |
16958 |
++ { true, true, true, true }, // lhs < rhs |
16959 |
++ }; |
16960 |
++ |
16961 |
++ static bool check_rhs[3][4] = { |
16962 |
++ // ss su us uu |
16963 |
++ { true, false, true, true }, // lhs > rhs |
16964 |
++ { true, false, true, true }, // lhs = rhs |
16965 |
++ { true, false, true, true }, // lhs < rhs |
16966 |
++ }; |
16967 |
++ |
16968 |
++ if (handle_unsigned_neg_or_bit_not(expand_from, stmt)) |
16969 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
16970 |
++ |
16971 |
++ // skip lhs check on HI -> QI cast |
16972 |
++ if (rhs_mode == HImode && lhs_mode == QImode) { |
16973 |
++ pointer_set_insert(expand_from->visited->no_cast_check, stmt); |
16974 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
16975 |
+ } |
16976 |
-+} |
16977 |
+ |
16978 |
-+static void change_orig_node(struct visited *visited, gimple stmt, const_tree orig_node, tree new_node, unsigned int num) |
16979 |
-+{ |
16980 |
-+ tree cast_lhs = cast_to_orig_type(visited, stmt, orig_node, new_node); |
16981 |
++ // skip lhs check on signed SI -> HI cast or signed SI -> QI cast |
16982 |
++ if (rhs_mode == SImode && !TYPE_UNSIGNED(rhs_type) && (lhs_mode == HImode || lhs_mode == QImode)) |
16983 |
++ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
16984 |
+ |
16985 |
-+ switch (gimple_code(stmt)) { |
16986 |
-+ case GIMPLE_RETURN: |
16987 |
-+ gimple_return_set_retval(as_a_greturn(stmt), cast_lhs); |
16988 |
-+ break; |
16989 |
-+ case GIMPLE_CALL: |
16990 |
-+ gimple_call_set_arg(as_a_gcall(stmt), num - 1, cast_lhs); |
16991 |
-+ break; |
16992 |
-+ case GIMPLE_ASM: |
16993 |
-+ change_size_overflow_asm_input(as_a_gasm(stmt), cast_lhs); |
16994 |
-+ break; |
16995 |
-+ case GIMPLE_ASSIGN: |
16996 |
-+ change_field_write_rhs(as_a_gassign(stmt), orig_node, cast_lhs); |
16997 |
-+ break; |
16998 |
-+ case GIMPLE_PHI: |
16999 |
-+ change_phi_arg(as_a_gphi(stmt), cast_lhs, num); |
17000 |
-+ break; |
17001 |
-+ default: |
17002 |
-+ debug_gimple_stmt(stmt); |
17003 |
-+ gcc_unreachable(); |
17004 |
++ if (lhs_size > rhs_size) { |
17005 |
++ cast_lhs = check_lhs[0][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
17006 |
++ cast_rhs = check_rhs[0][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
17007 |
++ } else if (lhs_size == rhs_size) { |
17008 |
++ cast_lhs = check_lhs[1][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
17009 |
++ cast_rhs = check_rhs[1][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
17010 |
++ } else { |
17011 |
++ cast_lhs = check_lhs[2][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
17012 |
++ cast_rhs = check_rhs[2][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
17013 |
+ } |
17014 |
+ |
17015 |
-+ update_stmt(stmt); |
17016 |
-+} |
17017 |
++ if (!cast_lhs && !cast_rhs) |
17018 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
17019 |
+ |
17020 |
-+// e.g., 3.8.2, 64, arch/x86/ia32/ia32_signal.c copy_siginfo_from_user32(): compat_ptr() u32 max |
17021 |
-+static bool skip_asm_cast(const_tree arg) |
17022 |
-+{ |
17023 |
-+ gimple def_stmt = get_def_stmt(arg); |
17024 |
++ if (cast_lhs && !skip_lhs_cast_check(expand_from->visited, stmt)) |
17025 |
++ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs1), new_rhs1, lhs, BEFORE_STMT); |
17026 |
+ |
17027 |
-+ if (!def_stmt || !gimple_assign_cast_p(def_stmt)) |
17028 |
-+ return false; |
17029 |
++ if (cast_rhs) |
17030 |
++ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs1), new_rhs1, rhs, BEFORE_STMT); |
17031 |
+ |
17032 |
-+ def_stmt = get_def_stmt(gimple_assign_rhs1(def_stmt)); |
17033 |
-+ if (is_size_overflow_asm(def_stmt)) |
17034 |
-+ return false; |
17035 |
-+ return def_stmt && gimple_code(def_stmt) == GIMPLE_ASM; |
17036 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
17037 |
+} |
17038 |
+ |
17039 |
-+static interesting_stmts_t create_interesting_stmts(interesting_stmts_t head, next_interesting_function_t next_node, tree orig_node, gimple first_stmt, unsigned int num) |
17040 |
++static tree handle_unary_rhs(interesting_stmts_t expand_from, gassign *stmt) |
17041 |
+{ |
17042 |
-+ interesting_stmts_t new_node; |
17043 |
++ enum tree_code rhs_code; |
17044 |
++ tree rhs1, new_rhs1, lhs = gimple_assign_lhs(stmt); |
17045 |
+ |
17046 |
-+ new_node = (interesting_stmts_t )xmalloc(sizeof(*new_node)); |
17047 |
-+ new_node->first_stmt = first_stmt; |
17048 |
-+ new_node->num = num; |
17049 |
-+ new_node->orig_node = orig_node; |
17050 |
-+ new_node->next = head; |
17051 |
-+ new_node->next_node = next_node; |
17052 |
-+ return new_node; |
17053 |
-+} |
17054 |
++ if (pointer_set_contains(expand_from->visited->my_stmts, stmt)) |
17055 |
++ return lhs; |
17056 |
+ |
17057 |
-+static void free_interesting_stmts(interesting_stmts_t head) |
17058 |
-+{ |
17059 |
-+ while (head) { |
17060 |
-+ interesting_stmts_t cur = head->next; |
17061 |
-+ free(head); |
17062 |
-+ head = cur; |
17063 |
-+ } |
17064 |
-+} |
17065 |
++ rhs1 = gimple_assign_rhs1(stmt); |
17066 |
++ if (TREE_CODE(TREE_TYPE(rhs1)) == POINTER_TYPE) |
17067 |
++ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
17068 |
+ |
17069 |
-+/* This function calls the main recursion function (expand) that duplicates the stmts. Before that it checks the intentional_overflow attribute, |
17070 |
-+ * it decides whether the duplication is necessary or not. After expand() it changes the orig node to the duplicated node |
17071 |
-+ * in the original stmt (first stmt) and it inserts the overflow check for the arg of the callee or for the return value. |
17072 |
-+ */ |
17073 |
-+static interesting_stmts_t search_interesting_stmt(interesting_stmts_t head, next_interesting_function_t next_node, gimple first_stmt, tree orig_node, unsigned int num) |
17074 |
-+{ |
17075 |
-+ enum tree_code orig_code; |
17076 |
++ new_rhs1 = expand(expand_from, rhs1); |
17077 |
+ |
17078 |
-+ gcc_assert(orig_node != NULL_TREE); |
17079 |
++ if (new_rhs1 == NULL_TREE) |
17080 |
++ return create_cast_assign(expand_from->visited, stmt); |
17081 |
+ |
17082 |
-+ if (is_gimple_constant(orig_node)) |
17083 |
-+ return head; |
17084 |
++ if (pointer_set_contains(expand_from->visited->no_cast_check, stmt)) |
17085 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
17086 |
+ |
17087 |
-+ orig_code = TREE_CODE(orig_node); |
17088 |
-+ gcc_assert(orig_code != FIELD_DECL && orig_code != FUNCTION_DECL); |
17089 |
++#if BUILDING_GCC_VERSION >= 5000 |
17090 |
++ if (short_or_neg_const_ushort(stmt)) { |
17091 |
++ pointer_set_insert(expand_from->visited->no_cast_check, stmt); |
17092 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
17093 |
++ } |
17094 |
++#endif |
17095 |
+ |
17096 |
-+ if (skip_types(orig_node)) |
17097 |
-+ return head; |
17098 |
++ rhs_code = gimple_assign_rhs_code(stmt); |
17099 |
++ if (rhs_code == BIT_NOT_EXPR || rhs_code == NEGATE_EXPR) { |
17100 |
++ tree size_overflow_type = get_size_overflow_type(expand_from->visited, stmt, rhs1); |
17101 |
+ |
17102 |
-+ // find a defining marked caller argument or struct field for arg |
17103 |
-+ if (check_intentional_size_overflow_asm_and_attribute(orig_node) != MARK_NO) |
17104 |
-+ return head; |
17105 |
++ new_rhs1 = cast_to_new_size_overflow_type(expand_from->visited, stmt, new_rhs1, size_overflow_type, BEFORE_STMT); |
17106 |
++ check_size_overflow(expand_from, stmt, size_overflow_type, new_rhs1, rhs1, BEFORE_STMT); |
17107 |
++ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
17108 |
++ } |
17109 |
+ |
17110 |
-+ if (skip_asm_cast(orig_node)) |
17111 |
-+ return head; |
17112 |
++ if (!gimple_assign_cast_p(stmt)) |
17113 |
++ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
17114 |
+ |
17115 |
-+ return create_interesting_stmts(head, next_node, orig_node, first_stmt, num); |
17116 |
++ return create_cast_overflow_check(expand_from, new_rhs1, stmt); |
17117 |
+} |
17118 |
+ |
17119 |
-+static bool is_signed_error_code_const(const_tree node) |
17120 |
++static tree handle_unary_ops(interesting_stmts_t expand_from, gassign *stmt) |
17121 |
+{ |
17122 |
-+ HOST_WIDE_INT constant = tree_to_shwi(node); |
17123 |
++ tree rhs1, lhs = gimple_assign_lhs(stmt); |
17124 |
++ gimple def_stmt = get_def_stmt(lhs); |
17125 |
+ |
17126 |
-+ return constant >= -4095 && constant <= -1; |
17127 |
++ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP); |
17128 |
++ rhs1 = gimple_assign_rhs1(def_stmt); |
17129 |
++ |
17130 |
++ if (is_gimple_constant(rhs1)) |
17131 |
++ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
17132 |
++ |
17133 |
++ switch (TREE_CODE(rhs1)) { |
17134 |
++ case SSA_NAME: { |
17135 |
++ tree ret = handle_unary_rhs(expand_from, as_a_gassign(def_stmt)); |
17136 |
++ |
17137 |
++ if (gimple_assign_cast_p(stmt)) |
17138 |
++ unsigned_signed_cast_intentional_overflow(expand_from->visited, stmt); |
17139 |
++ return ret; |
17140 |
++ } |
17141 |
++ case ARRAY_REF: |
17142 |
++ case BIT_FIELD_REF: |
17143 |
++ case ADDR_EXPR: |
17144 |
++ case COMPONENT_REF: |
17145 |
++ case INDIRECT_REF: |
17146 |
++#if BUILDING_GCC_VERSION >= 4006 |
17147 |
++ case MEM_REF: |
17148 |
++#endif |
17149 |
++ case TARGET_MEM_REF: |
17150 |
++ case VIEW_CONVERT_EXPR: |
17151 |
++ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
17152 |
++ case PARM_DECL: |
17153 |
++ case VAR_DECL: |
17154 |
++ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
17155 |
++ |
17156 |
++ default: |
17157 |
++ debug_gimple_stmt(def_stmt); |
17158 |
++ debug_tree(rhs1); |
17159 |
++ gcc_unreachable(); |
17160 |
++ } |
17161 |
+} |
17162 |
+ |
17163 |
-+static bool is_unsigned_error_code_const(const_tree node) |
17164 |
++static void __unused print_the_code_insertions(const_gimple stmt) |
17165 |
+{ |
17166 |
-+ unsigned HOST_WIDE_INT constant = tree_to_uhwi(node); |
17167 |
++ location_t loc = gimple_location(stmt); |
17168 |
+ |
17169 |
-+ // ulong -4095 |
17170 |
-+ if (constant >= 0xfffffffffffff001) |
17171 |
-+ return true; |
17172 |
-+ // uint -4095 |
17173 |
-+ return constant >= 0xfffff001; |
17174 |
++ inform(loc, "Integer size_overflow check applied here."); |
17175 |
+} |
17176 |
+ |
17177 |
-+static bool is_error_code_const(const_tree node) |
17178 |
++static bool is_from_cast(const_tree node) |
17179 |
+{ |
17180 |
-+ enum machine_mode mode; |
17181 |
++ gimple def_stmt = get_def_stmt(node); |
17182 |
+ |
17183 |
-+ if (!is_gimple_constant(node)) |
17184 |
-+ return false; |
17185 |
-+ mode = TYPE_MODE(TREE_TYPE(node)); |
17186 |
-+ if (mode != SImode && mode != DImode) |
17187 |
++ if (!def_stmt) |
17188 |
+ return false; |
17189 |
+ |
17190 |
-+ if (!TYPE_UNSIGNED(TREE_TYPE(node)) && is_signed_error_code_const(node)) |
17191 |
++ if (gimple_assign_cast_p(def_stmt)) |
17192 |
+ return true; |
17193 |
-+ return TYPE_UNSIGNED(TREE_TYPE(node)) && is_unsigned_error_code_const(node); |
17194 |
++ |
17195 |
++ return false; |
17196 |
+} |
17197 |
+ |
17198 |
-+static bool has_error_code(gphi *phi) |
17199 |
++// Skip duplication when there is a minus expr and the type of rhs1 or rhs2 is a pointer_type. |
17200 |
++static bool is_ptr_diff(gassign *stmt) |
17201 |
+{ |
17202 |
-+ unsigned int i, len = gimple_phi_num_args(phi); |
17203 |
-+ |
17204 |
-+ for (i = 0; i < len; i++) { |
17205 |
-+ const_tree arg = gimple_phi_arg_def(phi, i); |
17206 |
++ const_tree rhs1, rhs2, ptr1_rhs, ptr2_rhs; |
17207 |
+ |
17208 |
-+ if (is_error_code_const(arg)) |
17209 |
-+ return true; |
17210 |
-+ } |
17211 |
++ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR) |
17212 |
++ return false; |
17213 |
+ |
17214 |
-+ return false; |
17215 |
-+} |
17216 |
++ rhs1 = gimple_assign_rhs1(stmt); |
17217 |
++ if (!is_from_cast(rhs1)) |
17218 |
++ return false; |
17219 |
+ |
17220 |
-+static interesting_stmts_t search_interesting_rets(interesting_stmts_t head, next_interesting_function_t next_node_ret, greturn *ret) |
17221 |
-+{ |
17222 |
-+ tree first_node; |
17223 |
++ rhs2 = gimple_assign_rhs2(stmt); |
17224 |
++ if (!is_from_cast(rhs2)) |
17225 |
++ return false; |
17226 |
+ |
17227 |
-+ if (!next_node_ret || next_node_ret->marked == ASM_STMT_SO_MARK) |
17228 |
-+ return head; |
17229 |
++ ptr1_rhs = gimple_assign_rhs1(get_def_stmt(rhs1)); |
17230 |
++ ptr2_rhs = gimple_assign_rhs1(get_def_stmt(rhs2)); |
17231 |
+ |
17232 |
-+ first_node = gimple_return_retval(ret); |
17233 |
-+ if (first_node == NULL_TREE) |
17234 |
-+ return head; |
17235 |
++ if (TREE_CODE(TREE_TYPE(ptr1_rhs)) != POINTER_TYPE && TREE_CODE(TREE_TYPE(ptr2_rhs)) != POINTER_TYPE) |
17236 |
++ return false; |
17237 |
+ |
17238 |
-+ return search_interesting_stmt(head, next_node_ret, ret, first_node, 0); |
17239 |
++ return true; |
17240 |
+} |
17241 |
+ |
17242 |
-+static void handle_binary_assign(interesting_stmts_t expand_from, gassign *assign, tree rhs) |
17243 |
++static tree handle_comparison_code_class(interesting_stmts_t expand_from, gassign *stmt, tree new_rhs1, tree new_rhs2) |
17244 |
+{ |
17245 |
-+ tree new_node; |
17246 |
-+ gimple def_orig_node; |
17247 |
++ tree rhs1, rhs2, lhs; |
17248 |
+ |
17249 |
-+ new_node = expand(expand_from, rhs); |
17250 |
-+ if (new_node == NULL_TREE) |
17251 |
-+ return; |
17252 |
++ rhs1 = gimple_assign_rhs1(stmt); |
17253 |
++ if (!is_gimple_constant(rhs1) && new_rhs1 != NULL_TREE) |
17254 |
++ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs1), new_rhs1, rhs1, BEFORE_STMT); |
17255 |
+ |
17256 |
-+ def_orig_node = get_def_stmt(rhs); |
17257 |
-+ if (pointer_set_contains(expand_from->visited->no_cast_check, def_orig_node)) |
17258 |
-+ return; |
17259 |
-+ change_orig_node(expand_from->visited, assign, rhs, new_node, 0); |
17260 |
-+ check_size_overflow(expand_from, assign, TREE_TYPE(new_node), new_node, rhs, BEFORE_STMT); |
17261 |
++ lhs = gimple_assign_lhs(stmt); |
17262 |
++ if (new_rhs2 == NULL_TREE) |
17263 |
++ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
17264 |
++ |
17265 |
++ rhs2 = gimple_assign_rhs2(stmt); |
17266 |
++ if (!is_gimple_constant(rhs2)) |
17267 |
++ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs2), new_rhs2, rhs2, BEFORE_STMT); |
17268 |
++ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
17269 |
+} |
17270 |
+ |
17271 |
-+static bool search_error_codes(gimple_set *visited_error_codes, interesting_stmts_t expand_from, tree lhs, bool error_code) |
17272 |
++static tree handle_binary_ops(interesting_stmts_t expand_from, tree lhs) |
17273 |
+{ |
17274 |
-+ gimple def_stmt; |
17275 |
++ enum intentional_overflow_type res; |
17276 |
++ tree rhs1, rhs2, new_lhs; |
17277 |
++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); |
17278 |
++ tree new_rhs1 = NULL_TREE; |
17279 |
++ tree new_rhs2 = NULL_TREE; |
17280 |
+ |
17281 |
-+ def_stmt = get_def_stmt(lhs); |
17282 |
-+ if (!def_stmt || gimple_code(def_stmt) == GIMPLE_NOP) |
17283 |
-+ return error_code; |
17284 |
++ if (is_ptr_diff(def_stmt)) |
17285 |
++ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
17286 |
+ |
17287 |
-+ if (pointer_set_insert(visited_error_codes, def_stmt)) |
17288 |
-+ return error_code; |
17289 |
++ rhs1 = gimple_assign_rhs1(def_stmt); |
17290 |
++ rhs2 = gimple_assign_rhs2(def_stmt); |
17291 |
+ |
17292 |
-+ if (is_gimple_constant(lhs)) |
17293 |
-+ return error_code; |
17294 |
-+ if (skip_types(lhs)) |
17295 |
-+ return is_error_code_const(lhs); |
17296 |
++ /* no DImode/TImode division in the 32/64 bit kernel */ |
17297 |
++ switch (gimple_assign_rhs_code(def_stmt)) { |
17298 |
++ case RDIV_EXPR: |
17299 |
++ case TRUNC_DIV_EXPR: |
17300 |
++ case CEIL_DIV_EXPR: |
17301 |
++ case FLOOR_DIV_EXPR: |
17302 |
++ case ROUND_DIV_EXPR: |
17303 |
++ case TRUNC_MOD_EXPR: |
17304 |
++ case CEIL_MOD_EXPR: |
17305 |
++ case FLOOR_MOD_EXPR: |
17306 |
++ case ROUND_MOD_EXPR: |
17307 |
++ case EXACT_DIV_EXPR: |
17308 |
++ case POINTER_PLUS_EXPR: |
17309 |
++ case BIT_AND_EXPR: |
17310 |
++ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
17311 |
++ default: |
17312 |
++ break; |
17313 |
++ } |
17314 |
+ |
17315 |
-+ switch (gimple_code(def_stmt)) { |
17316 |
-+ case GIMPLE_CALL: |
17317 |
-+ case GIMPLE_ASM: |
17318 |
-+ return error_code; |
17319 |
-+ case GIMPLE_ASSIGN: { |
17320 |
-+ tree rhs1, rhs2; |
17321 |
-+ gassign *assign = as_a_gassign(def_stmt); |
17322 |
++ new_lhs = handle_integer_truncation(expand_from, lhs); |
17323 |
++ if (new_lhs != NULL_TREE) |
17324 |
++ return new_lhs; |
17325 |
+ |
17326 |
-+ switch (gimple_num_ops(assign)) { |
17327 |
-+ case 2: |
17328 |
-+ return search_error_codes(visited_error_codes, expand_from, gimple_assign_rhs1(def_stmt), error_code); |
17329 |
-+ case 3: |
17330 |
-+ if (!error_code) |
17331 |
-+ return error_code; |
17332 |
++ if (TREE_CODE(rhs1) == SSA_NAME) |
17333 |
++ new_rhs1 = expand(expand_from, rhs1); |
17334 |
++ if (TREE_CODE(rhs2) == SSA_NAME) |
17335 |
++ new_rhs2 = expand(expand_from, rhs2); |
17336 |
+ |
17337 |
-+ /* Run stmt duplication from the binary assignment ops (rhs1 and rhs2) |
17338 |
-+ * so that size_overflow checking skips the lhs of the last binary assignment |
17339 |
-+ * before the error code PHI. |
17340 |
-+ */ |
17341 |
-+ rhs1 = gimple_assign_rhs1(assign); |
17342 |
-+ handle_binary_assign(expand_from, assign, rhs1); |
17343 |
-+ rhs2 = gimple_assign_rhs2(assign); |
17344 |
-+ handle_binary_assign(expand_from, assign, rhs2); |
17345 |
-+ return error_code; |
17346 |
-+ } |
17347 |
-+ gcc_unreachable(); |
17348 |
++ res = add_mul_intentional_overflow(def_stmt); |
17349 |
++ if (res != NO_INTENTIONAL_OVERFLOW) { |
17350 |
++ new_lhs = dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); |
17351 |
++ insert_cast_expr(expand_from->visited, as_a_gassign(get_def_stmt(new_lhs)), res); |
17352 |
++ return new_lhs; |
17353 |
+ } |
17354 |
-+ case GIMPLE_PHI: { |
17355 |
-+ unsigned int i; |
17356 |
+ |
17357 |
-+ error_code = has_error_code(as_a_gphi(def_stmt)); |
17358 |
-+ for (i = 0; i < gimple_phi_num_args(def_stmt); i++) { |
17359 |
-+ error_code = search_error_codes(visited_error_codes, expand_from, gimple_phi_arg_def(def_stmt, i), error_code); |
17360 |
-+ } |
17361 |
-+ return error_code; |
17362 |
-+ } |
17363 |
-+ default: |
17364 |
-+ debug_gimple_stmt(def_stmt); |
17365 |
-+ error("%s: unknown gimple code", __func__); |
17366 |
-+ gcc_unreachable(); |
17367 |
++ if (skip_expr_on_double_type(def_stmt)) { |
17368 |
++ new_lhs = dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); |
17369 |
++ insert_cast_expr(expand_from->visited, as_a_gassign(get_def_stmt(new_lhs)), NO_INTENTIONAL_OVERFLOW); |
17370 |
++ return new_lhs; |
17371 |
+ } |
17372 |
-+} |
17373 |
+ |
17374 |
-+static bool handle_error_codes(interesting_stmts_t expand_from) |
17375 |
-+{ |
17376 |
-+ bool error_code; |
17377 |
-+ gimple_set *visited_error_codes; |
17378 |
++ if (is_a_neg_overflow(def_stmt, rhs2)) |
17379 |
++ return handle_intentional_overflow(expand_from, true, def_stmt, new_rhs1, NULL_TREE); |
17380 |
++ if (is_a_neg_overflow(def_stmt, rhs1)) |
17381 |
++ return handle_intentional_overflow(expand_from, true, def_stmt, new_rhs2, new_rhs2); |
17382 |
+ |
17383 |
-+ // expand the data flow from a return stmt |
17384 |
-+ if (expand_from->next_node->num != 0 || strcmp(expand_from->next_node->context, "fndecl")) |
17385 |
-+ return false; |
17386 |
+ |
17387 |
-+ visited_error_codes = pointer_set_create(); |
17388 |
-+ error_code = search_error_codes(visited_error_codes, expand_from, expand_from->orig_node, false); |
17389 |
-+ pointer_set_destroy(visited_error_codes); |
17390 |
++ if (is_a_constant_overflow(def_stmt, rhs2)) |
17391 |
++ return handle_intentional_overflow(expand_from, !is_a_cast_and_const_overflow(rhs1), def_stmt, new_rhs1, NULL_TREE); |
17392 |
++ if (is_a_constant_overflow(def_stmt, rhs1)) |
17393 |
++ return handle_intentional_overflow(expand_from, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, new_rhs2); |
17394 |
+ |
17395 |
-+ return error_code; |
17396 |
++ // the const is between 0 and (signed) MAX |
17397 |
++ if (is_gimple_constant(rhs1)) |
17398 |
++ new_rhs1 = create_assign(expand_from->visited, def_stmt, rhs1, BEFORE_STMT); |
17399 |
++ if (is_gimple_constant(rhs2)) |
17400 |
++ new_rhs2 = create_assign(expand_from->visited, def_stmt, rhs2, BEFORE_STMT); |
17401 |
++ |
17402 |
++ if (TREE_CODE_CLASS(gimple_assign_rhs_code(def_stmt)) == tcc_comparison) |
17403 |
++ return handle_comparison_code_class(expand_from, def_stmt, new_rhs1, new_rhs2); |
17404 |
++ |
17405 |
++ if (uconst_neg_intentional_overflow(def_stmt)) { |
17406 |
++ inform(gimple_location(def_stmt), "%s: gcc intentional overflow", __func__); |
17407 |
++ gcc_unreachable(); |
17408 |
++ } |
17409 |
++ |
17410 |
++ return dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); |
17411 |
+} |
17412 |
+ |
17413 |
-+static void handle_interesting_stmt(struct visited *visited, interesting_stmts_t head) |
17414 |
++#if BUILDING_GCC_VERSION >= 4006 |
17415 |
++static tree get_new_rhs(interesting_stmts_t expand_from, tree size_overflow_type, tree rhs) |
17416 |
+{ |
17417 |
-+ interesting_stmts_t cur; |
17418 |
++ if (is_gimple_constant(rhs)) |
17419 |
++ return cast_a_tree(size_overflow_type, rhs); |
17420 |
++ if (TREE_CODE(rhs) != SSA_NAME) |
17421 |
++ return NULL_TREE; |
17422 |
++ return expand(expand_from, rhs); |
17423 |
++} |
17424 |
+ |
17425 |
-+ for (cur = head; cur; cur = cur->next) { |
17426 |
-+ tree new_node; |
17427 |
-+ gimple orig_def_stmt; |
17428 |
++static tree handle_ternary_ops(interesting_stmts_t expand_from, tree lhs) |
17429 |
++{ |
17430 |
++ tree rhs1, rhs2, rhs3, new_rhs1, new_rhs2, new_rhs3, size_overflow_type; |
17431 |
++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); |
17432 |
+ |
17433 |
-+ cur->visited = visited; |
17434 |
-+ if (handle_error_codes(cur)) |
17435 |
-+ continue; |
17436 |
++ size_overflow_type = get_size_overflow_type(expand_from->visited, def_stmt, lhs); |
17437 |
+ |
17438 |
-+ new_node = expand(cur, cur->orig_node); |
17439 |
-+ if (new_node == NULL_TREE) |
17440 |
-+ continue; |
17441 |
++ rhs1 = gimple_assign_rhs1(def_stmt); |
17442 |
++ rhs2 = gimple_assign_rhs2(def_stmt); |
17443 |
++ rhs3 = gimple_assign_rhs3(def_stmt); |
17444 |
++ new_rhs1 = get_new_rhs(expand_from, size_overflow_type, rhs1); |
17445 |
++ new_rhs2 = get_new_rhs(expand_from, size_overflow_type, rhs2); |
17446 |
++ new_rhs3 = get_new_rhs(expand_from, size_overflow_type, rhs3); |
17447 |
+ |
17448 |
-+ orig_def_stmt = get_def_stmt(cur->orig_node); |
17449 |
-+ if (pointer_set_contains(visited->no_cast_check, orig_def_stmt)) |
17450 |
-+ continue; |
17451 |
-+ change_orig_node(visited, cur->first_stmt, cur->orig_node, new_node, cur->num); |
17452 |
-+ check_size_overflow(cur, cur->first_stmt, TREE_TYPE(new_node), new_node, cur->orig_node, BEFORE_STMT); |
17453 |
-+ } |
17454 |
++ return dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); |
17455 |
+} |
17456 |
++#endif |
17457 |
+ |
17458 |
-+static next_interesting_function_t get_interesting_function_next_node(tree decl, unsigned int num) |
17459 |
++static tree expand_visited(struct visited *visited, gimple def_stmt) |
17460 |
+{ |
17461 |
-+ next_interesting_function_t next_node; |
17462 |
-+ const struct size_overflow_hash *so_hash; |
17463 |
-+ struct fn_raw_data raw_data; |
17464 |
++ gimple_stmt_iterator gsi; |
17465 |
++ enum gimple_code code = gimple_code(def_stmt); |
17466 |
+ |
17467 |
-+ raw_data.decl = decl; |
17468 |
-+ raw_data.decl_str = DECL_NAME_POINTER(decl); |
17469 |
-+ raw_data.num = num; |
17470 |
-+ raw_data.marked = YES_SO_MARK; |
17471 |
++ if (code == GIMPLE_ASM) |
17472 |
++ return NULL_TREE; |
17473 |
+ |
17474 |
-+ next_node = get_global_next_interesting_function_entry_with_hash(&raw_data); |
17475 |
-+ if (next_node && next_node->marked != NO_SO_MARK) |
17476 |
-+ return next_node; |
17477 |
++ gsi = gsi_for_stmt(def_stmt); |
17478 |
++ gsi_next(&gsi); |
17479 |
+ |
17480 |
-+ so_hash = get_size_overflow_hash_entry_tree(raw_data.decl, raw_data.num, SIZE_OVERFLOW); |
17481 |
-+ if (so_hash) |
17482 |
-+ return get_and_create_next_node_from_global_next_nodes(&raw_data, NULL); |
17483 |
-+ return NULL; |
17484 |
++ if (gimple_code(def_stmt) == GIMPLE_PHI && gsi_end_p(gsi)) |
17485 |
++ return NULL_TREE; |
17486 |
++ return get_my_stmt_lhs(visited, def_stmt); |
17487 |
+} |
17488 |
+ |
17489 |
-+tree handle_fnptr_assign(const_gimple stmt) |
17490 |
++tree expand(interesting_stmts_t expand_from, tree lhs) |
17491 |
+{ |
17492 |
-+ tree field, rhs, op0; |
17493 |
-+ const_tree op0_type; |
17494 |
-+ enum tree_code rhs_code; |
17495 |
++ gimple def_stmt; |
17496 |
+ |
17497 |
-+ // TODO skip binary assignments for now (fs/sync.c _591 = __bpf_call_base + _590;) |
17498 |
-+ if (gimple_num_ops(stmt) != 2) |
17499 |
-+ return NULL_TREE; |
17500 |
++ def_stmt = get_def_stmt(lhs); |
17501 |
+ |
17502 |
-+ gcc_assert(gimple_num_ops(stmt) == 2); |
17503 |
-+ // TODO skip asm_stmt for now |
17504 |
-+ if (gimple_code(stmt) == GIMPLE_ASM) |
17505 |
-+ return NULL_TREE; |
17506 |
-+ rhs = gimple_assign_rhs1(stmt); |
17507 |
-+ if (is_gimple_constant(rhs)) |
17508 |
++ if (!def_stmt || gimple_code(def_stmt) == GIMPLE_NOP) |
17509 |
+ return NULL_TREE; |
17510 |
+ |
17511 |
-+ rhs_code = TREE_CODE(rhs); |
17512 |
-+ if (rhs_code == VAR_DECL) |
17513 |
-+ return rhs; |
17514 |
++ if (pointer_set_contains(expand_from->visited->my_stmts, def_stmt)) |
17515 |
++ return lhs; |
17516 |
+ |
17517 |
-+ switch (rhs_code) { |
17518 |
-+ case ADDR_EXPR: |
17519 |
-+ op0 = TREE_OPERAND(rhs, 0); |
17520 |
-+ gcc_assert(TREE_CODE(op0) == FUNCTION_DECL); |
17521 |
-+ return op0; |
17522 |
-+ case COMPONENT_REF: |
17523 |
-+ break; |
17524 |
-+ // TODO skip array_ref for now |
17525 |
-+ case ARRAY_REF: |
17526 |
-+ return NULL_TREE; |
17527 |
-+ // TODO skip ssa_name because it can lead to parm_decl |
17528 |
-+ case SSA_NAME: |
17529 |
++ if (pointer_set_contains(expand_from->visited->stmts, def_stmt)) |
17530 |
++ return expand_visited(expand_from->visited, def_stmt); |
17531 |
++ |
17532 |
++ if (is_gimple_constant(lhs)) |
17533 |
+ return NULL_TREE; |
17534 |
-+ // TODO skip mem_ref and indirect_ref for now |
17535 |
-+#if BUILDING_GCC_VERSION >= 4006 |
17536 |
-+ case MEM_REF: |
17537 |
-+#endif |
17538 |
-+ case INDIRECT_REF: |
17539 |
++ if (skip_types(lhs)) |
17540 |
+ return NULL_TREE; |
17541 |
-+ default: |
17542 |
-+ debug_tree(rhs); |
17543 |
-+ debug_gimple_stmt((gimple)stmt); |
17544 |
-+ gcc_unreachable(); |
17545 |
-+ } |
17546 |
+ |
17547 |
-+ op0 = TREE_OPERAND(rhs, 0); |
17548 |
-+ switch (TREE_CODE(op0)) { |
17549 |
-+ // TODO skip array_ref and parm_decl for now |
17550 |
-+ case ARRAY_REF: |
17551 |
-+ case PARM_DECL: |
17552 |
-+ return NULL_TREE; |
17553 |
-+ case COMPONENT_REF: |
17554 |
++ switch (gimple_code(def_stmt)) { |
17555 |
++ case GIMPLE_PHI: |
17556 |
++ return handle_phi(expand_from, lhs); |
17557 |
++ case GIMPLE_CALL: |
17558 |
++ case GIMPLE_ASM: |
17559 |
++ if (is_size_overflow_asm(def_stmt)) |
17560 |
++ return expand(expand_from, get_size_overflow_asm_input(as_a_gasm(def_stmt))); |
17561 |
++ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
17562 |
++ case GIMPLE_ASSIGN: |
17563 |
++ switch (gimple_num_ops(def_stmt)) { |
17564 |
++ case 2: |
17565 |
++ return handle_unary_ops(expand_from, as_a_gassign(def_stmt)); |
17566 |
++ case 3: |
17567 |
++ return handle_binary_ops(expand_from, lhs); |
17568 |
+#if BUILDING_GCC_VERSION >= 4006 |
17569 |
-+ case MEM_REF: |
17570 |
++ case 4: |
17571 |
++ return handle_ternary_ops(expand_from, lhs); |
17572 |
+#endif |
17573 |
-+ case INDIRECT_REF: |
17574 |
-+ case VAR_DECL: |
17575 |
-+ break; |
17576 |
++ } |
17577 |
+ default: |
17578 |
-+ debug_tree(op0); |
17579 |
++ debug_gimple_stmt(def_stmt); |
17580 |
++ error("%s: unknown gimple code", __func__); |
17581 |
+ gcc_unreachable(); |
17582 |
+ } |
17583 |
-+ |
17584 |
-+ op0_type = TREE_TYPE(op0); |
17585 |
-+ // TODO skip unions for now |
17586 |
-+ if (TREE_CODE(op0_type) == UNION_TYPE) |
17587 |
-+ return NULL_TREE; |
17588 |
-+ gcc_assert(TREE_CODE(op0_type) == RECORD_TYPE); |
17589 |
-+ |
17590 |
-+ field = TREE_OPERAND(rhs, 1); |
17591 |
-+ gcc_assert(TREE_CODE(field) == FIELD_DECL); |
17592 |
-+ return field; |
17593 |
+} |
17594 |
+diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c |
17595 |
+new file mode 100644 |
17596 |
+index 0000000..8b69bd4 |
17597 |
+--- /dev/null |
17598 |
++++ b/scripts/gcc-plugins/stackleak_plugin.c |
17599 |
+@@ -0,0 +1,350 @@ |
17600 |
++/* |
17601 |
++ * Copyright 2011-2016 by the PaX Team <pageexec@××××××××.hu> |
17602 |
++ * Licensed under the GPL v2 |
17603 |
++ * |
17604 |
++ * Note: the choice of the license means that the compilation process is |
17605 |
++ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
17606 |
++ * but for the kernel it doesn't matter since it doesn't link against |
17607 |
++ * any of the gcc libraries |
17608 |
++ * |
17609 |
++ * gcc plugin to help implement various PaX features |
17610 |
++ * |
17611 |
++ * - track lowest stack pointer |
17612 |
++ * |
17613 |
++ * TODO: |
17614 |
++ * - initialize all local variables |
17615 |
++ * |
17616 |
++ * BUGS: |
17617 |
++ * - none known |
17618 |
++ */ |
17619 |
+ |
17620 |
-+static tree get_fn_or_fnptr_decl(const gcall *call_stmt) |
17621 |
-+{ |
17622 |
-+ const_tree fnptr; |
17623 |
-+ const_gimple def_stmt; |
17624 |
-+ tree decl = gimple_call_fndecl(call_stmt); |
17625 |
++#include "gcc-common.h" |
17626 |
+ |
17627 |
-+ if (decl != NULL_TREE) |
17628 |
-+ return decl; |
17629 |
++int plugin_is_GPL_compatible; |
17630 |
+ |
17631 |
-+ fnptr = gimple_call_fn(call_stmt); |
17632 |
-+ if (fnptr == NULL_TREE) |
17633 |
-+ return NULL_TREE; |
17634 |
++static int track_frame_size = -1; |
17635 |
++static const char track_function[] = "pax_track_stack"; |
17636 |
++static const char check_function[] = "pax_check_alloca"; |
17637 |
++static GTY(()) tree track_function_decl; |
17638 |
++static GTY(()) tree check_function_decl; |
17639 |
++static bool init_locals; |
17640 |
+ |
17641 |
-+ // !!! assertot kell irni 0-ra, mert csak az lehet ott |
17642 |
-+ if (is_gimple_constant(fnptr)) |
17643 |
-+ return NULL_TREE; |
17644 |
-+ def_stmt = get_fnptr_def_stmt(fnptr); |
17645 |
-+ return handle_fnptr_assign(def_stmt); |
17646 |
-+} |
17647 |
++static struct plugin_info stackleak_plugin_info = { |
17648 |
++ .version = "201602181345", |
17649 |
++ .help = "track-lowest-sp=nn\ttrack sp in functions whose frame size is at least nn bytes\n" |
17650 |
++// "initialize-locals\t\tforcibly initialize all stack frames\n" |
17651 |
++}; |
17652 |
+ |
17653 |
-+// Start stmt duplication on marked function parameters |
17654 |
-+static interesting_stmts_t search_interesting_calls(interesting_stmts_t head, gcall *call_stmt) |
17655 |
++static void stackleak_check_alloca(gimple_stmt_iterator *gsi) |
17656 |
+{ |
17657 |
-+ tree decl; |
17658 |
-+ unsigned int i, len; |
17659 |
-+ |
17660 |
-+ len = gimple_call_num_args(call_stmt); |
17661 |
-+ if (len == 0) |
17662 |
-+ return head; |
17663 |
-+ |
17664 |
-+ decl = get_fn_or_fnptr_decl(call_stmt); |
17665 |
-+ if (decl == NULL_TREE) |
17666 |
-+ return head; |
17667 |
-+ |
17668 |
-+ for (i = 0; i < len; i++) { |
17669 |
-+ tree arg; |
17670 |
-+ next_interesting_function_t next_node; |
17671 |
++ gimple stmt; |
17672 |
++ gcall *check_alloca; |
17673 |
++ tree alloca_size; |
17674 |
++ cgraph_node_ptr node; |
17675 |
++ int frequency; |
17676 |
++ basic_block bb; |
17677 |
+ |
17678 |
-+ arg = gimple_call_arg(call_stmt, i); |
17679 |
-+ if (is_gimple_constant(arg)) |
17680 |
-+ continue; |
17681 |
-+ if (skip_types(arg)) |
17682 |
-+ continue; |
17683 |
-+ next_node = get_interesting_function_next_node(decl, i + 1); |
17684 |
-+ if (next_node) |
17685 |
-+ head = search_interesting_stmt(head, next_node, call_stmt, arg, i + 1); |
17686 |
-+ } |
17687 |
++ // insert call to void pax_check_alloca(unsigned long size) |
17688 |
++ alloca_size = gimple_call_arg(gsi_stmt(*gsi), 0); |
17689 |
++ stmt = gimple_build_call(check_function_decl, 1, alloca_size); |
17690 |
++ check_alloca = as_a_gcall(stmt); |
17691 |
++ gsi_insert_before(gsi, check_alloca, GSI_SAME_STMT); |
17692 |
+ |
17693 |
-+ return head; |
17694 |
++ // update the cgraph |
17695 |
++ bb = gimple_bb(check_alloca); |
17696 |
++ node = cgraph_get_create_node(check_function_decl); |
17697 |
++ gcc_assert(node); |
17698 |
++ frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); |
17699 |
++ cgraph_create_edge(cgraph_get_node(current_function_decl), node, check_alloca, bb->count, frequency, bb->loop_depth); |
17700 |
+} |
17701 |
+ |
17702 |
-+// Find assignements to structure fields and vardecls |
17703 |
-+static interesting_stmts_t search_interesting_structs_vardecls(interesting_stmts_t head, gassign *assign) |
17704 |
++static void stackleak_add_instrumentation(gimple_stmt_iterator *gsi, bool after) |
17705 |
+{ |
17706 |
-+ enum intentional_mark mark; |
17707 |
-+ next_interesting_function_t next_node; |
17708 |
-+ tree rhs1, rhs2, lhs, decl; |
17709 |
-+#if BUILDING_GCC_VERSION >= 4006 |
17710 |
-+ tree rhs3; |
17711 |
-+#endif |
17712 |
-+ |
17713 |
-+ lhs = gimple_assign_lhs(assign); |
17714 |
-+ |
17715 |
-+ if (VAR_P(lhs)) |
17716 |
-+ decl = lhs; |
17717 |
-+ else |
17718 |
-+ decl = get_ref_field(lhs); |
17719 |
-+ if (decl == NULL_TREE) |
17720 |
-+ return head; |
17721 |
-+ if (DECL_NAME(decl) == NULL_TREE) |
17722 |
-+ return head; |
17723 |
-+ |
17724 |
-+ if (is_bitfield_unnamed_cast(decl, assign)) |
17725 |
-+ return head; |
17726 |
-+ |
17727 |
-+ next_node = get_interesting_function_next_node(decl, 0); |
17728 |
-+ if (!next_node) |
17729 |
-+ return head; |
17730 |
-+ |
17731 |
-+ mark = get_intentional_attr_type(decl); |
17732 |
-+ if (mark != MARK_NO) |
17733 |
-+ return head; |
17734 |
-+ |
17735 |
-+ rhs1 = gimple_assign_rhs1(assign); |
17736 |
-+ head = search_interesting_stmt(head, next_node, assign, rhs1, 0); |
17737 |
++ gimple stmt; |
17738 |
++ gcall *track_stack; |
17739 |
++ cgraph_node_ptr node; |
17740 |
++ int frequency; |
17741 |
++ basic_block bb; |
17742 |
+ |
17743 |
-+ rhs2 = gimple_assign_rhs2(assign); |
17744 |
-+ if (rhs2) |
17745 |
-+ head = search_interesting_stmt(head, next_node, assign, rhs2, 0); |
17746 |
++ // insert call to void pax_track_stack(void) |
17747 |
++ stmt = gimple_build_call(track_function_decl, 0); |
17748 |
++ track_stack = as_a_gcall(stmt); |
17749 |
++ if (after) |
17750 |
++ gsi_insert_after(gsi, track_stack, GSI_CONTINUE_LINKING); |
17751 |
++ else |
17752 |
++ gsi_insert_before(gsi, track_stack, GSI_SAME_STMT); |
17753 |
+ |
17754 |
-+#if BUILDING_GCC_VERSION >= 4006 |
17755 |
-+ rhs3 = gimple_assign_rhs3(assign); |
17756 |
-+ if (rhs3) |
17757 |
-+ head = search_interesting_stmt(head, next_node, assign, rhs3, 0); |
17758 |
-+#endif |
17759 |
-+ return head; |
17760 |
++ // update the cgraph |
17761 |
++ bb = gimple_bb(track_stack); |
17762 |
++ node = cgraph_get_create_node(track_function_decl); |
17763 |
++ gcc_assert(node); |
17764 |
++ frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); |
17765 |
++ cgraph_create_edge(cgraph_get_node(current_function_decl), node, track_stack, bb->count, frequency, bb->loop_depth); |
17766 |
+} |
17767 |
+ |
17768 |
-+static next_interesting_function_t create_so_asm_next_interesting_function_node(const gasm *stmt) |
17769 |
++static bool is_alloca(gimple stmt) |
17770 |
+{ |
17771 |
-+ next_interesting_function_t next_node; |
17772 |
-+ struct fn_raw_data raw_data; |
17773 |
-+ |
17774 |
-+ raw_data.decl = NULL_TREE; |
17775 |
-+ raw_data.decl_str = gimple_asm_string(stmt); |
17776 |
-+ raw_data.context = "attr"; |
17777 |
-+ raw_data.hash = 0; |
17778 |
-+ raw_data.num = 0; |
17779 |
-+ raw_data.marked = ASM_STMT_SO_MARK; |
17780 |
++ if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA)) |
17781 |
++ return true; |
17782 |
+ |
17783 |
-+ next_node = get_global_next_interesting_function_entry(&raw_data); |
17784 |
-+ if (next_node) |
17785 |
-+ return next_node; |
17786 |
-+ next_node = create_new_next_interesting_entry(&raw_data, NULL); |
17787 |
-+ gcc_assert(next_node); |
17788 |
++#if BUILDING_GCC_VERSION >= 4007 |
17789 |
++ if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA_WITH_ALIGN)) |
17790 |
++ return true; |
17791 |
++#endif |
17792 |
+ |
17793 |
-+ add_to_global_next_interesting_function(next_node); |
17794 |
-+ return next_node; |
17795 |
++ return false; |
17796 |
+} |
17797 |
+ |
17798 |
-+// Collect interesting stmts for duplication |
17799 |
-+static void search_interesting_stmts(struct visited *visited) |
17800 |
++static unsigned int stackleak_tree_instrument_execute(void) |
17801 |
+{ |
17802 |
-+ basic_block bb; |
17803 |
-+ next_interesting_function_t next_node_ret; |
17804 |
-+ interesting_stmts_t head = NULL; |
17805 |
++ basic_block bb, entry_bb; |
17806 |
++ bool prologue_instrumented = false, is_leaf = true; |
17807 |
+ |
17808 |
-+ next_node_ret = get_interesting_function_next_node(current_function_decl, 0); |
17809 |
++ entry_bb = ENTRY_BLOCK_PTR_FOR_FN(cfun)->next_bb; |
17810 |
+ |
17811 |
++ // 1. loop through BBs and GIMPLE statements |
17812 |
+ FOR_EACH_BB_FN(bb, cfun) { |
17813 |
+ gimple_stmt_iterator gsi; |
17814 |
+ |
17815 |
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
17816 |
-+ gimple stmt = gsi_stmt(gsi); |
17817 |
++ gimple stmt; |
17818 |
+ |
17819 |
-+ switch (gimple_code(stmt)) { |
17820 |
-+ case GIMPLE_ASM: { |
17821 |
-+ tree first_node; |
17822 |
-+ next_interesting_function_t next_node; |
17823 |
-+ const gasm *asm_stmt = as_a_gasm(stmt); |
17824 |
++ stmt = gsi_stmt(gsi); |
17825 |
+ |
17826 |
-+ if (!is_size_overflow_insert_check_asm(asm_stmt)) |
17827 |
-+ continue; |
17828 |
-+ next_node = create_so_asm_next_interesting_function_node(asm_stmt); |
17829 |
-+ first_node = get_size_overflow_asm_input(asm_stmt); |
17830 |
-+ head = search_interesting_stmt(head, next_node, stmt, first_node, 0); |
17831 |
-+ break; |
17832 |
-+ } |
17833 |
-+ case GIMPLE_RETURN: |
17834 |
-+ head = search_interesting_rets(head, next_node_ret, as_a_greturn(stmt)); |
17835 |
-+ break; |
17836 |
-+ case GIMPLE_CALL: |
17837 |
-+ head = search_interesting_calls(head, as_a_gcall(stmt)); |
17838 |
-+ break; |
17839 |
-+ case GIMPLE_ASSIGN: |
17840 |
-+ /* !!! TODO LTO modeban nincs duplikalas a globalis valtozora, mert a tree mergek |
17841 |
-+ * utan mar nem lehet megkulonboztetni attol a globalis valtozotol, aminek a scopeja csak a file |
17842 |
-+ * igy a context nem vardecl lesz, hanem vardecl_filenev. De execute-ban kiirja, ha hianyzik a hash tablabol |
17843 |
-+ * IPA-ban van duplikalas. |
17844 |
-+ */ |
17845 |
-+ head = search_interesting_structs_vardecls(head, as_a_gassign(stmt)); |
17846 |
-+ break; |
17847 |
-+ default: |
17848 |
-+ break; |
17849 |
-+ } |
17850 |
++ if (is_gimple_call(stmt)) |
17851 |
++ is_leaf = false; |
17852 |
++ |
17853 |
++ // gimple match: align 8 built-in BUILT_IN_NORMAL:BUILT_IN_ALLOCA attributes <tree_list 0xb7576450> |
17854 |
++ if (!is_alloca(stmt)) |
17855 |
++ continue; |
17856 |
++ |
17857 |
++ // 2. insert stack overflow check before each __builtin_alloca call |
17858 |
++ stackleak_check_alloca(&gsi); |
17859 |
++ |
17860 |
++ // 3. insert track call after each __builtin_alloca call |
17861 |
++ stackleak_add_instrumentation(&gsi, true); |
17862 |
++ if (bb == entry_bb) |
17863 |
++ prologue_instrumented = true; |
17864 |
+ } |
17865 |
+ } |
17866 |
+ |
17867 |
-+ handle_interesting_stmt(visited, head); |
17868 |
-+ free_interesting_stmts(head); |
17869 |
-+} |
17870 |
++ // special cases for some bad linux code: taking the address of static inline functions will materialize them |
17871 |
++ // but we mustn't instrument some of them as the resulting stack alignment required by the function call ABI |
17872 |
++ // will break other assumptions regarding the expected (but not otherwise enforced) register clobbering ABI. |
17873 |
++ // case in point: native_save_fl on amd64 when optimized for size clobbers rdx if it were instrumented here. |
17874 |
++ if (is_leaf && !TREE_PUBLIC(current_function_decl) && DECL_DECLARED_INLINE_P(current_function_decl)) |
17875 |
++ return 0; |
17876 |
++ if (is_leaf && !strncmp(IDENTIFIER_POINTER(DECL_NAME(current_function_decl)), "_paravirt_", 10)) |
17877 |
++ return 0; |
17878 |
+ |
17879 |
-+static struct visited *create_visited(void) |
17880 |
-+{ |
17881 |
-+ struct visited *new_node; |
17882 |
++ // 4. insert track call at the beginning |
17883 |
++ if (!prologue_instrumented) { |
17884 |
++ gimple_stmt_iterator gsi; |
17885 |
+ |
17886 |
-+ new_node = (struct visited *)xmalloc(sizeof(*new_node)); |
17887 |
-+ new_node->stmts = pointer_set_create(); |
17888 |
-+ new_node->my_stmts = pointer_set_create(); |
17889 |
-+ new_node->skip_expr_casts = pointer_set_create(); |
17890 |
-+ new_node->no_cast_check = pointer_set_create(); |
17891 |
-+ return new_node; |
17892 |
++ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
17893 |
++ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
17894 |
++ if (!single_pred_p(bb)) { |
17895 |
++// gcc_assert(bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP)); |
17896 |
++ split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
17897 |
++ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
17898 |
++ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
17899 |
++ } |
17900 |
++ gsi = gsi_after_labels(bb); |
17901 |
++ stackleak_add_instrumentation(&gsi, false); |
17902 |
++ } |
17903 |
++ |
17904 |
++ return 0; |
17905 |
+} |
17906 |
+ |
17907 |
-+static void free_visited(struct visited *visited) |
17908 |
++static unsigned int stackleak_final_execute(void) |
17909 |
+{ |
17910 |
-+ pointer_set_destroy(visited->stmts); |
17911 |
-+ pointer_set_destroy(visited->my_stmts); |
17912 |
-+ pointer_set_destroy(visited->skip_expr_casts); |
17913 |
-+ pointer_set_destroy(visited->no_cast_check); |
17914 |
++ rtx_insn *insn, *next; |
17915 |
+ |
17916 |
-+ free(visited); |
17917 |
-+} |
17918 |
++ if (cfun->calls_alloca) |
17919 |
++ return 0; |
17920 |
+ |
17921 |
-+// Remove the size_overflow asm stmt and create an assignment from the input and output of the asm |
17922 |
-+static void replace_size_overflow_asm_with_assign(gasm *asm_stmt, tree lhs, tree rhs) |
17923 |
-+{ |
17924 |
-+ gassign *assign; |
17925 |
-+ gimple_stmt_iterator gsi; |
17926 |
++ // keep calls only if function frame is big enough |
17927 |
++ if (get_frame_size() >= track_frame_size) |
17928 |
++ return 0; |
17929 |
+ |
17930 |
-+ // already removed |
17931 |
-+ if (gimple_bb(asm_stmt) == NULL) |
17932 |
-+ return; |
17933 |
-+ gsi = gsi_for_stmt(asm_stmt); |
17934 |
++ // 1. find pax_track_stack calls |
17935 |
++ for (insn = get_insns(); insn; insn = next) { |
17936 |
++ // rtl match: (call_insn 8 7 9 3 (call (mem (symbol_ref ("pax_track_stack") [flags 0x41] <function_decl 0xb7470e80 pax_track_stack>) [0 S1 A8]) (4)) -1 (nil) (nil)) |
17937 |
++ rtx body; |
17938 |
+ |
17939 |
-+ assign = gimple_build_assign(lhs, rhs); |
17940 |
-+ gsi_insert_before(&gsi, assign, GSI_SAME_STMT); |
17941 |
-+ SSA_NAME_DEF_STMT(lhs) = assign; |
17942 |
++ next = NEXT_INSN(insn); |
17943 |
++ if (!CALL_P(insn)) |
17944 |
++ continue; |
17945 |
++ body = PATTERN(insn); |
17946 |
++ if (GET_CODE(body) != CALL) |
17947 |
++ continue; |
17948 |
++ body = XEXP(body, 0); |
17949 |
++ if (GET_CODE(body) != MEM) |
17950 |
++ continue; |
17951 |
++ body = XEXP(body, 0); |
17952 |
++ if (GET_CODE(body) != SYMBOL_REF) |
17953 |
++ continue; |
17954 |
++// if (strcmp(XSTR(body, 0), track_function)) |
17955 |
++ if (SYMBOL_REF_DECL(body) != track_function_decl) |
17956 |
++ continue; |
17957 |
++// warning(0, "track_frame_size: %d %ld %d", cfun->calls_alloca, get_frame_size(), track_frame_size); |
17958 |
++ // 2. delete call |
17959 |
++ delete_insn_and_edges(insn); |
17960 |
++#if BUILDING_GCC_VERSION >= 4007 |
17961 |
++ if (GET_CODE(next) == NOTE && NOTE_KIND(next) == NOTE_INSN_CALL_ARG_LOCATION) { |
17962 |
++ insn = next; |
17963 |
++ next = NEXT_INSN(insn); |
17964 |
++ delete_insn_and_edges(insn); |
17965 |
++ } |
17966 |
++#endif |
17967 |
++ } |
17968 |
+ |
17969 |
-+ gsi_remove(&gsi, true); |
17970 |
++// print_simple_rtl(stderr, get_insns()); |
17971 |
++// print_rtl(stderr, get_insns()); |
17972 |
++// warning(0, "track_frame_size: %d %ld %d", cfun->calls_alloca, get_frame_size(), track_frame_size); |
17973 |
++ |
17974 |
++ return 0; |
17975 |
+} |
17976 |
+ |
17977 |
-+// Replace our asm stmts with assignments (they are no longer needed and may interfere with later optimizations) |
17978 |
-+static void remove_size_overflow_asm(gimple stmt) |
17979 |
++static bool stackleak_track_stack_gate(void) |
17980 |
+{ |
17981 |
-+ gimple_stmt_iterator gsi; |
17982 |
-+ tree input, output; |
17983 |
++ tree section; |
17984 |
+ |
17985 |
-+ if (!is_size_overflow_asm(stmt)) |
17986 |
-+ return; |
17987 |
++ if (ix86_cmodel != CM_KERNEL) |
17988 |
++ return false; |
17989 |
+ |
17990 |
-+ if (gimple_asm_noutputs(as_a_gasm(stmt)) == 0) { |
17991 |
-+ gsi = gsi_for_stmt(stmt); |
17992 |
++ section = lookup_attribute("section", DECL_ATTRIBUTES(current_function_decl)); |
17993 |
++ if (section && TREE_VALUE(section)) { |
17994 |
++ section = TREE_VALUE(TREE_VALUE(section)); |
17995 |
+ |
17996 |
-+ ipa_remove_stmt_references(cgraph_get_node(current_function_decl), stmt); |
17997 |
-+ gsi_remove(&gsi, true); |
17998 |
-+ return; |
17999 |
++ if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10)) |
18000 |
++ return false; |
18001 |
++ if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13)) |
18002 |
++ return false; |
18003 |
++ if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13)) |
18004 |
++ return false; |
18005 |
++ if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13)) |
18006 |
++ return false; |
18007 |
+ } |
18008 |
+ |
18009 |
-+ input = gimple_asm_input_op(as_a_gasm(stmt), 0); |
18010 |
-+ output = gimple_asm_output_op(as_a_gasm(stmt), 0); |
18011 |
-+ replace_size_overflow_asm_with_assign(as_a_gasm(stmt), TREE_VALUE(output), TREE_VALUE(input)); |
18012 |
++ return track_frame_size >= 0; |
18013 |
+} |
18014 |
+ |
18015 |
-+static void remove_all_size_overflow_asm(void) |
18016 |
++static void stackleak_start_unit(void *gcc_data, void *user_data) |
18017 |
+{ |
18018 |
-+ basic_block bb; |
18019 |
++ tree fntype; |
18020 |
+ |
18021 |
-+ FOR_EACH_BB_FN(bb, cfun) { |
18022 |
-+ gimple_stmt_iterator si; |
18023 |
++ // void pax_track_stack(void) |
18024 |
++ fntype = build_function_type_list(void_type_node, NULL_TREE); |
18025 |
++ track_function_decl = build_fn_decl(track_function, fntype); |
18026 |
++ DECL_ASSEMBLER_NAME(track_function_decl); // for LTO |
18027 |
++ TREE_PUBLIC(track_function_decl) = 1; |
18028 |
++ TREE_USED(track_function_decl) = 1; |
18029 |
++ DECL_EXTERNAL(track_function_decl) = 1; |
18030 |
++ DECL_ARTIFICIAL(track_function_decl) = 1; |
18031 |
++ DECL_PRESERVE_P(track_function_decl) = 1; |
18032 |
+ |
18033 |
-+ for (si = gsi_start_bb(bb); !gsi_end_p(si); gsi_next(&si)) |
18034 |
-+ remove_size_overflow_asm(gsi_stmt(si)); |
18035 |
-+ } |
18036 |
++ // void pax_check_alloca(unsigned long) |
18037 |
++ fntype = build_function_type_list(void_type_node, long_unsigned_type_node, NULL_TREE); |
18038 |
++ check_function_decl = build_fn_decl(check_function, fntype); |
18039 |
++ DECL_ASSEMBLER_NAME(check_function_decl); // for LTO |
18040 |
++ TREE_PUBLIC(check_function_decl) = 1; |
18041 |
++ TREE_USED(check_function_decl) = 1; |
18042 |
++ DECL_EXTERNAL(check_function_decl) = 1; |
18043 |
++ DECL_ARTIFICIAL(check_function_decl) = 1; |
18044 |
++ DECL_PRESERVE_P(check_function_decl) = 1; |
18045 |
+} |
18046 |
+ |
18047 |
-+unsigned int size_overflow_function_transform(struct cgraph_node *node __unused) |
18048 |
++static bool stackleak_tree_instrument_gate(void) |
18049 |
+{ |
18050 |
-+ struct visited *visited; |
18051 |
++ return stackleak_track_stack_gate(); |
18052 |
++} |
18053 |
+ |
18054 |
-+#if BUILDING_GCC_VERSION >= 4008 |
18055 |
-+ if (dump_file) { |
18056 |
-+ fprintf(dump_file, "BEFORE TRANSFORM -------------------------\n"); |
18057 |
-+ size_overflow_dump_function(dump_file, node); |
18058 |
-+ } |
18059 |
-+#endif |
18060 |
-+ visited = create_visited(); |
18061 |
-+ set_dominance_info(); |
18062 |
++#define PASS_NAME stackleak_tree_instrument |
18063 |
++#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg |
18064 |
++#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts |
18065 |
++#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_update_ssa | TODO_rebuild_cgraph_edges |
18066 |
++#include "gcc-generate-gimple-pass.h" |
18067 |
+ |
18068 |
-+ search_interesting_stmts(visited); |
18069 |
++static bool stackleak_final_gate(void) |
18070 |
++{ |
18071 |
++ return stackleak_track_stack_gate(); |
18072 |
++} |
18073 |
+ |
18074 |
-+ remove_all_size_overflow_asm(); |
18075 |
++#define PASS_NAME stackleak_final |
18076 |
++#define TODO_FLAGS_FINISH TODO_dump_func |
18077 |
++#include "gcc-generate-rtl-pass.h" |
18078 |
+ |
18079 |
-+ unset_dominance_info(); |
18080 |
-+ free_visited(visited); |
18081 |
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
18082 |
++{ |
18083 |
++ const char * const plugin_name = plugin_info->base_name; |
18084 |
++ const int argc = plugin_info->argc; |
18085 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
18086 |
++ int i; |
18087 |
++ struct register_pass_info stackleak_tree_instrument_pass_info; |
18088 |
++ struct register_pass_info stackleak_final_pass_info; |
18089 |
++ static const struct ggc_root_tab gt_ggc_r_gt_stackleak[] = { |
18090 |
++ { |
18091 |
++ .base = &track_function_decl, |
18092 |
++ .nelt = 1, |
18093 |
++ .stride = sizeof(track_function_decl), |
18094 |
++ .cb = >_ggc_mx_tree_node, |
18095 |
++ .pchw = >_pch_nx_tree_node |
18096 |
++ }, |
18097 |
++ { |
18098 |
++ .base = &check_function_decl, |
18099 |
++ .nelt = 1, |
18100 |
++ .stride = sizeof(check_function_decl), |
18101 |
++ .cb = >_ggc_mx_tree_node, |
18102 |
++ .pchw = >_pch_nx_tree_node |
18103 |
++ }, |
18104 |
++ LAST_GGC_ROOT_TAB |
18105 |
++ }; |
18106 |
+ |
18107 |
-+#if BUILDING_GCC_VERSION >= 4008 |
18108 |
-+ if (dump_file) { |
18109 |
-+ fprintf(dump_file, "AFTER TRANSFORM -------------------------\n"); |
18110 |
-+ size_overflow_dump_function(dump_file, node); |
18111 |
++ stackleak_tree_instrument_pass_info.pass = make_stackleak_tree_instrument_pass(); |
18112 |
++// stackleak_tree_instrument_pass_info.reference_pass_name = "tree_profile"; |
18113 |
++ stackleak_tree_instrument_pass_info.reference_pass_name = "optimized"; |
18114 |
++ stackleak_tree_instrument_pass_info.ref_pass_instance_number = 1; |
18115 |
++ stackleak_tree_instrument_pass_info.pos_op = PASS_POS_INSERT_BEFORE; |
18116 |
++ |
18117 |
++ stackleak_final_pass_info.pass = make_stackleak_final_pass(); |
18118 |
++ stackleak_final_pass_info.reference_pass_name = "final"; |
18119 |
++ stackleak_final_pass_info.ref_pass_instance_number = 1; |
18120 |
++ stackleak_final_pass_info.pos_op = PASS_POS_INSERT_BEFORE; |
18121 |
++ |
18122 |
++ if (!plugin_default_version_check(version, &gcc_version)) { |
18123 |
++ error(G_("incompatible gcc/plugin versions")); |
18124 |
++ return 1; |
18125 |
+ } |
18126 |
-+#endif |
18127 |
-+ return TODO_dump_func | TODO_verify_stmts | TODO_remove_unused_locals | TODO_update_ssa_no_phi | TODO_ggc_collect | TODO_verify_flow; |
18128 |
++ |
18129 |
++ register_callback(plugin_name, PLUGIN_INFO, NULL, &stackleak_plugin_info); |
18130 |
++ |
18131 |
++ for (i = 0; i < argc; ++i) { |
18132 |
++ if (!strcmp(argv[i].key, "track-lowest-sp")) { |
18133 |
++ if (!argv[i].value) { |
18134 |
++ error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
18135 |
++ continue; |
18136 |
++ } |
18137 |
++ track_frame_size = atoi(argv[i].value); |
18138 |
++ if (argv[i].value[0] < '0' || argv[i].value[0] > '9' || track_frame_size < 0) |
18139 |
++ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); |
18140 |
++ continue; |
18141 |
++ } |
18142 |
++ if (!strcmp(argv[i].key, "initialize-locals")) { |
18143 |
++ if (argv[i].value) { |
18144 |
++ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); |
18145 |
++ continue; |
18146 |
++ } |
18147 |
++ init_locals = true; |
18148 |
++ continue; |
18149 |
++ } |
18150 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
18151 |
++ } |
18152 |
++ |
18153 |
++ register_callback(plugin_name, PLUGIN_START_UNIT, &stackleak_start_unit, NULL); |
18154 |
++ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_stackleak); |
18155 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_tree_instrument_pass_info); |
18156 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_final_pass_info); |
18157 |
++ |
18158 |
++ return 0; |
18159 |
+} |
18160 |
-diff --git a/tools/gcc/size_overflow_plugin/size_overflow_transform_core.c b/tools/gcc/size_overflow_plugin/size_overflow_transform_core.c |
18161 |
+diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c |
18162 |
new file mode 100644 |
18163 |
-index 0000000..062204a |
18164 |
+index 0000000..d7596e6 |
18165 |
--- /dev/null |
18166 |
-+++ b/tools/gcc/size_overflow_plugin/size_overflow_transform_core.c |
18167 |
-@@ -0,0 +1,1025 @@ |
18168 |
++++ b/scripts/gcc-plugins/structleak_plugin.c |
18169 |
+@@ -0,0 +1,239 @@ |
18170 |
+/* |
18171 |
-+ * Copyright 2011-2016 by Emese Revfy <re.emese@×××××.com> |
18172 |
-+ * Licensed under the GPL v2, or (at your option) v3 |
18173 |
++ * Copyright 2013-2016 by PaX Team <pageexec@××××××××.hu> |
18174 |
++ * Licensed under the GPL v2 |
18175 |
+ * |
18176 |
-+ * Homepage: |
18177 |
-+ * https://github.com/ephox-gcc-plugins/size_overflow |
18178 |
++ * Note: the choice of the license means that the compilation process is |
18179 |
++ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
18180 |
++ * but for the kernel it doesn't matter since it doesn't link against |
18181 |
++ * any of the gcc libraries |
18182 |
+ * |
18183 |
-+ * Documentation: |
18184 |
-+ * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 |
18185 |
++ * gcc plugin to forcibly initialize certain local variables that could |
18186 |
++ * otherwise leak kernel stack to userland if they aren't properly initialized |
18187 |
++ * by later code |
18188 |
+ * |
18189 |
-+ * This plugin recomputes expressions of function arguments marked by a size_overflow attribute |
18190 |
-+ * with double integer precision (DImode/TImode for 32/64 bit integer types). |
18191 |
-+ * The recomputed argument is checked against TYPE_MAX and an event is logged on overflow and the triggering process is killed. |
18192 |
++ * Homepage: http://pax.grsecurity.net/ |
18193 |
+ * |
18194 |
+ * Usage: |
18195 |
-+ * $ make |
18196 |
-+ * $ make run |
18197 |
++ * $ # for 4.5/4.6/C based 4.7 |
18198 |
++ * $ gcc -I`gcc -print-file-name=plugin`/include -I`gcc -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o structleak_plugin.so structleak_plugin.c |
18199 |
++ * $ # for C++ based 4.7/4.8+ |
18200 |
++ * $ g++ -I`g++ -print-file-name=plugin`/include -I`g++ -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o structleak_plugin.so structleak_plugin.c |
18201 |
++ * $ gcc -fplugin=./structleak_plugin.so test.c -O2 |
18202 |
++ * |
18203 |
++ * TODO: eliminate redundant initializers |
18204 |
++ * increase type coverage |
18205 |
+ */ |
18206 |
+ |
18207 |
-+#include "size_overflow.h" |
18208 |
++#include "gcc-common.h" |
18209 |
+ |
18210 |
-+#define MIN_CHECK true |
18211 |
-+#define MAX_CHECK false |
18212 |
++// unused C type flag in all versions 4.5-6 |
18213 |
++#define TYPE_USERSPACE(TYPE) TYPE_LANG_FLAG_5(TYPE) |
18214 |
+ |
18215 |
-+unsigned int call_count = 0; |
18216 |
++int plugin_is_GPL_compatible; |
18217 |
+ |
18218 |
-+tree get_size_overflow_type(struct visited *visited, const_gimple stmt, const_tree node) |
18219 |
-+{ |
18220 |
-+ const_tree type; |
18221 |
-+ tree new_type; |
18222 |
++static struct plugin_info structleak_plugin_info = { |
18223 |
++ .version = "201602181345", |
18224 |
++ .help = "disable\tdo not activate plugin\n", |
18225 |
++}; |
18226 |
+ |
18227 |
-+ gcc_assert(node != NULL_TREE); |
18228 |
++static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
18229 |
++{ |
18230 |
++ *no_add_attrs = true; |
18231 |
+ |
18232 |
-+ type = TREE_TYPE(node); |
18233 |
++ // check for types? for now accept everything linux has to offer |
18234 |
++ if (TREE_CODE(*node) != FIELD_DECL) |
18235 |
++ return NULL_TREE; |
18236 |
+ |
18237 |
-+ if (pointer_set_contains(visited->my_stmts, stmt)) |
18238 |
-+ return TREE_TYPE(node); |
18239 |
++ *no_add_attrs = false; |
18240 |
++ return NULL_TREE; |
18241 |
++} |
18242 |
+ |
18243 |
-+ switch (TYPE_MODE(type)) { |
18244 |
-+ case QImode: |
18245 |
-+ case HImode: |
18246 |
-+ new_type = size_overflow_type_SI; |
18247 |
-+ break; |
18248 |
-+ case SImode: |
18249 |
-+ new_type = size_overflow_type_DI; |
18250 |
-+ break; |
18251 |
-+ case DImode: |
18252 |
-+ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode)) |
18253 |
-+ new_type = TYPE_UNSIGNED(type) ? unsigned_intDI_type_node : intDI_type_node; |
18254 |
-+ else |
18255 |
-+ new_type = size_overflow_type_TI; |
18256 |
-+ break; |
18257 |
-+ case TImode: |
18258 |
-+ gcc_assert(!TYPE_UNSIGNED(type)); |
18259 |
-+ new_type = size_overflow_type_TI; |
18260 |
-+ break; |
18261 |
-+ default: |
18262 |
-+ debug_tree(node); |
18263 |
-+ error("%s: unsupported gcc configuration (%qE).", __func__, current_function_decl); |
18264 |
-+ gcc_unreachable(); |
18265 |
-+ } |
18266 |
++static struct attribute_spec user_attr = { |
18267 |
++ .name = "user", |
18268 |
++ .min_length = 0, |
18269 |
++ .max_length = 0, |
18270 |
++ .decl_required = false, |
18271 |
++ .type_required = false, |
18272 |
++ .function_type_required = false, |
18273 |
++ .handler = handle_user_attribute, |
18274 |
++#if BUILDING_GCC_VERSION >= 4007 |
18275 |
++ .affects_type_identity = true |
18276 |
++#endif |
18277 |
++}; |
18278 |
+ |
18279 |
-+ if (TYPE_QUALS(type) != 0) |
18280 |
-+ return build_qualified_type(new_type, TYPE_QUALS(type)); |
18281 |
-+ return new_type; |
18282 |
++static void register_attributes(void *event_data, void *data) |
18283 |
++{ |
18284 |
++ register_attribute(&user_attr); |
18285 |
++// register_attribute(&force_attr); |
18286 |
+} |
18287 |
+ |
18288 |
-+tree cast_to_new_size_overflow_type(struct visited *visited, gimple stmt, tree rhs, tree size_overflow_type, bool before) |
18289 |
++static tree get_field_type(tree field) |
18290 |
+{ |
18291 |
-+ gimple_stmt_iterator gsi; |
18292 |
-+ gimple new_stmt; |
18293 |
-+ |
18294 |
-+ if (rhs == NULL_TREE) |
18295 |
-+ return NULL_TREE; |
18296 |
-+ |
18297 |
-+ gsi = gsi_for_stmt(stmt); |
18298 |
-+ new_stmt = build_cast_stmt(visited, size_overflow_type, rhs, CREATE_NEW_VAR, &gsi, before, false); |
18299 |
-+ if (gimple_assign_cast_p(new_stmt)) |
18300 |
-+ gimple_assign_set_rhs_code(new_stmt, CONVERT_EXPR); |
18301 |
-+ pointer_set_insert(visited->my_stmts, new_stmt); |
18302 |
-+ |
18303 |
-+ return get_lhs(new_stmt); |
18304 |
++ return strip_array_types(TREE_TYPE(field)); |
18305 |
+} |
18306 |
+ |
18307 |
-+tree create_assign(struct visited *visited, gimple oldstmt, tree rhs1, bool before) |
18308 |
++static bool is_userspace_type(tree type) |
18309 |
+{ |
18310 |
-+ tree lhs, dst_type; |
18311 |
-+ gimple_stmt_iterator gsi; |
18312 |
-+ |
18313 |
-+ if (rhs1 == NULL_TREE) { |
18314 |
-+ debug_gimple_stmt(oldstmt); |
18315 |
-+ error("%s: rhs1 is NULL_TREE", __func__); |
18316 |
-+ gcc_unreachable(); |
18317 |
-+ } |
18318 |
-+ |
18319 |
-+ switch (gimple_code(oldstmt)) { |
18320 |
-+ case GIMPLE_ASM: |
18321 |
-+ lhs = rhs1; |
18322 |
-+ break; |
18323 |
-+ case GIMPLE_CALL: |
18324 |
-+ case GIMPLE_ASSIGN: |
18325 |
-+ lhs = gimple_get_lhs(oldstmt); |
18326 |
-+ break; |
18327 |
-+ default: |
18328 |
-+ debug_gimple_stmt(oldstmt); |
18329 |
-+ gcc_unreachable(); |
18330 |
-+ } |
18331 |
-+ |
18332 |
-+ gsi = gsi_for_stmt(oldstmt); |
18333 |
-+ pointer_set_insert(visited->stmts, oldstmt); |
18334 |
-+ if (lookup_stmt_eh_lp(oldstmt) != 0) { |
18335 |
-+ basic_block next_bb, cur_bb; |
18336 |
-+ const_edge e; |
18337 |
-+ |
18338 |
-+ gcc_assert(before == false); |
18339 |
-+ gcc_assert(stmt_can_throw_internal(oldstmt)); |
18340 |
-+ gcc_assert(gimple_code(oldstmt) == GIMPLE_CALL); |
18341 |
-+ gcc_assert(!gsi_end_p(gsi)); |
18342 |
++ tree field; |
18343 |
+ |
18344 |
-+ cur_bb = gimple_bb(oldstmt); |
18345 |
-+ next_bb = cur_bb->next_bb; |
18346 |
-+ e = find_edge(cur_bb, next_bb); |
18347 |
-+ gcc_assert(e != NULL); |
18348 |
-+ gcc_assert(e->flags & EDGE_FALLTHRU); |
18349 |
++ for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { |
18350 |
++ tree fieldtype = get_field_type(field); |
18351 |
++ enum tree_code code = TREE_CODE(fieldtype); |
18352 |
+ |
18353 |
-+ gsi = gsi_after_labels(next_bb); |
18354 |
-+ gcc_assert(!gsi_end_p(gsi)); |
18355 |
++ if (code == RECORD_TYPE || code == UNION_TYPE) |
18356 |
++ if (is_userspace_type(fieldtype)) |
18357 |
++ return true; |
18358 |
+ |
18359 |
-+ before = true; |
18360 |
-+ oldstmt = gsi_stmt(gsi); |
18361 |
++ if (lookup_attribute("user", DECL_ATTRIBUTES(field))) |
18362 |
++ return true; |
18363 |
+ } |
18364 |
-+ |
18365 |
-+ if (is_gimple_constant(rhs1) && TREE_CODE_CLASS(gimple_assign_rhs_code(oldstmt)) == tcc_comparison) |
18366 |
-+ dst_type = get_size_overflow_type(visited, oldstmt, rhs1); |
18367 |
-+ else |
18368 |
-+ dst_type = get_size_overflow_type(visited, oldstmt, lhs); |
18369 |
-+ |
18370 |
-+ if (is_gimple_constant(rhs1)) |
18371 |
-+ return cast_a_tree(dst_type, rhs1); |
18372 |
-+ return cast_to_new_size_overflow_type(visited, oldstmt, rhs1, dst_type, before); |
18373 |
++ return false; |
18374 |
+} |
18375 |
+ |
18376 |
-+tree dup_assign(struct visited *visited, gassign *oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) |
18377 |
++static void finish_type(void *event_data, void *data) |
18378 |
+{ |
18379 |
-+ gassign *stmt; |
18380 |
-+ gimple_stmt_iterator gsi; |
18381 |
-+ tree size_overflow_type, new_var, lhs = gimple_assign_lhs(oldstmt); |
18382 |
-+ |
18383 |
-+ if (pointer_set_contains(visited->my_stmts, oldstmt)) |
18384 |
-+ return lhs; |
18385 |
-+ |
18386 |
-+ if (gimple_num_ops(oldstmt) != 4 && rhs1 == NULL_TREE) { |
18387 |
-+ rhs1 = gimple_assign_rhs1(oldstmt); |
18388 |
-+ rhs1 = create_assign(visited, oldstmt, rhs1, BEFORE_STMT); |
18389 |
-+ } |
18390 |
-+ if (gimple_num_ops(oldstmt) == 3 && rhs2 == NULL_TREE) { |
18391 |
-+ rhs2 = gimple_assign_rhs2(oldstmt); |
18392 |
-+ rhs2 = create_assign(visited, oldstmt, rhs2, BEFORE_STMT); |
18393 |
-+ } |
18394 |
-+ |
18395 |
-+ stmt = as_a_gassign(gimple_copy(oldstmt)); |
18396 |
-+ gimple_set_location(stmt, gimple_location(oldstmt)); |
18397 |
-+ pointer_set_insert(visited->my_stmts, stmt); |
18398 |
-+ |
18399 |
-+ if (gimple_assign_rhs_code(oldstmt) == WIDEN_MULT_EXPR) |
18400 |
-+ gimple_assign_set_rhs_code(stmt, MULT_EXPR); |
18401 |
-+ |
18402 |
-+ size_overflow_type = get_size_overflow_type(visited, oldstmt, node); |
18403 |
-+ |
18404 |
-+ new_var = create_new_var(size_overflow_type); |
18405 |
-+ new_var = make_ssa_name(new_var, stmt); |
18406 |
-+ gimple_assign_set_lhs(stmt, new_var); |
18407 |
++ tree type = (tree)event_data; |
18408 |
+ |
18409 |
-+ if (rhs1 != NULL_TREE) |
18410 |
-+ gimple_assign_set_rhs1(stmt, rhs1); |
18411 |
++ if (type == NULL_TREE || type == error_mark_node) |
18412 |
++ return; |
18413 |
+ |
18414 |
-+ if (rhs2 != NULL_TREE) |
18415 |
-+ gimple_assign_set_rhs2(stmt, rhs2); |
18416 |
-+#if BUILDING_GCC_VERSION >= 4006 |
18417 |
-+ if (rhs3 != NULL_TREE) |
18418 |
-+ gimple_assign_set_rhs3(stmt, rhs3); |
18419 |
++#if BUILDING_GCC_VERSION >= 5000 |
18420 |
++ if (TREE_CODE(type) == ENUMERAL_TYPE) |
18421 |
++ return; |
18422 |
+#endif |
18423 |
-+ gimple_set_vuse(stmt, gimple_vuse(oldstmt)); |
18424 |
-+ gimple_set_vdef(stmt, gimple_vdef(oldstmt)); |
18425 |
+ |
18426 |
-+ gsi = gsi_for_stmt(oldstmt); |
18427 |
-+ gsi_insert_after(&gsi, stmt, GSI_SAME_STMT); |
18428 |
-+ update_stmt(stmt); |
18429 |
-+ pointer_set_insert(visited->stmts, oldstmt); |
18430 |
-+ return gimple_assign_lhs(stmt); |
18431 |
++ if (TYPE_USERSPACE(type)) |
18432 |
++ return; |
18433 |
++ |
18434 |
++ if (is_userspace_type(type)) |
18435 |
++ TYPE_USERSPACE(type) = 1; |
18436 |
+} |
18437 |
+ |
18438 |
-+static tree cast_parm_decl(struct visited *visited, tree phi_ssa_name, tree arg, tree size_overflow_type, basic_block bb) |
18439 |
++static void initialize(tree var) |
18440 |
+{ |
18441 |
-+ const_gimple assign; |
18442 |
++ basic_block bb; |
18443 |
+ gimple_stmt_iterator gsi; |
18444 |
-+ basic_block first_bb; |
18445 |
++ tree initializer; |
18446 |
++ gimple init_stmt; |
18447 |
+ |
18448 |
-+ gcc_assert(SSA_NAME_IS_DEFAULT_DEF(arg)); |
18449 |
++ // this is the original entry bb before the forced split |
18450 |
++ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
18451 |
+ |
18452 |
-+ if (bb->index == 0) { |
18453 |
-+ first_bb = split_block_after_labels(ENTRY_BLOCK_PTR_FOR_FN(cfun))->dest; |
18454 |
-+ gcc_assert(dom_info_available_p(CDI_DOMINATORS)); |
18455 |
-+ set_immediate_dominator(CDI_DOMINATORS, first_bb, ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
18456 |
-+ bb = first_bb; |
18457 |
-+ } |
18458 |
++ // first check if the variable is already initialized, warn otherwise |
18459 |
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
18460 |
++ gimple stmt = gsi_stmt(gsi); |
18461 |
++ tree rhs1; |
18462 |
+ |
18463 |
-+ gsi = gsi_after_labels(bb); |
18464 |
-+ assign = build_cast_stmt(visited, size_overflow_type, arg, phi_ssa_name, &gsi, BEFORE_STMT, false); |
18465 |
-+ pointer_set_insert(visited->my_stmts, assign); |
18466 |
-+ return get_lhs(assign); |
18467 |
-+} |
18468 |
++ // we're looking for an assignment of a single rhs... |
18469 |
++ if (!gimple_assign_single_p(stmt)) |
18470 |
++ continue; |
18471 |
++ rhs1 = gimple_assign_rhs1(stmt); |
18472 |
++#if BUILDING_GCC_VERSION >= 4007 |
18473 |
++ // ... of a non-clobbering expression... |
18474 |
++ if (TREE_CLOBBER_P(rhs1)) |
18475 |
++ continue; |
18476 |
++#endif |
18477 |
++ // ... to our variable... |
18478 |
++ if (gimple_get_lhs(stmt) != var) |
18479 |
++ continue; |
18480 |
++ // if it's an initializer then we're good |
18481 |
++ if (TREE_CODE(rhs1) == CONSTRUCTOR) |
18482 |
++ return; |
18483 |
++ } |
18484 |
+ |
18485 |
-+static tree use_phi_ssa_name(struct visited *visited, tree ssa_name_var, tree new_arg) |
18486 |
-+{ |
18487 |
-+ gimple_stmt_iterator gsi; |
18488 |
-+ const_gimple assign; |
18489 |
-+ gimple def_stmt = get_def_stmt(new_arg); |
18490 |
++ // these aren't the 0days you're looking for |
18491 |
++// inform(DECL_SOURCE_LOCATION(var), "userspace variable will be forcibly initialized"); |
18492 |
+ |
18493 |
-+ if (gimple_code(def_stmt) == GIMPLE_PHI) { |
18494 |
-+ gsi = gsi_after_labels(gimple_bb(def_stmt)); |
18495 |
-+ assign = build_cast_stmt(visited, TREE_TYPE(new_arg), new_arg, ssa_name_var, &gsi, BEFORE_STMT, true); |
18496 |
-+ } else { |
18497 |
-+ gsi = gsi_for_stmt(def_stmt); |
18498 |
-+ assign = build_cast_stmt(visited, TREE_TYPE(new_arg), new_arg, ssa_name_var, &gsi, AFTER_STMT, true); |
18499 |
-+ } |
18500 |
++ // build the initializer expression |
18501 |
++ initializer = build_constructor(TREE_TYPE(var), NULL); |
18502 |
+ |
18503 |
-+ pointer_set_insert(visited->my_stmts, assign); |
18504 |
-+ return get_lhs(assign); |
18505 |
++ // build the initializer stmt |
18506 |
++ init_stmt = gimple_build_assign(var, initializer); |
18507 |
++ gsi = gsi_after_labels(single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
18508 |
++ gsi_insert_before(&gsi, init_stmt, GSI_NEW_STMT); |
18509 |
++ update_stmt(init_stmt); |
18510 |
+} |
18511 |
+ |
18512 |
-+static tree cast_visited_phi_arg(struct visited *visited, tree ssa_name_var, tree arg, tree size_overflow_type) |
18513 |
++static unsigned int structleak_execute(void) |
18514 |
+{ |
18515 |
+ basic_block bb; |
18516 |
-+ gimple_stmt_iterator gsi; |
18517 |
-+ const_gimple def_stmt; |
18518 |
-+ const_gimple assign; |
18519 |
-+ |
18520 |
-+ def_stmt = get_def_stmt(arg); |
18521 |
-+ bb = gimple_bb(def_stmt); |
18522 |
-+ gcc_assert(bb->index != 0); |
18523 |
-+ gsi = gsi_after_labels(bb); |
18524 |
-+ |
18525 |
-+ assign = build_cast_stmt(visited, size_overflow_type, arg, ssa_name_var, &gsi, BEFORE_STMT, false); |
18526 |
-+ pointer_set_insert(visited->my_stmts, assign); |
18527 |
-+ return get_lhs(assign); |
18528 |
-+} |
18529 |
++ unsigned int ret = 0; |
18530 |
++ tree var; |
18531 |
++ unsigned int i; |
18532 |
+ |
18533 |
-+static tree create_new_phi_arg(struct visited *visited, tree ssa_name_var, tree new_arg, gphi *oldstmt, unsigned int i) |
18534 |
-+{ |
18535 |
-+ tree size_overflow_type; |
18536 |
-+ tree arg; |
18537 |
-+ const_gimple def_stmt; |
18538 |
++ // split the first bb where we can put the forced initializers |
18539 |
++ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
18540 |
++ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
18541 |
++ if (!single_pred_p(bb)) { |
18542 |
++// gcc_assert(bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP)); |
18543 |
++ split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
18544 |
++ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
18545 |
++ } |
18546 |
+ |
18547 |
-+ if (new_arg != NULL_TREE && is_gimple_constant(new_arg)) |
18548 |
-+ return new_arg; |
18549 |
++ // enumarate all local variables and forcibly initialize our targets |
18550 |
++ FOR_EACH_LOCAL_DECL(cfun, i, var) { |
18551 |
++ tree type = TREE_TYPE(var); |
18552 |
+ |
18553 |
-+ arg = gimple_phi_arg_def(oldstmt, i); |
18554 |
-+ def_stmt = get_def_stmt(arg); |
18555 |
-+ gcc_assert(def_stmt != NULL); |
18556 |
-+ size_overflow_type = get_size_overflow_type(visited, oldstmt, arg); |
18557 |
++ gcc_assert(DECL_P(var)); |
18558 |
++ if (!auto_var_in_fn_p(var, current_function_decl)) |
18559 |
++ continue; |
18560 |
+ |
18561 |
-+ switch (gimple_code(def_stmt)) { |
18562 |
-+ case GIMPLE_PHI: |
18563 |
-+ return cast_visited_phi_arg(visited, ssa_name_var, arg, size_overflow_type); |
18564 |
-+ case GIMPLE_NOP: { |
18565 |
-+ basic_block bb; |
18566 |
++ // only care about structure types |
18567 |
++ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) |
18568 |
++ continue; |
18569 |
+ |
18570 |
-+ bb = gimple_phi_arg_edge(oldstmt, i)->src; |
18571 |
-+ return cast_parm_decl(visited, ssa_name_var, arg, size_overflow_type, bb); |
18572 |
++ // if the type is of interest, examine the variable |
18573 |
++ if (TYPE_USERSPACE(type)) |
18574 |
++ initialize(var); |
18575 |
+ } |
18576 |
-+ case GIMPLE_ASM: { |
18577 |
-+ gimple_stmt_iterator gsi; |
18578 |
-+ const_gimple assign; |
18579 |
-+ gimple stmt = get_def_stmt(arg); |
18580 |
+ |
18581 |
-+ gsi = gsi_for_stmt(stmt); |
18582 |
-+ assign = build_cast_stmt(visited, size_overflow_type, arg, ssa_name_var, &gsi, AFTER_STMT, false); |
18583 |
-+ pointer_set_insert(visited->my_stmts, assign); |
18584 |
-+ return get_lhs(assign); |
18585 |
-+ } |
18586 |
-+ default: |
18587 |
-+ gcc_assert(new_arg != NULL_TREE); |
18588 |
-+ gcc_assert(types_compatible_p(TREE_TYPE(new_arg), size_overflow_type)); |
18589 |
-+ return use_phi_ssa_name(visited, ssa_name_var, new_arg); |
18590 |
-+ } |
18591 |
++ return ret; |
18592 |
+} |
18593 |
+ |
18594 |
-+static gphi *overflow_create_phi_node(struct visited *visited, gphi *oldstmt, tree result) |
18595 |
++#define PASS_NAME structleak |
18596 |
++#define NO_GATE |
18597 |
++#define PROPERTIES_REQUIRED PROP_cfg |
18598 |
++#define TODO_FLAGS_FINISH TODO_verify_il | TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_remove_unused_locals | TODO_update_ssa | TODO_ggc_collect | TODO_verify_flow |
18599 |
++#include "gcc-generate-gimple-pass.h" |
18600 |
++ |
18601 |
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
18602 |
+{ |
18603 |
-+ basic_block bb; |
18604 |
-+ gphi *phi; |
18605 |
-+ gimple_seq seq; |
18606 |
-+ gimple_stmt_iterator gsi = gsi_for_stmt(oldstmt); |
18607 |
++ int i; |
18608 |
++ const char * const plugin_name = plugin_info->base_name; |
18609 |
++ const int argc = plugin_info->argc; |
18610 |
++ const struct plugin_argument * const argv = plugin_info->argv; |
18611 |
++ bool enable = true; |
18612 |
++ struct register_pass_info structleak_pass_info; |
18613 |
+ |
18614 |
-+ bb = gsi_bb(gsi); |
18615 |
++ structleak_pass_info.pass = make_structleak_pass(); |
18616 |
++ structleak_pass_info.reference_pass_name = "ssa"; |
18617 |
++ structleak_pass_info.ref_pass_instance_number = 1; |
18618 |
++ structleak_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
18619 |
+ |
18620 |
-+ if (result == NULL_TREE) { |
18621 |
-+ tree old_result = gimple_phi_result(oldstmt); |
18622 |
-+ tree size_overflow_type = get_size_overflow_type(visited, oldstmt, old_result); |
18623 |
++ if (!plugin_default_version_check(version, &gcc_version)) { |
18624 |
++ error(G_("incompatible gcc/plugin versions")); |
18625 |
++ return 1; |
18626 |
++ } |
18627 |
+ |
18628 |
-+ result = create_new_var(size_overflow_type); |
18629 |
++ if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) { |
18630 |
++ inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name); |
18631 |
++ enable = false; |
18632 |
+ } |
18633 |
+ |
18634 |
-+ phi = as_a_gphi(create_phi_node(result, bb)); |
18635 |
-+ gimple_phi_set_result(phi, make_ssa_name(result, phi)); |
18636 |
-+ seq = phi_nodes(bb); |
18637 |
-+ gsi = gsi_last(seq); |
18638 |
-+ gsi_remove(&gsi, false); |
18639 |
++ for (i = 0; i < argc; ++i) { |
18640 |
++ if (!strcmp(argv[i].key, "disable")) { |
18641 |
++ enable = false; |
18642 |
++ continue; |
18643 |
++ } |
18644 |
++ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
18645 |
++ } |
18646 |
+ |
18647 |
-+ gsi = gsi_for_stmt(oldstmt); |
18648 |
-+ gsi_insert_after(&gsi, phi, GSI_NEW_STMT); |
18649 |
-+ gimple_set_bb(phi, bb); |
18650 |
-+ return phi; |
18651 |
++ register_callback(plugin_name, PLUGIN_INFO, NULL, &structleak_plugin_info); |
18652 |
++ if (enable) { |
18653 |
++ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &structleak_pass_info); |
18654 |
++ register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); |
18655 |
++ } |
18656 |
++ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
18657 |
++ |
18658 |
++ return 0; |
18659 |
+} |
18660 |
+diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh |
18661 |
+index fdebd66..a349e33 100755 |
18662 |
+--- a/scripts/headers_install.sh |
18663 |
++++ b/scripts/headers_install.sh |
18664 |
+@@ -32,6 +32,7 @@ do |
18665 |
+ FILE="$(basename "$i")" |
18666 |
+ sed -r \ |
18667 |
+ -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \ |
18668 |
++ -e 's/__intentional_overflow\([- \t,0-9]*\)//g' \ |
18669 |
+ -e 's/__attribute_const__([ \t]|$)/\1/g' \ |
18670 |
+ -e 's@^#include <linux/compiler.h>@@' \ |
18671 |
+ -e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \ |
18672 |
+diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c |
18673 |
+index 8fa81e8..a9ac144 100644 |
18674 |
+--- a/scripts/kallsyms.c |
18675 |
++++ b/scripts/kallsyms.c |
18676 |
+@@ -89,7 +89,7 @@ static inline int is_arm_mapping_symbol(const char *str) |
18677 |
+ } |
18678 |
+ |
18679 |
+ static int check_symbol_range(const char *sym, unsigned long long addr, |
18680 |
+- struct addr_range *ranges, int entries) |
18681 |
++ struct addr_range *ranges, size_t entries) |
18682 |
+ { |
18683 |
+ size_t i; |
18684 |
+ struct addr_range *ar; |
18685 |
+@@ -178,7 +178,7 @@ static int read_symbol(FILE *in, struct sym_entry *s) |
18686 |
+ } |
18687 |
+ |
18688 |
+ static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges, |
18689 |
+- int entries) |
18690 |
++ size_t entries) |
18691 |
+ { |
18692 |
+ size_t i; |
18693 |
+ struct addr_range *ar; |
18694 |
+diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h |
18695 |
+index 91ca126..5f7cad6 100644 |
18696 |
+--- a/scripts/kconfig/lkc.h |
18697 |
++++ b/scripts/kconfig/lkc.h |
18698 |
+@@ -108,7 +108,8 @@ void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); |
18699 |
+ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); |
18700 |
+ void menu_add_option(int token, char *arg); |
18701 |
+ void menu_finalize(struct menu *parent); |
18702 |
+-void menu_set_type(int type); |
18703 |
++enum symbol_type; |
18704 |
++void menu_set_type(enum symbol_type type); |
18705 |
+ |
18706 |
+ /* util.c */ |
18707 |
+ struct file *file_lookup(const char *name); |
18708 |
+@@ -123,7 +124,7 @@ struct gstr { |
18709 |
+ * when max_width is not zero long lines in string s (if any) get |
18710 |
+ * wrapped not to exceed the max_width value |
18711 |
+ */ |
18712 |
+- int max_width; |
18713 |
++ size_t max_width; |
18714 |
+ }; |
18715 |
+ struct gstr str_new(void); |
18716 |
+ void str_free(struct gstr *gs); |
18717 |
+diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c |
18718 |
+index aed678e..1a703de 100644 |
18719 |
+--- a/scripts/kconfig/menu.c |
18720 |
++++ b/scripts/kconfig/menu.c |
18721 |
+@@ -109,7 +109,7 @@ void menu_add_dep(struct expr *dep) |
18722 |
+ current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); |
18723 |
+ } |
18724 |
+ |
18725 |
+-void menu_set_type(int type) |
18726 |
++void menu_set_type(enum symbol_type type) |
18727 |
+ { |
18728 |
+ struct symbol *sym = current_entry->sym; |
18729 |
+ |
18730 |
+diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c |
18731 |
+index 25cf0c2..eb178ce 100644 |
18732 |
+--- a/scripts/kconfig/symbol.c |
18733 |
++++ b/scripts/kconfig/symbol.c |
18734 |
+@@ -956,7 +956,7 @@ const char *sym_escape_string_value(const char *in) |
18735 |
+ |
18736 |
+ struct sym_match { |
18737 |
+ struct symbol *sym; |
18738 |
+- off_t so, eo; |
18739 |
++ regoff_t so, eo; |
18740 |
+ }; |
18741 |
+ |
18742 |
+ /* Compare matched symbols as thus: |
18743 |
+@@ -978,8 +978,8 @@ static int sym_rel_comp(const void *sym1, const void *sym2) |
18744 |
+ * exactly; if this is the case, we can't decide which comes first, |
18745 |
+ * and we fallback to sorting alphabetically. |
18746 |
+ */ |
18747 |
+- exact1 = (s1->eo - s1->so) == strlen(s1->sym->name); |
18748 |
+- exact2 = (s2->eo - s2->so) == strlen(s2->sym->name); |
18749 |
++ exact1 = (s1->eo - s1->so) == (long)strlen(s1->sym->name); |
18750 |
++ exact2 = (s2->eo - s2->so) == (long)strlen(s2->sym->name); |
18751 |
+ if (exact1 && !exact2) |
18752 |
+ return -1; |
18753 |
+ if (!exact1 && exact2) |
18754 |
+diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh |
18755 |
+index ba6c34e..ea10bce 100755 |
18756 |
+--- a/scripts/link-vmlinux.sh |
18757 |
++++ b/scripts/link-vmlinux.sh |
18758 |
+@@ -179,7 +179,7 @@ else |
18759 |
+ fi; |
18760 |
+ |
18761 |
+ # final build of init/ |
18762 |
+-${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init |
18763 |
++${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}" GCC_PLUGINS_AFLAGS="${GCC_PLUGINS_AFLAGS}" |
18764 |
+ |
18765 |
+ kallsymso="" |
18766 |
+ kallsyms_vmlinux="" |
18767 |
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c |
18768 |
+index a915507..27c1b41 100644 |
18769 |
+--- a/scripts/mod/file2alias.c |
18770 |
++++ b/scripts/mod/file2alias.c |
18771 |
+@@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id, |
18772 |
+ unsigned long size, unsigned long id_size, |
18773 |
+ void *symval) |
18774 |
+ { |
18775 |
+- int i; |
18776 |
++ unsigned int i; |
18777 |
+ |
18778 |
+ if (size % id_size || size < id_size) { |
18779 |
+ fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " |
18780 |
+@@ -185,7 +185,7 @@ static void device_id_check(const char *modname, const char *device_id, |
18781 |
+ /* USB is special because the bcdDevice can be matched against a numeric range */ |
18782 |
+ /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ |
18783 |
+ static void do_usb_entry(void *symval, |
18784 |
+- unsigned int bcdDevice_initial, int bcdDevice_initial_digits, |
18785 |
++ unsigned int bcdDevice_initial, unsigned int bcdDevice_initial_digits, |
18786 |
+ unsigned char range_lo, unsigned char range_hi, |
18787 |
+ unsigned char max, struct module *mod) |
18788 |
+ { |
18789 |
+@@ -295,7 +295,7 @@ static void do_usb_entry_multi(void *symval, struct module *mod) |
18790 |
+ { |
18791 |
+ unsigned int devlo, devhi; |
18792 |
+ unsigned char chi, clo, max; |
18793 |
+- int ndigits; |
18794 |
++ unsigned int ndigits; |
18795 |
+ |
18796 |
+ DEF_FIELD(symval, usb_device_id, match_flags); |
18797 |
+ DEF_FIELD(symval, usb_device_id, idVendor); |
18798 |
+@@ -619,7 +619,7 @@ static void do_pnp_device_entry(void *symval, unsigned long size, |
18799 |
+ for (i = 0; i < count; i++) { |
18800 |
+ DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); |
18801 |
+ char acpi_id[sizeof(*id)]; |
18802 |
+- int j; |
18803 |
++ unsigned int j; |
18804 |
+ |
18805 |
+ buf_printf(&mod->dev_table_buf, |
18806 |
+ "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); |
18807 |
+@@ -648,7 +648,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size, |
18808 |
+ |
18809 |
+ for (j = 0; j < PNP_MAX_DEVICES; j++) { |
18810 |
+ const char *id = (char *)(*devs)[j].id; |
18811 |
+- int i2, j2; |
18812 |
++ unsigned int i2, j2; |
18813 |
+ int dup = 0; |
18814 |
+ |
18815 |
+ if (!id[0]) |
18816 |
+@@ -674,7 +674,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size, |
18817 |
+ /* add an individual alias for every device entry */ |
18818 |
+ if (!dup) { |
18819 |
+ char acpi_id[PNP_ID_LEN]; |
18820 |
+- int k; |
18821 |
++ unsigned int k; |
18822 |
+ |
18823 |
+ buf_printf(&mod->dev_table_buf, |
18824 |
+ "MODULE_ALIAS(\"pnp:d%s*\");\n", id); |
18825 |
+@@ -999,7 +999,7 @@ static void dmi_ascii_filter(char *d, const char *s) |
18826 |
+ static int do_dmi_entry(const char *filename, void *symval, |
18827 |
+ char *alias) |
18828 |
+ { |
18829 |
+- int i, j; |
18830 |
++ unsigned int i, j; |
18831 |
+ DEF_FIELD_ADDR(symval, dmi_system_id, matches); |
18832 |
+ sprintf(alias, "dmi*"); |
18833 |
+ |
18834 |
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c |
18835 |
+index 48958d3..d5ccb52 100644 |
18836 |
+--- a/scripts/mod/modpost.c |
18837 |
++++ b/scripts/mod/modpost.c |
18838 |
+@@ -37,6 +37,7 @@ static int vmlinux_section_warnings = 1; |
18839 |
+ static int warn_unresolved = 0; |
18840 |
+ /* How a symbol is exported */ |
18841 |
+ static int sec_mismatch_count = 0; |
18842 |
++static int writable_fptr_count = 0; |
18843 |
+ static int sec_mismatch_verbose = 1; |
18844 |
+ static int sec_mismatch_fatal = 0; |
18845 |
+ /* ignore missing files */ |
18846 |
+@@ -947,6 +948,7 @@ enum mismatch { |
18847 |
+ ANY_EXIT_TO_ANY_INIT, |
18848 |
+ EXPORT_TO_INIT_EXIT, |
18849 |
+ EXTABLE_TO_NON_TEXT, |
18850 |
++ DATA_TO_TEXT |
18851 |
+ }; |
18852 |
+ |
18853 |
+ /** |
18854 |
+@@ -1073,6 +1075,12 @@ static const struct sectioncheck sectioncheck[] = { |
18855 |
+ .good_tosec = {ALL_TEXT_SECTIONS , NULL}, |
18856 |
+ .mismatch = EXTABLE_TO_NON_TEXT, |
18857 |
+ .handler = extable_mismatch_handler, |
18858 |
++}, |
18859 |
++/* Do not reference code from writable data */ |
18860 |
++{ |
18861 |
++ .fromsec = { DATA_SECTIONS, NULL }, |
18862 |
++ .bad_tosec = { ALL_TEXT_SECTIONS, NULL }, |
18863 |
++ .mismatch = DATA_TO_TEXT |
18864 |
+ } |
18865 |
+ }; |
18866 |
+ |
18867 |
+@@ -1222,10 +1230,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, |
18868 |
+ continue; |
18869 |
+ if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) |
18870 |
+ continue; |
18871 |
+- if (sym->st_value == addr) |
18872 |
+- return sym; |
18873 |
+ /* Find a symbol nearby - addr are maybe negative */ |
18874 |
+ d = sym->st_value - addr; |
18875 |
++ if (d == 0) |
18876 |
++ return sym; |
18877 |
+ if (d < 0) |
18878 |
+ d = addr - sym->st_value; |
18879 |
+ if (d < distance) { |
18880 |
+@@ -1384,7 +1392,11 @@ static void report_sec_mismatch(const char *modname, |
18881 |
+ char *prl_from; |
18882 |
+ char *prl_to; |
18883 |
+ |
18884 |
+- sec_mismatch_count++; |
18885 |
++ if (mismatch->mismatch == DATA_TO_TEXT) |
18886 |
++ writable_fptr_count++; |
18887 |
++ else |
18888 |
++ sec_mismatch_count++; |
18889 |
+ |
18890 |
-+#if BUILDING_GCC_VERSION <= 4007 |
18891 |
-+static tree create_new_phi_node(struct visited *visited, VEC(tree, heap) **args, tree ssa_name_var, gimple oldstmt) |
18892 |
-+#else |
18893 |
-+static tree create_new_phi_node(struct visited *visited, vec<tree, va_heap, vl_embed> *&args, tree ssa_name_var, gphi *oldstmt) |
18894 |
+ if (!sec_mismatch_verbose) |
18895 |
+ return; |
18896 |
+ |
18897 |
+@@ -1508,6 +1520,14 @@ static void report_sec_mismatch(const char *modname, |
18898 |
+ fatal("There's a special handler for this mismatch type, " |
18899 |
+ "we should never get here."); |
18900 |
+ break; |
18901 |
++ case DATA_TO_TEXT: |
18902 |
++#if 0 |
18903 |
++ fprintf(stderr, |
18904 |
++ "The %s %s:%s references\n" |
18905 |
++ "the %s %s:%s%s\n", |
18906 |
++ from, fromsec, fromsym, to, tosec, tosym, to_p); |
18907 |
+#endif |
18908 |
-+{ |
18909 |
-+ gphi *new_phi; |
18910 |
++ break; |
18911 |
+ } |
18912 |
+ fprintf(stderr, "\n"); |
18913 |
+ } |
18914 |
+@@ -1897,7 +1917,7 @@ static void section_rel(const char *modname, struct elf_info *elf, |
18915 |
+ static void check_sec_ref(struct module *mod, const char *modname, |
18916 |
+ struct elf_info *elf) |
18917 |
+ { |
18918 |
+- int i; |
18919 |
+ unsigned int i; |
18920 |
-+ tree arg, result; |
18921 |
-+ location_t loc = gimple_location(oldstmt); |
18922 |
-+ |
18923 |
-+#if BUILDING_GCC_VERSION <= 4007 |
18924 |
-+ gcc_assert(!VEC_empty(tree, *args)); |
18925 |
-+#else |
18926 |
-+ gcc_assert(!args->is_empty()); |
18927 |
-+#endif |
18928 |
-+ |
18929 |
-+ new_phi = overflow_create_phi_node(visited, oldstmt, ssa_name_var); |
18930 |
-+ result = gimple_phi_result(new_phi); |
18931 |
-+ ssa_name_var = SSA_NAME_VAR(result); |
18932 |
-+ |
18933 |
-+#if BUILDING_GCC_VERSION <= 4007 |
18934 |
-+ FOR_EACH_VEC_ELT(tree, *args, i, arg) { |
18935 |
-+#else |
18936 |
-+ FOR_EACH_VEC_SAFE_ELT(args, i, arg) { |
18937 |
-+#endif |
18938 |
-+ arg = create_new_phi_arg(visited, ssa_name_var, arg, oldstmt, i); |
18939 |
-+ add_phi_arg(new_phi, arg, gimple_phi_arg_edge(oldstmt, i), loc); |
18940 |
-+ } |
18941 |
-+ |
18942 |
-+#if BUILDING_GCC_VERSION <= 4007 |
18943 |
-+ VEC_free(tree, heap, *args); |
18944 |
-+#else |
18945 |
-+ vec_free(args); |
18946 |
-+#endif |
18947 |
-+ update_stmt(new_phi); |
18948 |
-+ pointer_set_insert(visited->my_stmts, new_phi); |
18949 |
-+ return result; |
18950 |
-+} |
18951 |
-+ |
18952 |
-+static tree handle_phi(interesting_stmts_t expand_from, tree orig_result) |
18953 |
-+{ |
18954 |
-+#if BUILDING_GCC_VERSION <= 4007 |
18955 |
-+ VEC(tree, heap) *args = NULL; |
18956 |
-+#else |
18957 |
-+ vec<tree, va_heap, vl_embed> *args = NULL; |
18958 |
-+#endif |
18959 |
-+ unsigned int i, len; |
18960 |
-+ tree ssa_name_var = NULL_TREE; |
18961 |
-+ gphi *oldstmt = as_a_gphi(get_def_stmt(orig_result)); |
18962 |
-+ |
18963 |
-+ len = gimple_phi_num_args(oldstmt); |
18964 |
-+ pointer_set_insert(expand_from->visited->stmts, oldstmt); |
18965 |
-+ for (i = 0; i < len; i++) { |
18966 |
-+ tree arg, new_arg; |
18967 |
-+ |
18968 |
-+ arg = gimple_phi_arg_def(oldstmt, i); |
18969 |
-+ new_arg = expand(expand_from, arg); |
18970 |
-+ |
18971 |
-+ if (ssa_name_var == NULL_TREE && new_arg != NULL_TREE) |
18972 |
-+ ssa_name_var = SSA_NAME_VAR(new_arg); |
18973 |
-+ |
18974 |
-+ if (is_gimple_constant(arg)) { |
18975 |
-+ tree size_overflow_type = get_size_overflow_type(expand_from->visited, oldstmt, arg); |
18976 |
-+ |
18977 |
-+ new_arg = cast_a_tree(size_overflow_type, arg); |
18978 |
+ Elf_Shdr *sechdrs = elf->sechdrs; |
18979 |
+ |
18980 |
+ /* Walk through all sections */ |
18981 |
+@@ -2028,7 +2048,7 @@ void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, |
18982 |
+ va_end(ap); |
18983 |
+ } |
18984 |
+ |
18985 |
+-void buf_write(struct buffer *buf, const char *s, int len) |
18986 |
++void buf_write(struct buffer *buf, const char *s, unsigned int len) |
18987 |
+ { |
18988 |
+ if (buf->size - buf->pos < len) { |
18989 |
+ buf->size += len + SZ; |
18990 |
+@@ -2258,7 +2278,7 @@ static void write_if_changed(struct buffer *b, const char *fname) |
18991 |
+ if (fstat(fileno(file), &st) < 0) |
18992 |
+ goto close_write; |
18993 |
+ |
18994 |
+- if (st.st_size != b->pos) |
18995 |
++ if (st.st_size != (off_t)b->pos) |
18996 |
+ goto close_write; |
18997 |
+ |
18998 |
+ tmp = NOFAIL(malloc(b->pos)); |
18999 |
+@@ -2496,6 +2516,14 @@ int main(int argc, char **argv) |
19000 |
+ "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); |
19001 |
+ } |
19002 |
+ } |
19003 |
++ if (writable_fptr_count) { |
19004 |
++ if (!sec_mismatch_verbose) { |
19005 |
++ warn("modpost: Found %d writable function pointer(s).\n" |
19006 |
++ "To see full details build your kernel with:\n" |
19007 |
++ "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", |
19008 |
++ writable_fptr_count); |
19009 |
+ } |
19010 |
-+ |
19011 |
-+#if BUILDING_GCC_VERSION <= 4007 |
19012 |
-+ VEC_safe_push(tree, heap, args, new_arg); |
19013 |
-+#else |
19014 |
-+ vec_safe_push(args, new_arg); |
19015 |
-+#endif |
19016 |
+ } |
19017 |
-+ |
19018 |
-+#if BUILDING_GCC_VERSION <= 4007 |
19019 |
-+ return create_new_phi_node(expand_from->visited, &args, ssa_name_var, oldstmt); |
19020 |
-+#else |
19021 |
-+ return create_new_phi_node(expand_from->visited, args, ssa_name_var, oldstmt); |
19022 |
-+#endif |
19023 |
-+} |
19024 |
-+ |
19025 |
-+static tree create_cast_assign(struct visited *visited, gassign *stmt) |
19026 |
-+{ |
19027 |
-+ tree rhs1 = gimple_assign_rhs1(stmt); |
19028 |
-+ tree lhs = gimple_assign_lhs(stmt); |
19029 |
-+ const_tree rhs1_type = TREE_TYPE(rhs1); |
19030 |
-+ const_tree lhs_type = TREE_TYPE(lhs); |
19031 |
-+ |
19032 |
-+ if (TYPE_UNSIGNED(rhs1_type) == TYPE_UNSIGNED(lhs_type)) |
19033 |
-+ return create_assign(visited, stmt, lhs, AFTER_STMT); |
19034 |
-+ |
19035 |
-+ return create_assign(visited, stmt, rhs1, AFTER_STMT); |
19036 |
-+} |
19037 |
-+ |
19038 |
-+static bool skip_lhs_cast_check(struct visited *visited, const gassign *stmt) |
19039 |
-+{ |
19040 |
-+ const_tree rhs = gimple_assign_rhs1(stmt); |
19041 |
-+ const_gimple def_stmt = get_def_stmt(rhs); |
19042 |
-+ |
19043 |
-+ // 3.8.2 kernel/futex_compat.c compat_exit_robust_list(): get_user() 64 ulong -> int (compat_long_t), int max |
19044 |
-+ if (gimple_code(def_stmt) == GIMPLE_ASM) |
19045 |
-+ return true; |
19046 |
-+ |
19047 |
-+ if (is_const_plus_unsigned_signed_truncation(rhs)) { |
19048 |
-+ pointer_set_insert(visited->no_cast_check, stmt); |
19049 |
-+ return true; |
19050 |
+ |
19051 |
+ return err; |
19052 |
+ } |
19053 |
+diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h |
19054 |
+index 6a5e151..f2fbaf5 100644 |
19055 |
+--- a/scripts/mod/modpost.h |
19056 |
++++ b/scripts/mod/modpost.h |
19057 |
+@@ -98,15 +98,15 @@ void *do_nofail(void *ptr, const char *expr); |
19058 |
+ |
19059 |
+ struct buffer { |
19060 |
+ char *p; |
19061 |
+- int pos; |
19062 |
+- int size; |
19063 |
++ unsigned int pos; |
19064 |
++ unsigned int size; |
19065 |
+ }; |
19066 |
+ |
19067 |
+ void __attribute__((format(printf, 2, 3))) |
19068 |
+ buf_printf(struct buffer *buf, const char *fmt, ...); |
19069 |
+ |
19070 |
+ void |
19071 |
+-buf_write(struct buffer *buf, const char *s, int len); |
19072 |
++buf_write(struct buffer *buf, const char *s, unsigned int len); |
19073 |
+ |
19074 |
+ struct module { |
19075 |
+ struct module *next; |
19076 |
+diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c |
19077 |
+index 944418d..15291e4 100644 |
19078 |
+--- a/scripts/mod/sumversion.c |
19079 |
++++ b/scripts/mod/sumversion.c |
19080 |
+@@ -470,7 +470,7 @@ static void write_version(const char *filename, const char *sum, |
19081 |
+ goto out; |
19082 |
+ } |
19083 |
+ |
19084 |
+- if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { |
19085 |
++ if (write(fd, sum, strlen(sum)+1) != (ssize_t)strlen(sum)+1) { |
19086 |
+ warn("writing sum in %s failed: %s\n", |
19087 |
+ filename, strerror(errno)); |
19088 |
+ goto out; |
19089 |
+diff --git a/scripts/module-common.lds b/scripts/module-common.lds |
19090 |
+index 73a2c7d..df11b31 100644 |
19091 |
+--- a/scripts/module-common.lds |
19092 |
++++ b/scripts/module-common.lds |
19093 |
+@@ -6,6 +6,10 @@ |
19094 |
+ SECTIONS { |
19095 |
+ /DISCARD/ : { *(.discard) } |
19096 |
+ |
19097 |
++ .rodata 0: { |
19098 |
++ *(.rodata) *(.rodata.*) |
19099 |
++ *(.data..read_only) |
19100 |
+ } |
19101 |
+ __ksymtab 0 : { *(SORT(___ksymtab+*)) } |
19102 |
+ __ksymtab_gpl 0 : { *(SORT(___ksymtab_gpl+*)) } |
19103 |
+ __ksymtab_unused 0 : { *(SORT(___ksymtab_unused+*)) } |
19104 |
+diff --git a/scripts/package/Makefile b/scripts/package/Makefile |
19105 |
+index c2c7389..81b8117 100644 |
19106 |
+--- a/scripts/package/Makefile |
19107 |
++++ b/scripts/package/Makefile |
19108 |
+@@ -40,7 +40,7 @@ if test "$(objtree)" != "$(srctree)"; then \ |
19109 |
+ fi ; \ |
19110 |
+ $(srctree)/scripts/setlocalversion --save-scmversion; \ |
19111 |
+ ln -sf $(srctree) $(2); \ |
19112 |
+-tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ |
19113 |
++tar --owner=root --group=root -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ |
19114 |
+ $(addprefix $(2)/,$(TAR_CONTENT) $(3)); \ |
19115 |
+ rm -f $(2) $(objtree)/.scmversion |
19116 |
+ |
19117 |
+diff --git a/scripts/package/builddeb b/scripts/package/builddeb |
19118 |
+index 6c3b038..4bac93f 100755 |
19119 |
+--- a/scripts/package/builddeb |
19120 |
++++ b/scripts/package/builddeb |
19121 |
+@@ -326,6 +326,7 @@ fi |
19122 |
+ (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" |
19123 |
+ (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" |
19124 |
+ (cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles" |
19125 |
++(cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles" |
19126 |
+ destdir=$kernel_headers_dir/usr/src/linux-headers-$version |
19127 |
+ mkdir -p "$destdir" |
19128 |
+ (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) |
19129 |
+diff --git a/scripts/package/mkspec b/scripts/package/mkspec |
19130 |
+index fe44d68..3874acb 100755 |
19131 |
+--- a/scripts/package/mkspec |
19132 |
++++ b/scripts/package/mkspec |
19133 |
+@@ -120,29 +120,40 @@ echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/{build,source}" |
19134 |
+ echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE" |
19135 |
+ echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude=firmware --exclude .config.old --exclude .missing-syscalls.d\"" |
19136 |
+ echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)" |
19137 |
+-echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE" |
19138 |
+-echo "ln -sf /usr/src/kernels/$KERNELRELEASE build" |
19139 |
+-echo "ln -sf /usr/src/kernels/$KERNELRELEASE source" |
19140 |
+ fi |
19141 |
+ |
19142 |
+ echo "" |
19143 |
+ echo "%clean" |
19144 |
+ echo 'rm -rf $RPM_BUILD_ROOT' |
19145 |
+ echo "" |
19146 |
++echo "%pre" |
19147 |
++echo 'chmod -f 0500 /boot' |
19148 |
++echo 'if [ -d /lib/modules ]; then' |
19149 |
++echo 'chmod -f 0500 /lib/modules' |
19150 |
++echo 'fi' |
19151 |
++echo 'if [ -d /lib32/modules ]; then' |
19152 |
++echo 'chmod -f 0500 /lib32/modules' |
19153 |
++echo 'fi' |
19154 |
++echo 'if [ -d /lib64/modules ]; then' |
19155 |
++echo 'chmod -f 0500 /lib64/modules' |
19156 |
++echo 'fi' |
19157 |
++echo "" |
19158 |
++echo "%post devel" |
19159 |
++echo "ln -sf /usr/src/kernels/$KERNELRELEASE /lib/modules/$KERNELRELEASE/build" |
19160 |
++echo "ln -sf /usr/src/kernels/$KERNELRELEASE /lib/modules/$KERNELRELEASE/source" |
19161 |
++echo "" |
19162 |
+ echo "%post" |
19163 |
+-echo "if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then" |
19164 |
+-echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm" |
19165 |
+-echo "cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm" |
19166 |
+-echo "rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE" |
19167 |
+-echo "/sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm" |
19168 |
+-echo "rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm" |
19169 |
++echo "if [ -x /sbin/dracut ]; then" |
19170 |
++echo '/sbin/new-kernel-pkg --dracut --mkinitrd --depmod --install --make-default '"$KERNELRELEASE"' || exit $?' |
19171 |
++echo "else" |
19172 |
++echo '/sbin/new-kernel-pkg --mkinitrd --depmod --install --make-default '"$KERNELRELEASE"' || exit $?' |
19173 |
+ echo "fi" |
19174 |
+ echo "" |
19175 |
+ echo "%files" |
19176 |
+-echo '%defattr (-, root, root)' |
19177 |
+-echo "/lib/modules/$KERNELRELEASE" |
19178 |
++echo '%defattr (400, root, root, 500)' |
19179 |
+ echo "%exclude /lib/modules/$KERNELRELEASE/build" |
19180 |
+ echo "%exclude /lib/modules/$KERNELRELEASE/source" |
19181 |
++echo "/lib/modules/$KERNELRELEASE" |
19182 |
+ echo "/lib/firmware/$KERNELRELEASE" |
19183 |
+ echo "/boot/*" |
19184 |
+ echo "" |
19185 |
+@@ -152,9 +163,11 @@ echo "/usr/include" |
19186 |
+ echo "" |
19187 |
+ if ! $PREBUILT; then |
19188 |
+ echo "%files devel" |
19189 |
+-echo '%defattr (-, root, root)' |
19190 |
++echo '%defattr (400, root, root, 500)' |
19191 |
++echo "%dir /lib/modules/$KERNELRELEASE" |
19192 |
+ echo "/usr/src/kernels/$KERNELRELEASE" |
19193 |
+-echo "/lib/modules/$KERNELRELEASE/build" |
19194 |
+-echo "/lib/modules/$KERNELRELEASE/source" |
19195 |
++echo "%attr (500, root, root) /usr/src/kernels/$KERNELRELEASE/scripts/recordmcount" |
19196 |
++echo "%attr (500, root, root) /usr/src/kernels/$KERNELRELEASE/scripts/basic/fixdep" |
19197 |
++echo "%attr (500, root, root) /usr/src/kernels/$KERNELRELEASE/scripts/mod/modpost" |
19198 |
+ echo "" |
19199 |
+ fi |
19200 |
+diff --git a/scripts/pnmtologo.c b/scripts/pnmtologo.c |
19201 |
+index 4718d78..9220d58 100644 |
19202 |
+--- a/scripts/pnmtologo.c |
19203 |
++++ b/scripts/pnmtologo.c |
19204 |
+@@ -244,14 +244,14 @@ static void write_header(void) |
19205 |
+ fprintf(out, " * Linux logo %s\n", logoname); |
19206 |
+ fputs(" */\n\n", out); |
19207 |
+ fputs("#include <linux/linux_logo.h>\n\n", out); |
19208 |
+- fprintf(out, "static unsigned char %s_data[] __initdata = {\n", |
19209 |
++ fprintf(out, "static unsigned char %s_data[] = {\n", |
19210 |
+ logoname); |
19211 |
+ } |
19212 |
+ |
19213 |
+ static void write_footer(void) |
19214 |
+ { |
19215 |
+ fputs("\n};\n\n", out); |
19216 |
+- fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); |
19217 |
++ fprintf(out, "const struct linux_logo %s = {\n", logoname); |
19218 |
+ fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); |
19219 |
+ fprintf(out, "\t.width\t\t= %d,\n", logo_width); |
19220 |
+ fprintf(out, "\t.height\t\t= %d,\n", logo_height); |
19221 |
+@@ -381,7 +381,7 @@ static void write_logo_clut224(void) |
19222 |
+ fputs("\n};\n\n", out); |
19223 |
+ |
19224 |
+ /* write logo clut */ |
19225 |
+- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", |
19226 |
++ fprintf(out, "static unsigned char %s_clut[] = {\n", |
19227 |
+ logoname); |
19228 |
+ write_hex_cnt = 0; |
19229 |
+ for (i = 0; i < logo_clutsize; i++) { |
19230 |
+diff --git a/scripts/sortextable.h b/scripts/sortextable.h |
19231 |
+index ba87004..3f4852c 100644 |
19232 |
+--- a/scripts/sortextable.h |
19233 |
++++ b/scripts/sortextable.h |
19234 |
+@@ -108,9 +108,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) |
19235 |
+ const char *secstrtab; |
19236 |
+ const char *strtab; |
19237 |
+ char *extab_image; |
19238 |
+- int extab_index = 0; |
19239 |
+- int i; |
19240 |
+- int idx; |
19241 |
++ unsigned int extab_index = 0; |
19242 |
++ unsigned int i; |
19243 |
++ unsigned int idx; |
19244 |
+ unsigned int num_sections; |
19245 |
+ unsigned int secindex_strings; |
19246 |
+ |
19247 |
+diff --git a/scripts/tags.sh b/scripts/tags.sh |
19248 |
+index 23ba1c6..cad2484 100755 |
19249 |
+--- a/scripts/tags.sh |
19250 |
++++ b/scripts/tags.sh |
19251 |
+@@ -26,7 +26,7 @@ else |
19252 |
+ fi |
19253 |
+ |
19254 |
+ # ignore userspace tools |
19255 |
+-ignore="$ignore ( -path ${tree}tools ) -prune -o" |
19256 |
++ignore="$ignore ( -path \"${tree}tools/[^g]*\" ) -prune -o" |
19257 |
+ |
19258 |
+ # Find all available archs |
19259 |
+ find_all_archs() |
19260 |
+diff --git a/security/Kconfig b/security/Kconfig |
19261 |
+index e452378..8059bd2 100644 |
19262 |
+--- a/security/Kconfig |
19263 |
++++ b/security/Kconfig |
19264 |
+@@ -4,6 +4,993 @@ |
19265 |
+ |
19266 |
+ menu "Security options" |
19267 |
+ |
19268 |
++menu "Grsecurity" |
19269 |
+ |
19270 |
-+ return false; |
19271 |
-+} |
19272 |
-+ |
19273 |
-+static tree create_string_param(tree string) |
19274 |
-+{ |
19275 |
-+ tree i_type, a_type; |
19276 |
-+ const int length = TREE_STRING_LENGTH(string); |
19277 |
++ config ARCH_TRACK_EXEC_LIMIT |
19278 |
++ bool |
19279 |
+ |
19280 |
-+ gcc_assert(length > 0); |
19281 |
++ config PAX_KERNEXEC_PLUGIN |
19282 |
++ bool |
19283 |
++ depends on GCC_PLUGINS |
19284 |
+ |
19285 |
-+ i_type = build_index_type(build_int_cst(NULL_TREE, length - 1)); |
19286 |
-+ a_type = build_array_type(char_type_node, i_type); |
19287 |
++ config PAX_PER_CPU_PGD |
19288 |
++ bool |
19289 |
+ |
19290 |
-+ TREE_TYPE(string) = a_type; |
19291 |
-+ TREE_CONSTANT(string) = 1; |
19292 |
-+ TREE_READONLY(string) = 1; |
19293 |
++ config TASK_SIZE_MAX_SHIFT |
19294 |
++ int |
19295 |
++ depends on X86_64 |
19296 |
++ default 47 if !PAX_PER_CPU_PGD |
19297 |
++ default 42 if PAX_PER_CPU_PGD |
19298 |
+ |
19299 |
-+ return build1(ADDR_EXPR, ptr_type_node, string); |
19300 |
-+} |
19301 |
++ config PAX_ENABLE_PAE |
19302 |
++ bool |
19303 |
++ default y if (X86_32 && (MPENTIUM4 || MK8 || MPSC || MCORE2 || MATOM)) |
19304 |
++ |
19305 |
++ config PAX_USERCOPY_SLABS |
19306 |
++ bool |
19307 |
+ |
19308 |
-+static void insert_cond(basic_block cond_bb, tree arg, enum tree_code cond_code, tree type_value) |
19309 |
-+{ |
19310 |
-+ gcond *cond_stmt; |
19311 |
-+ gimple_stmt_iterator gsi = gsi_last_bb(cond_bb); |
19312 |
++config GRKERNSEC |
19313 |
++ bool "Grsecurity" |
19314 |
++ select CRYPTO |
19315 |
++ select CRYPTO_SHA256 |
19316 |
++ select PROC_FS |
19317 |
++ select STOP_MACHINE |
19318 |
++ select TTY |
19319 |
++ select DEBUG_KERNEL |
19320 |
++ select DEBUG_LIST |
19321 |
++ select MULTIUSER |
19322 |
++ help |
19323 |
++ If you say Y here, you will be able to configure many features |
19324 |
++ that will enhance the security of your system. It is highly |
19325 |
++ recommended that you say Y here and read through the help |
19326 |
++ for each option so that you fully understand the features and |
19327 |
++ can evaluate their usefulness for your machine. |
19328 |
+ |
19329 |
-+ cond_stmt = gimple_build_cond(cond_code, arg, type_value, NULL_TREE, NULL_TREE); |
19330 |
-+ gsi_insert_after(&gsi, cond_stmt, GSI_CONTINUE_LINKING); |
19331 |
-+ update_stmt(cond_stmt); |
19332 |
-+} |
19333 |
++choice |
19334 |
++ prompt "Configuration Method" |
19335 |
++ depends on GRKERNSEC |
19336 |
++ default GRKERNSEC_CONFIG_CUSTOM |
19337 |
++ help |
19338 |
+ |
19339 |
-+static void insert_cond_result(interesting_stmts_t expand_from, basic_block bb_true, const_gimple stmt, const_tree arg, bool min) |
19340 |
-+{ |
19341 |
-+ gcall *func_stmt; |
19342 |
-+ const_gimple def_stmt; |
19343 |
-+ const_tree loc_line; |
19344 |
-+ tree loc_file, ssa_name, current_func; |
19345 |
-+ expanded_location xloc; |
19346 |
-+ char *ssa_name_buf; |
19347 |
-+ int len; |
19348 |
-+ struct cgraph_edge *edge; |
19349 |
-+ struct cgraph_node *report_node; |
19350 |
-+ int frequency; |
19351 |
-+ gimple_stmt_iterator gsi = gsi_start_bb(bb_true); |
19352 |
++config GRKERNSEC_CONFIG_AUTO |
19353 |
++ bool "Automatic" |
19354 |
++ help |
19355 |
++ If you choose this configuration method, you'll be able to answer a small |
19356 |
++ number of simple questions about how you plan to use this kernel. |
19357 |
++ The settings of grsecurity and PaX will be automatically configured for |
19358 |
++ the highest commonly-used settings within the provided constraints. |
19359 |
+ |
19360 |
-+ def_stmt = get_def_stmt(arg); |
19361 |
-+ if (gimple_has_location(def_stmt)) |
19362 |
-+ xloc = expand_location(gimple_location(def_stmt)); |
19363 |
-+ else if (gimple_has_location(stmt)) |
19364 |
-+ xloc = expand_location(gimple_location(stmt)); |
19365 |
-+ else |
19366 |
-+ xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl)); |
19367 |
++ If you require additional configuration, custom changes can still be made |
19368 |
++ from the "custom configuration" menu. |
19369 |
+ |
19370 |
-+ loc_line = build_int_cstu(unsigned_type_node, xloc.line); |
19371 |
++config GRKERNSEC_CONFIG_CUSTOM |
19372 |
++ bool "Custom" |
19373 |
++ help |
19374 |
++ If you choose this configuration method, you'll be able to configure all |
19375 |
++ grsecurity and PaX settings manually. Via this method, no options are |
19376 |
++ automatically enabled. |
19377 |
+ |
19378 |
-+ loc_file = build_string(strlen(xloc.file) + 1, xloc.file); |
19379 |
-+ loc_file = create_string_param(loc_file); |
19380 |
++ Take note that if menuconfig is exited with this configuration method |
19381 |
++ chosen, you will not be able to use the automatic configuration methods |
19382 |
++ without starting again with a kernel configuration with no grsecurity |
19383 |
++ or PaX options specified inside. |
19384 |
+ |
19385 |
-+ current_func = build_string(DECL_NAME_LENGTH(current_function_decl) + 1, DECL_NAME_POINTER(current_function_decl)); |
19386 |
-+ current_func = create_string_param(current_func); |
19387 |
++endchoice |
19388 |
+ |
19389 |
-+ gcc_assert(DECL_NAME(SSA_NAME_VAR(arg)) != NULL); |
19390 |
-+ call_count++; |
19391 |
-+ len = asprintf(&ssa_name_buf, "%s_%u %s, count: %u, decl: %s; num: %u; context: %s;\n", DECL_NAME_POINTER(SSA_NAME_VAR(arg)), SSA_NAME_VERSION(arg), min ? "min" : "max", call_count, expand_from->next_node->decl_name, expand_from->next_node->num, expand_from->next_node->context); |
19392 |
-+ gcc_assert(len > 0); |
19393 |
-+ ssa_name = build_string(len + 1, ssa_name_buf); |
19394 |
-+ free(ssa_name_buf); |
19395 |
-+ ssa_name = create_string_param(ssa_name); |
19396 |
++choice |
19397 |
++ prompt "Usage Type" |
19398 |
++ depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO) |
19399 |
++ default GRKERNSEC_CONFIG_SERVER |
19400 |
++ help |
19401 |
+ |
19402 |
-+ // void report_size_overflow(const char *file, unsigned int line, const char *func, const char *ssa_name) |
19403 |
-+ func_stmt = as_a_gcall(gimple_build_call(report_size_overflow_decl, 4, loc_file, loc_line, current_func, ssa_name)); |
19404 |
-+ gsi_insert_after(&gsi, func_stmt, GSI_CONTINUE_LINKING); |
19405 |
++config GRKERNSEC_CONFIG_SERVER |
19406 |
++ bool "Server" |
19407 |
++ help |
19408 |
++ Choose this option if you plan to use this kernel on a server. |
19409 |
+ |
19410 |
-+ report_node = cgraph_get_create_node(report_size_overflow_decl); |
19411 |
-+ gcc_assert(report_node); |
19412 |
-+ frequency = compute_call_stmt_bb_frequency(current_function_decl, bb_true); |
19413 |
++config GRKERNSEC_CONFIG_DESKTOP |
19414 |
++ bool "Desktop" |
19415 |
++ help |
19416 |
++ Choose this option if you plan to use this kernel on a desktop. |
19417 |
+ |
19418 |
-+ edge = cgraph_create_edge(get_cnode(current_function_decl), report_node, func_stmt, bb_true->count, frequency, bb_true->loop_depth); |
19419 |
-+ gcc_assert(edge != NULL); |
19420 |
-+} |
19421 |
++endchoice |
19422 |
+ |
19423 |
-+static void insert_check_size_overflow(interesting_stmts_t expand_from, gimple stmt, enum tree_code cond_code, tree arg, tree type_value, bool before, bool min) |
19424 |
-+{ |
19425 |
-+ basic_block cond_bb, join_bb, bb_true; |
19426 |
-+ edge e; |
19427 |
-+ gimple_stmt_iterator gsi = gsi_for_stmt(stmt); |
19428 |
++choice |
19429 |
++ prompt "Virtualization Type" |
19430 |
++ depends on (GRKERNSEC && X86 && GRKERNSEC_CONFIG_AUTO) |
19431 |
++ default GRKERNSEC_CONFIG_VIRT_NONE |
19432 |
++ help |
19433 |
+ |
19434 |
-+ cond_bb = gimple_bb(stmt); |
19435 |
-+ if (before) |
19436 |
-+ gsi_prev(&gsi); |
19437 |
-+ if (gsi_end_p(gsi)) |
19438 |
-+ e = split_block_after_labels(cond_bb); |
19439 |
-+ else |
19440 |
-+ e = split_block(cond_bb, gsi_stmt(gsi)); |
19441 |
-+ cond_bb = e->src; |
19442 |
-+ join_bb = e->dest; |
19443 |
-+ e->flags = EDGE_FALSE_VALUE; |
19444 |
-+ e->probability = REG_BR_PROB_BASE; |
19445 |
++config GRKERNSEC_CONFIG_VIRT_NONE |
19446 |
++ bool "None" |
19447 |
++ help |
19448 |
++ Choose this option if this kernel will be run on bare metal. |
19449 |
+ |
19450 |
-+ bb_true = create_empty_bb(cond_bb); |
19451 |
-+ make_edge(cond_bb, bb_true, EDGE_TRUE_VALUE); |
19452 |
-+ make_edge(cond_bb, join_bb, EDGE_FALSE_VALUE); |
19453 |
-+ make_edge(bb_true, join_bb, EDGE_FALLTHRU); |
19454 |
++config GRKERNSEC_CONFIG_VIRT_GUEST |
19455 |
++ bool "Guest" |
19456 |
++ help |
19457 |
++ Choose this option if this kernel will be run as a VM guest. |
19458 |
+ |
19459 |
-+ gcc_assert(dom_info_available_p(CDI_DOMINATORS)); |
19460 |
-+ set_immediate_dominator(CDI_DOMINATORS, bb_true, cond_bb); |
19461 |
-+ set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb); |
19462 |
++config GRKERNSEC_CONFIG_VIRT_HOST |
19463 |
++ bool "Host" |
19464 |
++ help |
19465 |
++ Choose this option if this kernel will be run as a VM host. |
19466 |
+ |
19467 |
-+ if (current_loops != NULL) { |
19468 |
-+ gcc_assert(cond_bb->loop_father == join_bb->loop_father); |
19469 |
-+ add_bb_to_loop(bb_true, cond_bb->loop_father); |
19470 |
-+ } |
19471 |
++endchoice |
19472 |
+ |
19473 |
-+ insert_cond(cond_bb, arg, cond_code, type_value); |
19474 |
-+ insert_cond_result(expand_from, bb_true, stmt, arg, min); |
19475 |
++choice |
19476 |
++ prompt "Virtualization Hardware" |
19477 |
++ depends on (GRKERNSEC && X86 && GRKERNSEC_CONFIG_AUTO && (GRKERNSEC_CONFIG_VIRT_GUEST || GRKERNSEC_CONFIG_VIRT_HOST)) |
19478 |
++ help |
19479 |
+ |
19480 |
-+// print_the_code_insertions(stmt); |
19481 |
-+} |
19482 |
++config GRKERNSEC_CONFIG_VIRT_EPT |
19483 |
++ bool "EPT/RVI Processor Support" |
19484 |
++ depends on X86 |
19485 |
++ help |
19486 |
++ Choose this option if your CPU supports the EPT or RVI features of 2nd-gen |
19487 |
++ hardware virtualization. This allows for additional kernel hardening protections |
19488 |
++ to operate without additional performance impact. |
19489 |
+ |
19490 |
-+void check_size_overflow(interesting_stmts_t expand_from, gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before) |
19491 |
-+{ |
19492 |
-+ const_tree rhs_type = TREE_TYPE(rhs); |
19493 |
-+ tree cast_rhs_type, type_max_type, type_min_type, type_max, type_min; |
19494 |
++ To see if your Intel processor supports EPT, see: |
19495 |
++ http://ark.intel.com/Products/VirtualizationTechnology |
19496 |
++ (Most Core i3/5/7 support EPT) |
19497 |
+ |
19498 |
-+ if (pointer_set_contains(expand_from->visited->no_cast_check, stmt)) |
19499 |
-+ return; |
19500 |
++ To see if your AMD processor supports RVI, see: |
19501 |
++ http://support.amd.com/us/kbarticles/Pages/GPU120AMDRVICPUsHyperVWin8.aspx |
19502 |
+ |
19503 |
-+ gcc_assert(rhs_type != NULL_TREE); |
19504 |
-+ if (TREE_CODE(rhs_type) == POINTER_TYPE) |
19505 |
-+ return; |
19506 |
++config GRKERNSEC_CONFIG_VIRT_SOFT |
19507 |
++ bool "First-gen/No Hardware Virtualization" |
19508 |
++ help |
19509 |
++ Choose this option if you use an Atom/Pentium/Core 2 processor that either doesn't |
19510 |
++ support hardware virtualization or doesn't support the EPT/RVI extensions. |
19511 |
+ |
19512 |
-+ gcc_assert(TREE_CODE(rhs_type) == INTEGER_TYPE || TREE_CODE(rhs_type) == ENUMERAL_TYPE); |
19513 |
++endchoice |
19514 |
+ |
19515 |
-+ if (is_gimple_assign(stmt) && neg_short_add_intentional_overflow(as_a_gassign(stmt))) |
19516 |
-+ return; |
19517 |
++choice |
19518 |
++ prompt "Virtualization Software" |
19519 |
++ depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO && (GRKERNSEC_CONFIG_VIRT_GUEST || GRKERNSEC_CONFIG_VIRT_HOST)) |
19520 |
++ help |
19521 |
+ |
19522 |
-+ type_max = cast_a_tree(size_overflow_type, TYPE_MAX_VALUE(rhs_type)); |
19523 |
-+ // typemax (-1) < typemin (0) |
19524 |
-+ if (TREE_OVERFLOW(type_max)) |
19525 |
-+ return; |
19526 |
++config GRKERNSEC_CONFIG_VIRT_XEN |
19527 |
++ bool "Xen" |
19528 |
++ help |
19529 |
++ Choose this option if this kernel is running as a Xen guest or host. |
19530 |
+ |
19531 |
-+ type_min = cast_a_tree(size_overflow_type, TYPE_MIN_VALUE(rhs_type)); |
19532 |
++config GRKERNSEC_CONFIG_VIRT_VMWARE |
19533 |
++ bool "VMWare" |
19534 |
++ help |
19535 |
++ Choose this option if this kernel is running as a VMWare guest or host. |
19536 |
+ |
19537 |
-+ cast_rhs_type = TREE_TYPE(cast_rhs); |
19538 |
-+ type_max_type = TREE_TYPE(type_max); |
19539 |
-+ gcc_assert(types_compatible_p(cast_rhs_type, type_max_type)); |
19540 |
++config GRKERNSEC_CONFIG_VIRT_KVM |
19541 |
++ bool "KVM" |
19542 |
++ help |
19543 |
++ Choose this option if this kernel is running as a KVM guest or host. |
19544 |
+ |
19545 |
-+ insert_check_size_overflow(expand_from, stmt, GT_EXPR, cast_rhs, type_max, before, MAX_CHECK); |
19546 |
++config GRKERNSEC_CONFIG_VIRT_VIRTUALBOX |
19547 |
++ bool "VirtualBox" |
19548 |
++ help |
19549 |
++ Choose this option if this kernel is running as a VirtualBox guest or host. |
19550 |
+ |
19551 |
-+ // special case: get_size_overflow_type(), 32, u64->s |
19552 |
-+ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode) && TYPE_UNSIGNED(size_overflow_type) && !TYPE_UNSIGNED(rhs_type)) |
19553 |
-+ return; |
19554 |
++config GRKERNSEC_CONFIG_VIRT_HYPERV |
19555 |
++ bool "Hyper-V" |
19556 |
++ help |
19557 |
++ Choose this option if this kernel is running as a Hyper-V guest. |
19558 |
+ |
19559 |
-+ type_min_type = TREE_TYPE(type_min); |
19560 |
-+ gcc_assert(types_compatible_p(type_max_type, type_min_type)); |
19561 |
-+ insert_check_size_overflow(expand_from, stmt, LT_EXPR, cast_rhs, type_min, before, MIN_CHECK); |
19562 |
-+} |
19563 |
++endchoice |
19564 |
+ |
19565 |
-+static tree get_my_stmt_lhs(struct visited *visited, gimple stmt) |
19566 |
-+{ |
19567 |
-+ gimple_stmt_iterator gsi; |
19568 |
-+ gimple next_stmt = NULL; |
19569 |
++choice |
19570 |
++ prompt "Required Priorities" |
19571 |
++ depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO) |
19572 |
++ default GRKERNSEC_CONFIG_PRIORITY_PERF |
19573 |
++ help |
19574 |
+ |
19575 |
-+ gsi = gsi_for_stmt(stmt); |
19576 |
++config GRKERNSEC_CONFIG_PRIORITY_PERF |
19577 |
++ bool "Performance" |
19578 |
++ help |
19579 |
++ Choose this option if performance is of highest priority for this deployment |
19580 |
++ of grsecurity. Features like UDEREF on a 64bit kernel, kernel stack clearing, |
19581 |
++ clearing of structures intended for userland, and freed memory sanitizing will |
19582 |
++ be disabled. |
19583 |
+ |
19584 |
-+ do { |
19585 |
-+ gsi_next(&gsi); |
19586 |
-+ next_stmt = gsi_stmt(gsi); |
19587 |
++config GRKERNSEC_CONFIG_PRIORITY_SECURITY |
19588 |
++ bool "Security" |
19589 |
++ help |
19590 |
++ Choose this option if security is of highest priority for this deployment of |
19591 |
++ grsecurity. UDEREF, kernel stack clearing, clearing of structures intended |
19592 |
++ for userland, and freed memory sanitizing will be enabled for this kernel. |
19593 |
++ In a worst-case scenario, these features can introduce a 20% performance hit |
19594 |
++ (UDEREF on x64 contributing half of this hit). |
19595 |
+ |
19596 |
-+ if (gimple_code(stmt) == GIMPLE_PHI && !pointer_set_contains(visited->my_stmts, next_stmt)) |
19597 |
-+ return NULL_TREE; |
19598 |
++endchoice |
19599 |
+ |
19600 |
-+ if (pointer_set_contains(visited->my_stmts, next_stmt) && !pointer_set_contains(visited->skip_expr_casts, next_stmt)) |
19601 |
-+ break; |
19602 |
++menu "Default Special Groups" |
19603 |
++depends on (GRKERNSEC && GRKERNSEC_CONFIG_AUTO) |
19604 |
+ |
19605 |
-+ gcc_assert(pointer_set_contains(visited->my_stmts, next_stmt)); |
19606 |
-+ } while (!gsi_end_p(gsi)); |
19607 |
++config GRKERNSEC_PROC_GID |
19608 |
++ int "GID exempted from /proc restrictions" |
19609 |
++ default 1001 |
19610 |
++ help |
19611 |
++ Setting this GID determines which group will be exempted from |
19612 |
++ grsecurity's /proc restrictions, allowing users of the specified |
19613 |
++ group to view network statistics and the existence of other users' |
19614 |
++ processes on the system. This GID may also be chosen at boot time |
19615 |
++ via "grsec_proc_gid=" on the kernel commandline. |
19616 |
+ |
19617 |
-+ gcc_assert(next_stmt); |
19618 |
-+ return get_lhs(next_stmt); |
19619 |
-+} |
19620 |
++config GRKERNSEC_TPE_UNTRUSTED_GID |
19621 |
++ int "GID for TPE-untrusted users" |
19622 |
++ depends on GRKERNSEC_CONFIG_SERVER && GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT |
19623 |
++ default 1005 |
19624 |
++ help |
19625 |
++ Setting this GID determines which group untrusted users should |
19626 |
++ be added to. These users will be placed under grsecurity's Trusted Path |
19627 |
++ Execution mechanism, preventing them from executing their own binaries. |
19628 |
++ The users will only be able to execute binaries in directories owned and |
19629 |
++ writable only by the root user. If the sysctl option is enabled, a sysctl |
19630 |
++ option with name "tpe_gid" is created. |
19631 |
+ |
19632 |
-+/* When the result of the negation is cast to a signed type then move |
19633 |
-+ * the size_overflow cast check before negation. |
19634 |
-+ * ssa: |
19635 |
-+ * unsigned _588 |
19636 |
-+ * _588 = _587 >> 12; |
19637 |
-+ * _589 = -_588; |
19638 |
-+ * _590 = (long int) _589; |
19639 |
-+ */ |
19640 |
-+static bool handle_unsigned_neg_or_bit_not(interesting_stmts_t expand_from, const gassign *stmt) |
19641 |
-+{ |
19642 |
-+ gimple def_neg_stmt, neg_stmt; |
19643 |
-+ tree lhs, new_neg_rhs; |
19644 |
-+ const_tree rhs, neg_rhs; |
19645 |
-+ enum tree_code rhs_code; |
19646 |
++config GRKERNSEC_TPE_TRUSTED_GID |
19647 |
++ int "GID for TPE-trusted users" |
19648 |
++ depends on GRKERNSEC_CONFIG_SERVER && GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT |
19649 |
++ default 1005 |
19650 |
++ help |
19651 |
++ Setting this GID determines what group TPE restrictions will be |
19652 |
++ *disabled* for. If the sysctl option is enabled, a sysctl option |
19653 |
++ with name "tpe_gid" is created. |
19654 |
+ |
19655 |
-+ rhs = gimple_assign_rhs1(stmt); |
19656 |
-+ lhs = gimple_assign_lhs(stmt); |
19657 |
-+ if (TYPE_UNSIGNED(TREE_TYPE(lhs)) || !TYPE_UNSIGNED(TREE_TYPE(rhs))) |
19658 |
-+ return false; |
19659 |
++config GRKERNSEC_SYMLINKOWN_GID |
19660 |
++ int "GID for users with kernel-enforced SymlinksIfOwnerMatch" |
19661 |
++ depends on GRKERNSEC_CONFIG_SERVER |
19662 |
++ default 1006 |
19663 |
++ help |
19664 |
++ Setting this GID determines what group kernel-enforced |
19665 |
++ SymlinksIfOwnerMatch will be enabled for. If the sysctl option |
19666 |
++ is enabled, a sysctl option with name "symlinkown_gid" is created. |
19667 |
+ |
19668 |
-+ neg_stmt = get_def_stmt(rhs); |
19669 |
-+ if (!neg_stmt || !is_gimple_assign(neg_stmt)) |
19670 |
-+ return false; |
19671 |
+ |
19672 |
-+ rhs_code = gimple_assign_rhs_code(neg_stmt); |
19673 |
-+ if (rhs_code != BIT_NOT_EXPR && rhs_code != NEGATE_EXPR) |
19674 |
-+ return false; |
19675 |
++endmenu |
19676 |
+ |
19677 |
-+ neg_rhs = gimple_assign_rhs1(neg_stmt); |
19678 |
-+ def_neg_stmt = get_def_stmt(neg_rhs); |
19679 |
-+ if (!def_neg_stmt) |
19680 |
-+ return false; |
19681 |
++menu "Customize Configuration" |
19682 |
++depends on GRKERNSEC |
19683 |
+ |
19684 |
-+ new_neg_rhs = get_my_stmt_lhs(expand_from->visited, def_neg_stmt); |
19685 |
-+ check_size_overflow(expand_from, neg_stmt, TREE_TYPE(new_neg_rhs), new_neg_rhs, lhs, BEFORE_STMT); |
19686 |
-+ pointer_set_insert(expand_from->visited->no_cast_check, stmt); |
19687 |
-+ return true; |
19688 |
-+} |
19689 |
++menu "PaX" |
19690 |
+ |
19691 |
-+static tree create_cast_overflow_check(interesting_stmts_t expand_from, tree new_rhs1, gassign *stmt) |
19692 |
-+{ |
19693 |
-+ bool cast_lhs, cast_rhs; |
19694 |
-+ tree lhs = gimple_assign_lhs(stmt); |
19695 |
-+ tree rhs = gimple_assign_rhs1(stmt); |
19696 |
-+ const_tree lhs_type = TREE_TYPE(lhs); |
19697 |
-+ const_tree rhs_type = TREE_TYPE(rhs); |
19698 |
-+ enum machine_mode lhs_mode = TYPE_MODE(lhs_type); |
19699 |
-+ enum machine_mode rhs_mode = TYPE_MODE(rhs_type); |
19700 |
-+ unsigned int lhs_size = GET_MODE_BITSIZE(lhs_mode); |
19701 |
-+ unsigned int rhs_size = GET_MODE_BITSIZE(rhs_mode); |
19702 |
++config PAX |
19703 |
++ bool "Enable various PaX features" |
19704 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19705 |
++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS || PARISC || PPC || SPARC || X86) |
19706 |
++ help |
19707 |
++ This allows you to enable various PaX features. PaX adds |
19708 |
++ intrusion prevention mechanisms to the kernel that reduce |
19709 |
++ the risks posed by exploitable memory corruption bugs. |
19710 |
+ |
19711 |
-+ static bool check_lhs[3][4] = { |
19712 |
-+ // ss su us uu |
19713 |
-+ { false, true, true, false }, // lhs > rhs |
19714 |
-+ { false, false, false, false }, // lhs = rhs |
19715 |
-+ { true, true, true, true }, // lhs < rhs |
19716 |
-+ }; |
19717 |
++menu "PaX Control" |
19718 |
++ depends on PAX |
19719 |
+ |
19720 |
-+ static bool check_rhs[3][4] = { |
19721 |
-+ // ss su us uu |
19722 |
-+ { true, false, true, true }, // lhs > rhs |
19723 |
-+ { true, false, true, true }, // lhs = rhs |
19724 |
-+ { true, false, true, true }, // lhs < rhs |
19725 |
-+ }; |
19726 |
++config PAX_SOFTMODE |
19727 |
++ bool 'Support soft mode' |
19728 |
++ help |
19729 |
++ Enabling this option will allow you to run PaX in soft mode, that |
19730 |
++ is, PaX features will not be enforced by default, only on executables |
19731 |
++ marked explicitly. You must also enable PT_PAX_FLAGS or XATTR_PAX_FLAGS |
19732 |
++ support as they are the only way to mark executables for soft mode use. |
19733 |
+ |
19734 |
-+ if (handle_unsigned_neg_or_bit_not(expand_from, stmt)) |
19735 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19736 |
++ Soft mode can be activated by using the "pax_softmode=1" kernel command |
19737 |
++ line option on boot. Furthermore you can control various PaX features |
19738 |
++ at runtime via the entries in /proc/sys/kernel/pax. |
19739 |
+ |
19740 |
-+ // skip lhs check on HI -> QI cast |
19741 |
-+ if (rhs_mode == HImode && lhs_mode == QImode) { |
19742 |
-+ pointer_set_insert(expand_from->visited->no_cast_check, stmt); |
19743 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19744 |
-+ } |
19745 |
++config PAX_EI_PAX |
19746 |
++ bool 'Use legacy ELF header marking' |
19747 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19748 |
++ help |
19749 |
++ Enabling this option will allow you to control PaX features on |
19750 |
++ a per executable basis via the 'chpax' utility available at |
19751 |
++ http://pax.grsecurity.net/. The control flags will be read from |
19752 |
++ an otherwise reserved part of the ELF header. This marking has |
19753 |
++ numerous drawbacks (no support for soft-mode, toolchain does not |
19754 |
++ know about the non-standard use of the ELF header) therefore it |
19755 |
++ has been deprecated in favour of PT_PAX_FLAGS and XATTR_PAX_FLAGS |
19756 |
++ support. |
19757 |
+ |
19758 |
-+ // skip lhs check on signed SI -> HI cast or signed SI -> QI cast |
19759 |
-+ if (rhs_mode == SImode && !TYPE_UNSIGNED(rhs_type) && (lhs_mode == HImode || lhs_mode == QImode)) |
19760 |
-+ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
19761 |
++ Note that if you enable PT_PAX_FLAGS or XATTR_PAX_FLAGS marking |
19762 |
++ support as well, they will override the legacy EI_PAX marks. |
19763 |
+ |
19764 |
-+ if (lhs_size > rhs_size) { |
19765 |
-+ cast_lhs = check_lhs[0][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
19766 |
-+ cast_rhs = check_rhs[0][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
19767 |
-+ } else if (lhs_size == rhs_size) { |
19768 |
-+ cast_lhs = check_lhs[1][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
19769 |
-+ cast_rhs = check_rhs[1][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
19770 |
-+ } else { |
19771 |
-+ cast_lhs = check_lhs[2][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
19772 |
-+ cast_rhs = check_rhs[2][TYPE_UNSIGNED(rhs_type) + 2 * TYPE_UNSIGNED(lhs_type)]; |
19773 |
-+ } |
19774 |
++ If you enable none of the marking options then all applications |
19775 |
++ will run with PaX enabled on them by default. |
19776 |
+ |
19777 |
-+ if (!cast_lhs && !cast_rhs) |
19778 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19779 |
++config PAX_PT_PAX_FLAGS |
19780 |
++ bool 'Use ELF program header marking' |
19781 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19782 |
++ help |
19783 |
++ Enabling this option will allow you to control PaX features on |
19784 |
++ a per executable basis via the 'paxctl' utility available at |
19785 |
++ http://pax.grsecurity.net/. The control flags will be read from |
19786 |
++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking |
19787 |
++ has the benefits of supporting both soft mode and being fully |
19788 |
++ integrated into the toolchain (the binutils patch is available |
19789 |
++ from http://pax.grsecurity.net). |
19790 |
+ |
19791 |
-+ if (cast_lhs && !skip_lhs_cast_check(expand_from->visited, stmt)) |
19792 |
-+ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs1), new_rhs1, lhs, BEFORE_STMT); |
19793 |
++ Note that if you enable the legacy EI_PAX marking support as well, |
19794 |
++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. |
19795 |
+ |
19796 |
-+ if (cast_rhs) |
19797 |
-+ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs1), new_rhs1, rhs, BEFORE_STMT); |
19798 |
++ If you enable both PT_PAX_FLAGS and XATTR_PAX_FLAGS support then you |
19799 |
++ must make sure that the marks are the same if a binary has both marks. |
19800 |
+ |
19801 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19802 |
-+} |
19803 |
++ If you enable none of the marking options then all applications |
19804 |
++ will run with PaX enabled on them by default. |
19805 |
+ |
19806 |
-+static tree handle_unary_rhs(interesting_stmts_t expand_from, gassign *stmt) |
19807 |
-+{ |
19808 |
-+ enum tree_code rhs_code; |
19809 |
-+ tree rhs1, new_rhs1, lhs = gimple_assign_lhs(stmt); |
19810 |
++config PAX_XATTR_PAX_FLAGS |
19811 |
++ bool 'Use filesystem extended attributes marking' |
19812 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19813 |
++ select CIFS_XATTR if CIFS |
19814 |
++ select EXT2_FS_XATTR if EXT2_FS |
19815 |
++ select EXT3_FS_XATTR if EXT3_FS |
19816 |
++ select F2FS_FS_XATTR if F2FS_FS |
19817 |
++ select JFFS2_FS_XATTR if JFFS2_FS |
19818 |
++ select REISERFS_FS_XATTR if REISERFS_FS |
19819 |
++ select SQUASHFS_XATTR if SQUASHFS |
19820 |
++ select TMPFS_XATTR if TMPFS |
19821 |
++ help |
19822 |
++ Enabling this option will allow you to control PaX features on |
19823 |
++ a per executable basis via the 'setfattr' utility. The control |
19824 |
++ flags will be read from the user.pax.flags extended attribute of |
19825 |
++ the file. This marking has the benefit of supporting binary-only |
19826 |
++ applications that self-check themselves (e.g., skype) and would |
19827 |
++ not tolerate chpax/paxctl changes. The main drawback is that |
19828 |
++ extended attributes are not supported by some filesystems (e.g., |
19829 |
++ isofs, udf, vfat) so copying files through such filesystems will |
19830 |
++ lose the extended attributes and these PaX markings. |
19831 |
+ |
19832 |
-+ if (pointer_set_contains(expand_from->visited->my_stmts, stmt)) |
19833 |
-+ return lhs; |
19834 |
++ Note that if you enable the legacy EI_PAX marking support as well, |
19835 |
++ the EI_PAX marks will be overridden by the XATTR_PAX_FLAGS marks. |
19836 |
+ |
19837 |
-+ rhs1 = gimple_assign_rhs1(stmt); |
19838 |
-+ if (TREE_CODE(TREE_TYPE(rhs1)) == POINTER_TYPE) |
19839 |
-+ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
19840 |
++ If you enable both PT_PAX_FLAGS and XATTR_PAX_FLAGS support then you |
19841 |
++ must make sure that the marks are the same if a binary has both marks. |
19842 |
+ |
19843 |
-+ new_rhs1 = expand(expand_from, rhs1); |
19844 |
++ If you enable none of the marking options then all applications |
19845 |
++ will run with PaX enabled on them by default. |
19846 |
+ |
19847 |
-+ if (new_rhs1 == NULL_TREE) |
19848 |
-+ return create_cast_assign(expand_from->visited, stmt); |
19849 |
++choice |
19850 |
++ prompt 'MAC system integration' |
19851 |
++ default PAX_HAVE_ACL_FLAGS |
19852 |
++ help |
19853 |
++ Mandatory Access Control systems have the option of controlling |
19854 |
++ PaX flags on a per executable basis, choose the method supported |
19855 |
++ by your particular system. |
19856 |
+ |
19857 |
-+ if (pointer_set_contains(expand_from->visited->no_cast_check, stmt)) |
19858 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19859 |
++ - "none": if your MAC system does not interact with PaX, |
19860 |
++ - "direct": if your MAC system defines pax_set_initial_flags() itself, |
19861 |
++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback. |
19862 |
+ |
19863 |
-+#if BUILDING_GCC_VERSION >= 5000 |
19864 |
-+ if (short_or_neg_const_ushort(stmt)) { |
19865 |
-+ pointer_set_insert(expand_from->visited->no_cast_check, stmt); |
19866 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19867 |
-+ } |
19868 |
-+#endif |
19869 |
++ NOTE: this option is for developers/integrators only. |
19870 |
+ |
19871 |
-+ rhs_code = gimple_assign_rhs_code(stmt); |
19872 |
-+ if (rhs_code == BIT_NOT_EXPR || rhs_code == NEGATE_EXPR) { |
19873 |
-+ tree size_overflow_type = get_size_overflow_type(expand_from->visited, stmt, rhs1); |
19874 |
++ config PAX_NO_ACL_FLAGS |
19875 |
++ bool 'none' |
19876 |
+ |
19877 |
-+ new_rhs1 = cast_to_new_size_overflow_type(expand_from->visited, stmt, new_rhs1, size_overflow_type, BEFORE_STMT); |
19878 |
-+ check_size_overflow(expand_from, stmt, size_overflow_type, new_rhs1, rhs1, BEFORE_STMT); |
19879 |
-+ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
19880 |
-+ } |
19881 |
++ config PAX_HAVE_ACL_FLAGS |
19882 |
++ bool 'direct' |
19883 |
+ |
19884 |
-+ if (!gimple_assign_cast_p(stmt)) |
19885 |
-+ return dup_assign(expand_from->visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); |
19886 |
++ config PAX_HOOK_ACL_FLAGS |
19887 |
++ bool 'hook' |
19888 |
++endchoice |
19889 |
+ |
19890 |
-+ return create_cast_overflow_check(expand_from, new_rhs1, stmt); |
19891 |
-+} |
19892 |
++endmenu |
19893 |
+ |
19894 |
-+static tree handle_unary_ops(interesting_stmts_t expand_from, gassign *stmt) |
19895 |
-+{ |
19896 |
-+ tree rhs1, lhs = gimple_assign_lhs(stmt); |
19897 |
-+ gimple def_stmt = get_def_stmt(lhs); |
19898 |
++menu "Non-executable pages" |
19899 |
++ depends on PAX |
19900 |
+ |
19901 |
-+ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP); |
19902 |
-+ rhs1 = gimple_assign_rhs1(def_stmt); |
19903 |
++config PAX_NOEXEC |
19904 |
++ bool "Enforce non-executable pages" |
19905 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19906 |
++ depends on ALPHA || (ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || IA64 || MIPS || PARISC || PPC || S390 || SPARC || X86 |
19907 |
++ help |
19908 |
++ By design some architectures do not allow for protecting memory |
19909 |
++ pages against execution or even if they do, Linux does not make |
19910 |
++ use of this feature. In practice this means that if a page is |
19911 |
++ readable (such as the stack or heap) it is also executable. |
19912 |
+ |
19913 |
-+ if (is_gimple_constant(rhs1)) |
19914 |
-+ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
19915 |
++ There is a well known exploit technique that makes use of this |
19916 |
++ fact and a common programming mistake where an attacker can |
19917 |
++ introduce code of his choice somewhere in the attacked program's |
19918 |
++ memory (typically the stack or the heap) and then execute it. |
19919 |
+ |
19920 |
-+ switch (TREE_CODE(rhs1)) { |
19921 |
-+ case SSA_NAME: { |
19922 |
-+ tree ret = handle_unary_rhs(expand_from, as_a_gassign(def_stmt)); |
19923 |
++ If the attacked program was running with different (typically |
19924 |
++ higher) privileges than that of the attacker, then he can elevate |
19925 |
++ his own privilege level (e.g. get a root shell, write to files for |
19926 |
++ which he does not have write access to, etc). |
19927 |
+ |
19928 |
-+ if (gimple_assign_cast_p(stmt)) |
19929 |
-+ unsigned_signed_cast_intentional_overflow(expand_from->visited, stmt); |
19930 |
-+ return ret; |
19931 |
-+ } |
19932 |
-+ case ARRAY_REF: |
19933 |
-+ case BIT_FIELD_REF: |
19934 |
-+ case ADDR_EXPR: |
19935 |
-+ case COMPONENT_REF: |
19936 |
-+ case INDIRECT_REF: |
19937 |
-+#if BUILDING_GCC_VERSION >= 4006 |
19938 |
-+ case MEM_REF: |
19939 |
-+#endif |
19940 |
-+ case TARGET_MEM_REF: |
19941 |
-+ case VIEW_CONVERT_EXPR: |
19942 |
-+ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
19943 |
-+ case PARM_DECL: |
19944 |
-+ case VAR_DECL: |
19945 |
-+ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
19946 |
++ Enabling this option will let you choose from various features |
19947 |
++ that prevent the injection and execution of 'foreign' code in |
19948 |
++ a program. |
19949 |
+ |
19950 |
-+ default: |
19951 |
-+ debug_gimple_stmt(def_stmt); |
19952 |
-+ debug_tree(rhs1); |
19953 |
-+ gcc_unreachable(); |
19954 |
-+ } |
19955 |
-+} |
19956 |
++ This will also break programs that rely on the old behaviour and |
19957 |
++ expect that dynamically allocated memory via the malloc() family |
19958 |
++ of functions is executable (which it is not). Notable examples |
19959 |
++ are the XFree86 4.x server, the java runtime and wine. |
19960 |
+ |
19961 |
-+static void __unused print_the_code_insertions(const_gimple stmt) |
19962 |
-+{ |
19963 |
-+ location_t loc = gimple_location(stmt); |
19964 |
++config PAX_PAGEEXEC |
19965 |
++ bool "Paging based non-executable pages" |
19966 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19967 |
++ depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MATOM || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7) |
19968 |
++ select ARCH_TRACK_EXEC_LIMIT if X86_32 |
19969 |
++ help |
19970 |
++ This implementation is based on the paging feature of the CPU. |
19971 |
++ On i386 without hardware non-executable bit support there is a |
19972 |
++ variable but usually low performance impact, however on Intel's |
19973 |
++ P4 core based CPUs it is very high so you should not enable this |
19974 |
++ for kernels meant to be used on such CPUs. |
19975 |
+ |
19976 |
-+ inform(loc, "Integer size_overflow check applied here."); |
19977 |
-+} |
19978 |
++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386 |
19979 |
++ with hardware non-executable bit support there is no performance |
19980 |
++ impact, on ppc the impact is negligible. |
19981 |
+ |
19982 |
-+static bool is_from_cast(const_tree node) |
19983 |
-+{ |
19984 |
-+ gimple def_stmt = get_def_stmt(node); |
19985 |
++ Note that several architectures require various emulations due to |
19986 |
++ badly designed userland ABIs, this will cause a performance impact |
19987 |
++ but will disappear as soon as userland is fixed. For example, ppc |
19988 |
++ userland MUST have been built with secure-plt by a recent toolchain. |
19989 |
+ |
19990 |
-+ if (!def_stmt) |
19991 |
-+ return false; |
19992 |
++config PAX_SEGMEXEC |
19993 |
++ bool "Segmentation based non-executable pages" |
19994 |
++ default y if GRKERNSEC_CONFIG_AUTO |
19995 |
++ depends on PAX_NOEXEC && X86_32 |
19996 |
++ help |
19997 |
++ This implementation is based on the segmentation feature of the |
19998 |
++ CPU and has a very small performance impact, however applications |
19999 |
++ will be limited to a 1.5 GB address space instead of the normal |
20000 |
++ 3 GB. |
20001 |
+ |
20002 |
-+ if (gimple_assign_cast_p(def_stmt)) |
20003 |
-+ return true; |
20004 |
++config PAX_EMUTRAMP |
20005 |
++ bool "Emulate trampolines" |
20006 |
++ default y if PARISC || GRKERNSEC_CONFIG_AUTO |
20007 |
++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || X86) |
20008 |
++ help |
20009 |
++ There are some programs and libraries that for one reason or |
20010 |
++ another attempt to execute special small code snippets from |
20011 |
++ non-executable memory pages. Most notable examples are the |
20012 |
++ signal handler return code generated by the kernel itself and |
20013 |
++ the GCC trampolines. |
20014 |
+ |
20015 |
-+ return false; |
20016 |
-+} |
20017 |
++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then |
20018 |
++ such programs will no longer work under your kernel. |
20019 |
+ |
20020 |
-+// Skip duplication when there is a minus expr and the type of rhs1 or rhs2 is a pointer_type. |
20021 |
-+static bool is_ptr_diff(gassign *stmt) |
20022 |
-+{ |
20023 |
-+ const_tree rhs1, rhs2, ptr1_rhs, ptr2_rhs; |
20024 |
++ As a remedy you can say Y here and use the 'chpax' or 'paxctl' |
20025 |
++ utilities to enable trampoline emulation for the affected programs |
20026 |
++ yet still have the protection provided by the non-executable pages. |
20027 |
+ |
20028 |
-+ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR) |
20029 |
-+ return false; |
20030 |
++ On parisc you MUST enable this option and EMUSIGRT as well, otherwise |
20031 |
++ your system will not even boot. |
20032 |
+ |
20033 |
-+ rhs1 = gimple_assign_rhs1(stmt); |
20034 |
-+ if (!is_from_cast(rhs1)) |
20035 |
-+ return false; |
20036 |
++ Alternatively you can say N here and use the 'chpax' or 'paxctl' |
20037 |
++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC |
20038 |
++ for the affected files. |
20039 |
+ |
20040 |
-+ rhs2 = gimple_assign_rhs2(stmt); |
20041 |
-+ if (!is_from_cast(rhs2)) |
20042 |
-+ return false; |
20043 |
++ NOTE: enabling this feature *may* open up a loophole in the |
20044 |
++ protection provided by non-executable pages that an attacker |
20045 |
++ could abuse. Therefore the best solution is to not have any |
20046 |
++ files on your system that would require this option. This can |
20047 |
++ be achieved by not using libc5 (which relies on the kernel |
20048 |
++ signal handler return code) and not using or rewriting programs |
20049 |
++ that make use of the nested function implementation of GCC. |
20050 |
++ Skilled users can just fix GCC itself so that it implements |
20051 |
++ nested function calls in a way that does not interfere with PaX. |
20052 |
+ |
20053 |
-+ ptr1_rhs = gimple_assign_rhs1(get_def_stmt(rhs1)); |
20054 |
-+ ptr2_rhs = gimple_assign_rhs1(get_def_stmt(rhs2)); |
20055 |
++config PAX_EMUSIGRT |
20056 |
++ bool "Automatically emulate sigreturn trampolines" |
20057 |
++ depends on PAX_EMUTRAMP && PARISC |
20058 |
++ default y |
20059 |
++ help |
20060 |
++ Enabling this option will have the kernel automatically detect |
20061 |
++ and emulate signal return trampolines executing on the stack |
20062 |
++ that would otherwise lead to task termination. |
20063 |
+ |
20064 |
-+ if (TREE_CODE(TREE_TYPE(ptr1_rhs)) != POINTER_TYPE && TREE_CODE(TREE_TYPE(ptr2_rhs)) != POINTER_TYPE) |
20065 |
-+ return false; |
20066 |
++ This solution is intended as a temporary one for users with |
20067 |
++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, |
20068 |
++ Modula-3 runtime, etc) or executables linked to such, basically |
20069 |
++ everything that does not specify its own SA_RESTORER function in |
20070 |
++ normal executable memory like glibc 2.1+ does. |
20071 |
+ |
20072 |
-+ return true; |
20073 |
-+} |
20074 |
++ On parisc you MUST enable this option, otherwise your system will |
20075 |
++ not even boot. |
20076 |
+ |
20077 |
-+static tree handle_comparison_code_class(interesting_stmts_t expand_from, gassign *stmt, tree new_rhs1, tree new_rhs2) |
20078 |
-+{ |
20079 |
-+ tree rhs1, rhs2, lhs; |
20080 |
++ NOTE: this feature cannot be disabled on a per executable basis |
20081 |
++ and since it *does* open up a loophole in the protection provided |
20082 |
++ by non-executable pages, the best solution is to not have any |
20083 |
++ files on your system that would require this option. |
20084 |
+ |
20085 |
-+ rhs1 = gimple_assign_rhs1(stmt); |
20086 |
-+ if (!is_gimple_constant(rhs1) && new_rhs1 != NULL_TREE) |
20087 |
-+ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs1), new_rhs1, rhs1, BEFORE_STMT); |
20088 |
++config PAX_MPROTECT |
20089 |
++ bool "Restrict mprotect()" |
20090 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20091 |
++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) |
20092 |
++ help |
20093 |
++ Enabling this option will prevent programs from |
20094 |
++ - changing the executable status of memory pages that were |
20095 |
++ not originally created as executable, |
20096 |
++ - making read-only executable pages writable again, |
20097 |
++ - creating executable pages from anonymous memory, |
20098 |
++ - making read-only-after-relocations (RELRO) data pages writable again. |
20099 |
+ |
20100 |
-+ lhs = gimple_assign_lhs(stmt); |
20101 |
-+ if (new_rhs2 == NULL_TREE) |
20102 |
-+ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
20103 |
++ You should say Y here to complete the protection provided by |
20104 |
++ the enforcement of non-executable pages. |
20105 |
+ |
20106 |
-+ rhs2 = gimple_assign_rhs2(stmt); |
20107 |
-+ if (!is_gimple_constant(rhs2)) |
20108 |
-+ check_size_overflow(expand_from, stmt, TREE_TYPE(new_rhs2), new_rhs2, rhs2, BEFORE_STMT); |
20109 |
-+ return create_assign(expand_from->visited, stmt, lhs, AFTER_STMT); |
20110 |
-+} |
20111 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
20112 |
++ this feature on a per file basis. |
20113 |
+ |
20114 |
-+static tree handle_binary_ops(interesting_stmts_t expand_from, tree lhs) |
20115 |
-+{ |
20116 |
-+ enum intentional_overflow_type res; |
20117 |
-+ tree rhs1, rhs2, new_lhs; |
20118 |
-+ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); |
20119 |
-+ tree new_rhs1 = NULL_TREE; |
20120 |
-+ tree new_rhs2 = NULL_TREE; |
20121 |
++config PAX_MPROTECT_COMPAT |
20122 |
++ bool "Use legacy/compat protection demoting (read help)" |
20123 |
++ depends on PAX_MPROTECT |
20124 |
++ default n |
20125 |
++ help |
20126 |
++ The current implementation of PAX_MPROTECT denies RWX allocations/mprotects |
20127 |
++ by sending the proper error code to the application. For some older |
20128 |
++ userland, this can cause problems with applications that assume such |
20129 |
++ allocations will not be prevented by PaX or SELinux and other access |
20130 |
++ control systems and have no fallback mechanisms. For modern distros, |
20131 |
++ this option should generally be set to 'N'. |
20132 |
++ |
20133 |
++config PAX_ELFRELOCS |
20134 |
++ bool "Allow ELF text relocations (read help)" |
20135 |
++ depends on PAX_MPROTECT |
20136 |
++ default n |
20137 |
++ help |
20138 |
++ Non-executable pages and mprotect() restrictions are effective |
20139 |
++ in preventing the introduction of new executable code into an |
20140 |
++ attacked task's address space. There remain only two venues |
20141 |
++ for this kind of attack: if the attacker can execute already |
20142 |
++ existing code in the attacked task then he can either have it |
20143 |
++ create and mmap() a file containing his code or have it mmap() |
20144 |
++ an already existing ELF library that does not have position |
20145 |
++ independent code in it and use mprotect() on it to make it |
20146 |
++ writable and copy his code there. While protecting against |
20147 |
++ the former approach is beyond PaX, the latter can be prevented |
20148 |
++ by having only PIC ELF libraries on one's system (which do not |
20149 |
++ need to relocate their code). If you are sure this is your case, |
20150 |
++ as is the case with all modern Linux distributions, then leave |
20151 |
++ this option disabled. You should say 'n' here. |
20152 |
+ |
20153 |
-+ if (is_ptr_diff(def_stmt)) |
20154 |
-+ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
20155 |
++config PAX_ETEXECRELOCS |
20156 |
++ bool "Allow ELF ET_EXEC text relocations" |
20157 |
++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC) |
20158 |
++ select PAX_ELFRELOCS |
20159 |
++ default y |
20160 |
++ help |
20161 |
++ On some architectures there are incorrectly created applications |
20162 |
++ that require text relocations and would not work without enabling |
20163 |
++ this option. If you are an alpha, ia64 or parisc user, you should |
20164 |
++ enable this option and disable it once you have made sure that |
20165 |
++ none of your applications need it. |
20166 |
+ |
20167 |
-+ rhs1 = gimple_assign_rhs1(def_stmt); |
20168 |
-+ rhs2 = gimple_assign_rhs2(def_stmt); |
20169 |
++config PAX_EMUPLT |
20170 |
++ bool "Automatically emulate ELF PLT" |
20171 |
++ depends on PAX_MPROTECT && (ALPHA || PARISC || SPARC) |
20172 |
++ default y |
20173 |
++ help |
20174 |
++ Enabling this option will have the kernel automatically detect |
20175 |
++ and emulate the Procedure Linkage Table entries in ELF files. |
20176 |
++ On some architectures such entries are in writable memory, and |
20177 |
++ become non-executable leading to task termination. Therefore |
20178 |
++ it is mandatory that you enable this option on alpha, parisc, |
20179 |
++ sparc and sparc64, otherwise your system would not even boot. |
20180 |
+ |
20181 |
-+ /* no DImode/TImode division in the 32/64 bit kernel */ |
20182 |
-+ switch (gimple_assign_rhs_code(def_stmt)) { |
20183 |
-+ case RDIV_EXPR: |
20184 |
-+ case TRUNC_DIV_EXPR: |
20185 |
-+ case CEIL_DIV_EXPR: |
20186 |
-+ case FLOOR_DIV_EXPR: |
20187 |
-+ case ROUND_DIV_EXPR: |
20188 |
-+ case TRUNC_MOD_EXPR: |
20189 |
-+ case CEIL_MOD_EXPR: |
20190 |
-+ case FLOOR_MOD_EXPR: |
20191 |
-+ case ROUND_MOD_EXPR: |
20192 |
-+ case EXACT_DIV_EXPR: |
20193 |
-+ case POINTER_PLUS_EXPR: |
20194 |
-+ case BIT_AND_EXPR: |
20195 |
-+ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
20196 |
-+ default: |
20197 |
-+ break; |
20198 |
-+ } |
20199 |
++ NOTE: this feature *does* open up a loophole in the protection |
20200 |
++ provided by the non-executable pages, therefore the proper |
20201 |
++ solution is to modify the toolchain to produce a PLT that does |
20202 |
++ not need to be writable. |
20203 |
+ |
20204 |
-+ new_lhs = handle_integer_truncation(expand_from, lhs); |
20205 |
-+ if (new_lhs != NULL_TREE) |
20206 |
-+ return new_lhs; |
20207 |
++config PAX_DLRESOLVE |
20208 |
++ bool 'Emulate old glibc resolver stub' |
20209 |
++ depends on PAX_EMUPLT && SPARC |
20210 |
++ default n |
20211 |
++ help |
20212 |
++ This option is needed if userland has an old glibc (before 2.4) |
20213 |
++ that puts a 'save' instruction into the runtime generated resolver |
20214 |
++ stub that needs special emulation. |
20215 |
+ |
20216 |
-+ if (TREE_CODE(rhs1) == SSA_NAME) |
20217 |
-+ new_rhs1 = expand(expand_from, rhs1); |
20218 |
-+ if (TREE_CODE(rhs2) == SSA_NAME) |
20219 |
-+ new_rhs2 = expand(expand_from, rhs2); |
20220 |
++config PAX_KERNEXEC |
20221 |
++ bool "Enforce non-executable kernel pages" |
20222 |
++ default y if GRKERNSEC_CONFIG_AUTO && (!X86 || GRKERNSEC_CONFIG_VIRT_NONE || (GRKERNSEC_CONFIG_VIRT_EPT && GRKERNSEC_CONFIG_VIRT_GUEST) || (GRKERNSEC_CONFIG_VIRT_EPT && GRKERNSEC_CONFIG_VIRT_KVM)) |
20223 |
++ depends on (X86 || (ARM && (CPU_V6 || CPU_V6K || CPU_V7) && !(ARM_LPAE && MODULES))) && !XEN |
20224 |
++ select PAX_PER_CPU_PGD if X86_64 || (X86_32 && X86_PAE) |
20225 |
++ select PAX_KERNEXEC_PLUGIN if X86_64 |
20226 |
++ select ARM_KERNMEM_PERMS if ARM |
20227 |
++ help |
20228 |
++ This is the kernel land equivalent of PAGEEXEC and MPROTECT, |
20229 |
++ that is, enabling this option will make it harder to inject |
20230 |
++ and execute 'foreign' code in kernel memory itself. |
20231 |
+ |
20232 |
-+ res = add_mul_intentional_overflow(def_stmt); |
20233 |
-+ if (res != NO_INTENTIONAL_OVERFLOW) { |
20234 |
-+ new_lhs = dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); |
20235 |
-+ insert_cast_expr(expand_from->visited, as_a_gassign(get_def_stmt(new_lhs)), res); |
20236 |
-+ return new_lhs; |
20237 |
-+ } |
20238 |
++ Note that on amd64, CONFIG_EFI enabled with "efi=old_map" on |
20239 |
++ the kernel command-line will result in an RWX physical map. |
20240 |
+ |
20241 |
-+ if (skip_expr_on_double_type(def_stmt)) { |
20242 |
-+ new_lhs = dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); |
20243 |
-+ insert_cast_expr(expand_from->visited, as_a_gassign(get_def_stmt(new_lhs)), NO_INTENTIONAL_OVERFLOW); |
20244 |
-+ return new_lhs; |
20245 |
-+ } |
20246 |
++ Likewise, the EFI runtime services are necessarily mapped as |
20247 |
++ RWX. If CONFIG_EFI is enabled on an EFI-capable system, it |
20248 |
++ is recommended that you boot with "noefi" on the kernel |
20249 |
++ command-line if possible to eliminate the mapping. |
20250 |
+ |
20251 |
-+ if (is_a_neg_overflow(def_stmt, rhs2)) |
20252 |
-+ return handle_intentional_overflow(expand_from, true, def_stmt, new_rhs1, NULL_TREE); |
20253 |
-+ if (is_a_neg_overflow(def_stmt, rhs1)) |
20254 |
-+ return handle_intentional_overflow(expand_from, true, def_stmt, new_rhs2, new_rhs2); |
20255 |
++choice |
20256 |
++ prompt "Return Address Instrumentation Method" |
20257 |
++ default PAX_KERNEXEC_PLUGIN_METHOD_BTS |
20258 |
++ depends on PAX_KERNEXEC_PLUGIN |
20259 |
++ help |
20260 |
++ Select the method used to instrument function pointer dereferences. |
20261 |
++ Note that binary modules cannot be instrumented by this approach. |
20262 |
+ |
20263 |
++ Note that the implementation requires a gcc with plugin support, |
20264 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20265 |
++ headers explicitly in addition to the normal gcc package. |
20266 |
+ |
20267 |
-+ if (is_a_constant_overflow(def_stmt, rhs2)) |
20268 |
-+ return handle_intentional_overflow(expand_from, !is_a_cast_and_const_overflow(rhs1), def_stmt, new_rhs1, NULL_TREE); |
20269 |
-+ if (is_a_constant_overflow(def_stmt, rhs1)) |
20270 |
-+ return handle_intentional_overflow(expand_from, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, new_rhs2); |
20271 |
++ config PAX_KERNEXEC_PLUGIN_METHOD_BTS |
20272 |
++ bool "bts" |
20273 |
++ help |
20274 |
++ This method is compatible with binary only modules but has |
20275 |
++ a higher runtime overhead. |
20276 |
+ |
20277 |
-+ // the const is between 0 and (signed) MAX |
20278 |
-+ if (is_gimple_constant(rhs1)) |
20279 |
-+ new_rhs1 = create_assign(expand_from->visited, def_stmt, rhs1, BEFORE_STMT); |
20280 |
-+ if (is_gimple_constant(rhs2)) |
20281 |
-+ new_rhs2 = create_assign(expand_from->visited, def_stmt, rhs2, BEFORE_STMT); |
20282 |
++ config PAX_KERNEXEC_PLUGIN_METHOD_OR |
20283 |
++ bool "or" |
20284 |
++ depends on !PARAVIRT |
20285 |
++ help |
20286 |
++ This method is incompatible with binary only modules but has |
20287 |
++ a lower runtime overhead. |
20288 |
++endchoice |
20289 |
+ |
20290 |
-+ if (TREE_CODE_CLASS(gimple_assign_rhs_code(def_stmt)) == tcc_comparison) |
20291 |
-+ return handle_comparison_code_class(expand_from, def_stmt, new_rhs1, new_rhs2); |
20292 |
++config PAX_KERNEXEC_PLUGIN_METHOD |
20293 |
++ string |
20294 |
++ default "bts" if PAX_KERNEXEC_PLUGIN_METHOD_BTS |
20295 |
++ default "or" if PAX_KERNEXEC_PLUGIN_METHOD_OR |
20296 |
++ default "" |
20297 |
+ |
20298 |
-+ if (uconst_neg_intentional_overflow(def_stmt)) { |
20299 |
-+ inform(gimple_location(def_stmt), "%s: gcc intentional overflow", __func__); |
20300 |
-+ gcc_unreachable(); |
20301 |
-+ } |
20302 |
++config PAX_KERNEXEC_MODULE_TEXT |
20303 |
++ int "Minimum amount of memory reserved for module code" |
20304 |
++ default "8" if (!GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_SERVER) |
20305 |
++ default "12" if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_DESKTOP) |
20306 |
++ depends on PAX_KERNEXEC && X86_32 |
20307 |
++ help |
20308 |
++ Due to implementation details the kernel must reserve a fixed |
20309 |
++ amount of memory for runtime allocated code (such as modules) |
20310 |
++ at compile time that cannot be changed at runtime. Here you |
20311 |
++ can specify the minimum amount in MB that will be reserved. |
20312 |
++ Due to the same implementation details this size will always |
20313 |
++ be rounded up to the next 2/4 MB boundary (depends on PAE) so |
20314 |
++ the actually available memory for runtime allocated code will |
20315 |
++ usually be more than this minimum. |
20316 |
+ |
20317 |
-+ return dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); |
20318 |
-+} |
20319 |
++ The default 4 MB should be enough for most users but if you have |
20320 |
++ an excessive number of modules (e.g., most distribution configs |
20321 |
++ compile many drivers as modules) or use huge modules such as |
20322 |
++ nvidia's kernel driver, you will need to adjust this amount. |
20323 |
++ A good rule of thumb is to look at your currently loaded kernel |
20324 |
++ modules and add up their sizes. |
20325 |
+ |
20326 |
-+#if BUILDING_GCC_VERSION >= 4006 |
20327 |
-+static tree get_new_rhs(interesting_stmts_t expand_from, tree size_overflow_type, tree rhs) |
20328 |
-+{ |
20329 |
-+ if (is_gimple_constant(rhs)) |
20330 |
-+ return cast_a_tree(size_overflow_type, rhs); |
20331 |
-+ if (TREE_CODE(rhs) != SSA_NAME) |
20332 |
-+ return NULL_TREE; |
20333 |
-+ return expand(expand_from, rhs); |
20334 |
-+} |
20335 |
++endmenu |
20336 |
+ |
20337 |
-+static tree handle_ternary_ops(interesting_stmts_t expand_from, tree lhs) |
20338 |
-+{ |
20339 |
-+ tree rhs1, rhs2, rhs3, new_rhs1, new_rhs2, new_rhs3, size_overflow_type; |
20340 |
-+ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); |
20341 |
++menu "Address Space Layout Randomization" |
20342 |
++ depends on PAX |
20343 |
+ |
20344 |
-+ size_overflow_type = get_size_overflow_type(expand_from->visited, def_stmt, lhs); |
20345 |
++config PAX_ASLR |
20346 |
++ bool "Address Space Layout Randomization" |
20347 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20348 |
++ help |
20349 |
++ Many if not most exploit techniques rely on the knowledge of |
20350 |
++ certain addresses in the attacked program. The following options |
20351 |
++ will allow the kernel to apply a certain amount of randomization |
20352 |
++ to specific parts of the program thereby forcing an attacker to |
20353 |
++ guess them in most cases. Any failed guess will most likely crash |
20354 |
++ the attacked program which allows the kernel to detect such attempts |
20355 |
++ and react on them. PaX itself provides no reaction mechanisms, |
20356 |
++ instead it is strongly encouraged that you make use of grsecurity's |
20357 |
++ (http://www.grsecurity.net/) built-in crash detection features or |
20358 |
++ develop one yourself. |
20359 |
+ |
20360 |
-+ rhs1 = gimple_assign_rhs1(def_stmt); |
20361 |
-+ rhs2 = gimple_assign_rhs2(def_stmt); |
20362 |
-+ rhs3 = gimple_assign_rhs3(def_stmt); |
20363 |
-+ new_rhs1 = get_new_rhs(expand_from, size_overflow_type, rhs1); |
20364 |
-+ new_rhs2 = get_new_rhs(expand_from, size_overflow_type, rhs2); |
20365 |
-+ new_rhs3 = get_new_rhs(expand_from, size_overflow_type, rhs3); |
20366 |
++ By saying Y here you can choose to randomize the following areas: |
20367 |
++ - top of the task's kernel stack |
20368 |
++ - top of the task's userland stack |
20369 |
++ - base address for mmap() requests that do not specify one |
20370 |
++ (this includes all libraries) |
20371 |
++ - base address of the main executable |
20372 |
+ |
20373 |
-+ return dup_assign(expand_from->visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3); |
20374 |
-+} |
20375 |
-+#endif |
20376 |
++ It is strongly recommended to say Y here as address space layout |
20377 |
++ randomization has negligible impact on performance yet it provides |
20378 |
++ a very effective protection. |
20379 |
+ |
20380 |
-+static tree expand_visited(struct visited *visited, gimple def_stmt) |
20381 |
-+{ |
20382 |
-+ gimple_stmt_iterator gsi; |
20383 |
-+ enum gimple_code code = gimple_code(def_stmt); |
20384 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
20385 |
++ this feature on a per file basis. |
20386 |
+ |
20387 |
-+ if (code == GIMPLE_ASM) |
20388 |
-+ return NULL_TREE; |
20389 |
++config PAX_RANDKSTACK |
20390 |
++ bool "Randomize kernel stack base" |
20391 |
++ default y if GRKERNSEC_CONFIG_AUTO && !(GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_VIRTUALBOX) |
20392 |
++ depends on X86_TSC && X86 |
20393 |
++ help |
20394 |
++ By saying Y here the kernel will randomize every task's kernel |
20395 |
++ stack on every system call. This will not only force an attacker |
20396 |
++ to guess it but also prevent him from making use of possible |
20397 |
++ leaked information about it. |
20398 |
+ |
20399 |
-+ gsi = gsi_for_stmt(def_stmt); |
20400 |
-+ gsi_next(&gsi); |
20401 |
++ Since the kernel stack is a rather scarce resource, randomization |
20402 |
++ may cause unexpected stack overflows, therefore you should very |
20403 |
++ carefully test your system. Note that once enabled in the kernel |
20404 |
++ configuration, this feature cannot be disabled on a per file basis. |
20405 |
+ |
20406 |
-+ if (gimple_code(def_stmt) == GIMPLE_PHI && gsi_end_p(gsi)) |
20407 |
-+ return NULL_TREE; |
20408 |
-+ return get_my_stmt_lhs(visited, def_stmt); |
20409 |
-+} |
20410 |
++config PAX_RANDUSTACK |
20411 |
++ bool |
20412 |
+ |
20413 |
-+tree expand(interesting_stmts_t expand_from, tree lhs) |
20414 |
-+{ |
20415 |
-+ gimple def_stmt; |
20416 |
++config PAX_RANDMMAP |
20417 |
++ bool "Randomize user stack and mmap() bases" |
20418 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20419 |
++ depends on PAX_ASLR |
20420 |
++ select PAX_RANDUSTACK |
20421 |
++ help |
20422 |
++ By saying Y here the kernel will randomize every task's userland |
20423 |
++ stack and use a randomized base address for mmap() requests that |
20424 |
++ do not specify one themselves. |
20425 |
+ |
20426 |
-+ def_stmt = get_def_stmt(lhs); |
20427 |
++ The stack randomization is done in two steps where the second |
20428 |
++ one may apply a big amount of shift to the top of the stack and |
20429 |
++ cause problems for programs that want to use lots of memory (more |
20430 |
++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). |
20431 |
+ |
20432 |
-+ if (!def_stmt || gimple_code(def_stmt) == GIMPLE_NOP) |
20433 |
-+ return NULL_TREE; |
20434 |
++ As a result of mmap randomization all dynamically loaded libraries |
20435 |
++ will appear at random addresses and therefore be harder to exploit |
20436 |
++ by a technique where an attacker attempts to execute library code |
20437 |
++ for his purposes (e.g. spawn a shell from an exploited program that |
20438 |
++ is running at an elevated privilege level). |
20439 |
+ |
20440 |
-+ if (pointer_set_contains(expand_from->visited->my_stmts, def_stmt)) |
20441 |
-+ return lhs; |
20442 |
++ Furthermore, if a program is relinked as a dynamic ELF file, its |
20443 |
++ base address will be randomized as well, completing the full |
20444 |
++ randomization of the address space layout. Attacking such programs |
20445 |
++ becomes a guess game. You can find an example of doing this at |
20446 |
++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at |
20447 |
++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz . |
20448 |
+ |
20449 |
-+ if (pointer_set_contains(expand_from->visited->stmts, def_stmt)) |
20450 |
-+ return expand_visited(expand_from->visited, def_stmt); |
20451 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this |
20452 |
++ feature on a per file basis. |
20453 |
+ |
20454 |
-+ if (is_gimple_constant(lhs)) |
20455 |
-+ return NULL_TREE; |
20456 |
-+ if (skip_types(lhs)) |
20457 |
-+ return NULL_TREE; |
20458 |
++endmenu |
20459 |
+ |
20460 |
-+ switch (gimple_code(def_stmt)) { |
20461 |
-+ case GIMPLE_PHI: |
20462 |
-+ return handle_phi(expand_from, lhs); |
20463 |
-+ case GIMPLE_CALL: |
20464 |
-+ case GIMPLE_ASM: |
20465 |
-+ if (is_size_overflow_asm(def_stmt)) |
20466 |
-+ return expand(expand_from, get_size_overflow_asm_input(as_a_gasm(def_stmt))); |
20467 |
-+ return create_assign(expand_from->visited, def_stmt, lhs, AFTER_STMT); |
20468 |
-+ case GIMPLE_ASSIGN: |
20469 |
-+ switch (gimple_num_ops(def_stmt)) { |
20470 |
-+ case 2: |
20471 |
-+ return handle_unary_ops(expand_from, as_a_gassign(def_stmt)); |
20472 |
-+ case 3: |
20473 |
-+ return handle_binary_ops(expand_from, lhs); |
20474 |
-+#if BUILDING_GCC_VERSION >= 4006 |
20475 |
-+ case 4: |
20476 |
-+ return handle_ternary_ops(expand_from, lhs); |
20477 |
-+#endif |
20478 |
-+ } |
20479 |
-+ default: |
20480 |
-+ debug_gimple_stmt(def_stmt); |
20481 |
-+ error("%s: unknown gimple code", __func__); |
20482 |
-+ gcc_unreachable(); |
20483 |
-+ } |
20484 |
-+} |
20485 |
-diff --git a/tools/gcc/stackleak_plugin.c b/tools/gcc/stackleak_plugin.c |
20486 |
-new file mode 100644 |
20487 |
-index 0000000..8b69bd4 |
20488 |
---- /dev/null |
20489 |
-+++ b/tools/gcc/stackleak_plugin.c |
20490 |
-@@ -0,0 +1,350 @@ |
20491 |
-+/* |
20492 |
-+ * Copyright 2011-2016 by the PaX Team <pageexec@××××××××.hu> |
20493 |
-+ * Licensed under the GPL v2 |
20494 |
-+ * |
20495 |
-+ * Note: the choice of the license means that the compilation process is |
20496 |
-+ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
20497 |
-+ * but for the kernel it doesn't matter since it doesn't link against |
20498 |
-+ * any of the gcc libraries |
20499 |
-+ * |
20500 |
-+ * gcc plugin to help implement various PaX features |
20501 |
-+ * |
20502 |
-+ * - track lowest stack pointer |
20503 |
-+ * |
20504 |
-+ * TODO: |
20505 |
-+ * - initialize all local variables |
20506 |
-+ * |
20507 |
-+ * BUGS: |
20508 |
-+ * - none known |
20509 |
-+ */ |
20510 |
++menu "Miscellaneous hardening features" |
20511 |
+ |
20512 |
-+#include "gcc-common.h" |
20513 |
++config PAX_MEMORY_SANITIZE |
20514 |
++ bool "Sanitize all freed memory" |
20515 |
++ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_PRIORITY_SECURITY) |
20516 |
++ help |
20517 |
++ By saying Y here the kernel will erase memory pages and slab objects |
20518 |
++ as soon as they are freed. This in turn reduces the lifetime of data |
20519 |
++ stored in them, making it less likely that sensitive information such |
20520 |
++ as passwords, cryptographic secrets, etc stay in memory for too long. |
20521 |
+ |
20522 |
-+int plugin_is_GPL_compatible; |
20523 |
++ This is especially useful for programs whose runtime is short, long |
20524 |
++ lived processes and the kernel itself benefit from this as long as |
20525 |
++ they ensure timely freeing of memory that may hold sensitive |
20526 |
++ information. |
20527 |
+ |
20528 |
-+static int track_frame_size = -1; |
20529 |
-+static const char track_function[] = "pax_track_stack"; |
20530 |
-+static const char check_function[] = "pax_check_alloca"; |
20531 |
-+static GTY(()) tree track_function_decl; |
20532 |
-+static GTY(()) tree check_function_decl; |
20533 |
-+static bool init_locals; |
20534 |
++ A nice side effect of the sanitization of slab objects is the |
20535 |
++ reduction of possible info leaks caused by padding bytes within the |
20536 |
++ leaky structures. Use-after-free bugs for structures containing |
20537 |
++ pointers can also be detected as dereferencing the sanitized pointer |
20538 |
++ will generate an access violation. |
20539 |
+ |
20540 |
-+static struct plugin_info stackleak_plugin_info = { |
20541 |
-+ .version = "201602181345", |
20542 |
-+ .help = "track-lowest-sp=nn\ttrack sp in functions whose frame size is at least nn bytes\n" |
20543 |
-+// "initialize-locals\t\tforcibly initialize all stack frames\n" |
20544 |
-+}; |
20545 |
++ The tradeoff is performance impact, on a single CPU system kernel |
20546 |
++ compilation sees a 3% slowdown, other systems and workloads may vary |
20547 |
++ and you are advised to test this feature on your expected workload |
20548 |
++ before deploying it. |
20549 |
+ |
20550 |
-+static void stackleak_check_alloca(gimple_stmt_iterator *gsi) |
20551 |
-+{ |
20552 |
-+ gimple stmt; |
20553 |
-+ gcall *check_alloca; |
20554 |
-+ tree alloca_size; |
20555 |
-+ cgraph_node_ptr node; |
20556 |
-+ int frequency; |
20557 |
-+ basic_block bb; |
20558 |
++ The slab sanitization feature excludes a few slab caches per default |
20559 |
++ for performance reasons. To extend the feature to cover those as |
20560 |
++ well, pass "pax_sanitize_slab=full" as kernel command line parameter. |
20561 |
+ |
20562 |
-+ // insert call to void pax_check_alloca(unsigned long size) |
20563 |
-+ alloca_size = gimple_call_arg(gsi_stmt(*gsi), 0); |
20564 |
-+ stmt = gimple_build_call(check_function_decl, 1, alloca_size); |
20565 |
-+ check_alloca = as_a_gcall(stmt); |
20566 |
-+ gsi_insert_before(gsi, check_alloca, GSI_SAME_STMT); |
20567 |
++ To reduce the performance penalty by sanitizing pages only, albeit |
20568 |
++ limiting the effectiveness of this feature at the same time, slab |
20569 |
++ sanitization can be disabled with the kernel command line parameter |
20570 |
++ "pax_sanitize_slab=off". |
20571 |
+ |
20572 |
-+ // update the cgraph |
20573 |
-+ bb = gimple_bb(check_alloca); |
20574 |
-+ node = cgraph_get_create_node(check_function_decl); |
20575 |
-+ gcc_assert(node); |
20576 |
-+ frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); |
20577 |
-+ cgraph_create_edge(cgraph_get_node(current_function_decl), node, check_alloca, bb->count, frequency, bb->loop_depth); |
20578 |
-+} |
20579 |
++ Note that this feature does not protect data stored in live pages, |
20580 |
++ e.g., process memory swapped to disk may stay there for a long time. |
20581 |
+ |
20582 |
-+static void stackleak_add_instrumentation(gimple_stmt_iterator *gsi, bool after) |
20583 |
-+{ |
20584 |
-+ gimple stmt; |
20585 |
-+ gcall *track_stack; |
20586 |
-+ cgraph_node_ptr node; |
20587 |
-+ int frequency; |
20588 |
-+ basic_block bb; |
20589 |
++config PAX_MEMORY_STACKLEAK |
20590 |
++ bool "Sanitize kernel stack" |
20591 |
++ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_PRIORITY_SECURITY) |
20592 |
++ depends on X86 && GCC_PLUGINS |
20593 |
++ help |
20594 |
++ By saying Y here the kernel will erase the kernel stack before it |
20595 |
++ returns from a system call. This in turn reduces the information |
20596 |
++ that a kernel stack leak bug can reveal. |
20597 |
+ |
20598 |
-+ // insert call to void pax_track_stack(void) |
20599 |
-+ stmt = gimple_build_call(track_function_decl, 0); |
20600 |
-+ track_stack = as_a_gcall(stmt); |
20601 |
-+ if (after) |
20602 |
-+ gsi_insert_after(gsi, track_stack, GSI_CONTINUE_LINKING); |
20603 |
-+ else |
20604 |
-+ gsi_insert_before(gsi, track_stack, GSI_SAME_STMT); |
20605 |
++ Note that such a bug can still leak information that was put on |
20606 |
++ the stack by the current system call (the one eventually triggering |
20607 |
++ the bug) but traces of earlier system calls on the kernel stack |
20608 |
++ cannot leak anymore. |
20609 |
+ |
20610 |
-+ // update the cgraph |
20611 |
-+ bb = gimple_bb(track_stack); |
20612 |
-+ node = cgraph_get_create_node(track_function_decl); |
20613 |
-+ gcc_assert(node); |
20614 |
-+ frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); |
20615 |
-+ cgraph_create_edge(cgraph_get_node(current_function_decl), node, track_stack, bb->count, frequency, bb->loop_depth); |
20616 |
-+} |
20617 |
++ The tradeoff is performance impact: on a single CPU system kernel |
20618 |
++ compilation sees a 1% slowdown, other systems and workloads may vary |
20619 |
++ and you are advised to test this feature on your expected workload |
20620 |
++ before deploying it. |
20621 |
+ |
20622 |
-+static bool is_alloca(gimple stmt) |
20623 |
-+{ |
20624 |
-+ if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA)) |
20625 |
-+ return true; |
20626 |
++ Note that the full feature requires a gcc with plugin support, |
20627 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20628 |
++ headers explicitly in addition to the normal gcc package. Using |
20629 |
++ older gcc versions means that functions with large enough stack |
20630 |
++ frames may leave uninitialized memory behind that may be exposed |
20631 |
++ to a later syscall leaking the stack. |
20632 |
+ |
20633 |
-+#if BUILDING_GCC_VERSION >= 4007 |
20634 |
-+ if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA_WITH_ALIGN)) |
20635 |
-+ return true; |
20636 |
-+#endif |
20637 |
++config PAX_MEMORY_STRUCTLEAK |
20638 |
++ bool "Forcibly initialize local variables copied to userland" |
20639 |
++ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_PRIORITY_SECURITY) |
20640 |
++ depends on GCC_PLUGINS |
20641 |
++ help |
20642 |
++ By saying Y here the kernel will zero initialize some local |
20643 |
++ variables that are going to be copied to userland. This in |
20644 |
++ turn prevents unintended information leakage from the kernel |
20645 |
++ stack should later code forget to explicitly set all parts of |
20646 |
++ the copied variable. |
20647 |
+ |
20648 |
-+ return false; |
20649 |
-+} |
20650 |
++ The tradeoff is less performance impact than PAX_MEMORY_STACKLEAK |
20651 |
++ at a much smaller coverage. |
20652 |
+ |
20653 |
-+static unsigned int stackleak_tree_instrument_execute(void) |
20654 |
-+{ |
20655 |
-+ basic_block bb, entry_bb; |
20656 |
-+ bool prologue_instrumented = false, is_leaf = true; |
20657 |
++ Note that the implementation requires a gcc with plugin support, |
20658 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20659 |
++ headers explicitly in addition to the normal gcc package. |
20660 |
+ |
20661 |
-+ entry_bb = ENTRY_BLOCK_PTR_FOR_FN(cfun)->next_bb; |
20662 |
++config PAX_MEMORY_UDEREF |
20663 |
++ bool "Prevent invalid userland pointer dereference" |
20664 |
++ default y if GRKERNSEC_CONFIG_AUTO && !(X86_64 && GRKERNSEC_CONFIG_PRIORITY_PERF) && !(X86_64 && GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_VIRTUALBOX) && (!X86 || GRKERNSEC_CONFIG_VIRT_NONE || GRKERNSEC_CONFIG_VIRT_EPT) |
20665 |
++ depends on (X86 || (ARM && (CPU_V6 || CPU_V6K || CPU_V7) && !ARM_LPAE)) && !UML_X86 && !XEN |
20666 |
++ select PAX_PER_CPU_PGD if X86_64 |
20667 |
++ help |
20668 |
++ By saying Y here the kernel will be prevented from dereferencing |
20669 |
++ userland pointers in contexts where the kernel expects only kernel |
20670 |
++ pointers. This is both a useful runtime debugging feature and a |
20671 |
++ security measure that prevents exploiting a class of kernel bugs. |
20672 |
+ |
20673 |
-+ // 1. loop through BBs and GIMPLE statements |
20674 |
-+ FOR_EACH_BB_FN(bb, cfun) { |
20675 |
-+ gimple_stmt_iterator gsi; |
20676 |
++ The tradeoff is that some virtualization solutions may experience |
20677 |
++ a huge slowdown and therefore you should not enable this feature |
20678 |
++ for kernels meant to run in such environments. Whether a given VM |
20679 |
++ solution is affected or not is best determined by simply trying it |
20680 |
++ out, the performance impact will be obvious right on boot as this |
20681 |
++ mechanism engages from very early on. A good rule of thumb is that |
20682 |
++ VMs running on CPUs without hardware virtualization support (i.e., |
20683 |
++ the majority of IA-32 CPUs) will likely experience the slowdown. |
20684 |
+ |
20685 |
-+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
20686 |
-+ gimple stmt; |
20687 |
++ On X86_64 the kernel will make use of PCID support when available |
20688 |
++ (Intel's Westmere, Sandy Bridge, etc) for better security (default) |
20689 |
++ or performance impact. Pass pax_weakuderef on the kernel command |
20690 |
++ line to choose the latter. |
20691 |
+ |
20692 |
-+ stmt = gsi_stmt(gsi); |
20693 |
++config PAX_REFCOUNT |
20694 |
++ bool "Prevent various kernel object reference counter overflows" |
20695 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20696 |
++ depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || MIPS || PPC || SPARC64 || X86) |
20697 |
++ help |
20698 |
++ By saying Y here the kernel will detect and prevent overflowing |
20699 |
++ various (but not all) kinds of object reference counters. Such |
20700 |
++ overflows can normally occur due to bugs only and are often, if |
20701 |
++ not always, exploitable. |
20702 |
+ |
20703 |
-+ if (is_gimple_call(stmt)) |
20704 |
-+ is_leaf = false; |
20705 |
++ The tradeoff is that data structures protected by an overflowed |
20706 |
++ refcount will never be freed and therefore will leak memory. Note |
20707 |
++ that this leak also happens even without this protection but in |
20708 |
++ that case the overflow can eventually trigger the freeing of the |
20709 |
++ data structure while it is still being used elsewhere, resulting |
20710 |
++ in the exploitable situation that this feature prevents. |
20711 |
+ |
20712 |
-+ // gimple match: align 8 built-in BUILT_IN_NORMAL:BUILT_IN_ALLOCA attributes <tree_list 0xb7576450> |
20713 |
-+ if (!is_alloca(stmt)) |
20714 |
-+ continue; |
20715 |
++ Since this has a negligible performance impact, you should enable |
20716 |
++ this feature. |
20717 |
+ |
20718 |
-+ // 2. insert stack overflow check before each __builtin_alloca call |
20719 |
-+ stackleak_check_alloca(&gsi); |
20720 |
++config PAX_CONSTIFY_PLUGIN |
20721 |
++ bool "Automatically constify eligible structures" |
20722 |
++ default y |
20723 |
++ depends on !UML && PAX_KERNEXEC |
20724 |
++ help |
20725 |
++ By saying Y here the compiler will automatically constify a class |
20726 |
++ of types that contain only function pointers. This reduces the |
20727 |
++ kernel's attack surface and also produces a better memory layout. |
20728 |
+ |
20729 |
-+ // 3. insert track call after each __builtin_alloca call |
20730 |
-+ stackleak_add_instrumentation(&gsi, true); |
20731 |
-+ if (bb == entry_bb) |
20732 |
-+ prologue_instrumented = true; |
20733 |
-+ } |
20734 |
-+ } |
20735 |
++ Note that the implementation requires a gcc with plugin support, |
20736 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20737 |
++ headers explicitly in addition to the normal gcc package. |
20738 |
++ |
20739 |
++ Note that if some code really has to modify constified variables |
20740 |
++ then the source code will have to be patched to allow it. Examples |
20741 |
++ can be found in PaX itself (the no_const attribute) and for some |
20742 |
++ out-of-tree modules at http://www.grsecurity.net/~paxguy1/ . |
20743 |
+ |
20744 |
-+ // special cases for some bad linux code: taking the address of static inline functions will materialize them |
20745 |
-+ // but we mustn't instrument some of them as the resulting stack alignment required by the function call ABI |
20746 |
-+ // will break other assumptions regarding the expected (but not otherwise enforced) register clobbering ABI. |
20747 |
-+ // case in point: native_save_fl on amd64 when optimized for size clobbers rdx if it were instrumented here. |
20748 |
-+ if (is_leaf && !TREE_PUBLIC(current_function_decl) && DECL_DECLARED_INLINE_P(current_function_decl)) |
20749 |
-+ return 0; |
20750 |
-+ if (is_leaf && !strncmp(IDENTIFIER_POINTER(DECL_NAME(current_function_decl)), "_paravirt_", 10)) |
20751 |
-+ return 0; |
20752 |
++config PAX_USERCOPY |
20753 |
++ bool "Harden heap object copies between kernel and userland" |
20754 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20755 |
++ depends on ARM || IA64 || PPC || SPARC || X86 |
20756 |
++ depends on GRKERNSEC && (SLAB || SLUB || SLOB) |
20757 |
++ select PAX_USERCOPY_SLABS |
20758 |
++ help |
20759 |
++ By saying Y here the kernel will enforce the size of heap objects |
20760 |
++ when they are copied in either direction between the kernel and |
20761 |
++ userland, even if only a part of the heap object is copied. |
20762 |
+ |
20763 |
-+ // 4. insert track call at the beginning |
20764 |
-+ if (!prologue_instrumented) { |
20765 |
-+ gimple_stmt_iterator gsi; |
20766 |
++ Specifically, this checking prevents information leaking from the |
20767 |
++ kernel heap during kernel to userland copies (if the kernel heap |
20768 |
++ object is otherwise fully initialized) and prevents kernel heap |
20769 |
++ overflows during userland to kernel copies. |
20770 |
+ |
20771 |
-+ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
20772 |
-+ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
20773 |
-+ if (!single_pred_p(bb)) { |
20774 |
-+// gcc_assert(bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP)); |
20775 |
-+ split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
20776 |
-+ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
20777 |
-+ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
20778 |
-+ } |
20779 |
-+ gsi = gsi_after_labels(bb); |
20780 |
-+ stackleak_add_instrumentation(&gsi, false); |
20781 |
-+ } |
20782 |
++ Note that the current implementation provides the strictest bounds |
20783 |
++ checks for the SLUB allocator. |
20784 |
+ |
20785 |
-+ return 0; |
20786 |
-+} |
20787 |
++ Enabling this option also enables per-slab cache protection against |
20788 |
++ data in a given cache being copied into/out of via userland |
20789 |
++ accessors. Though the whitelist of regions will be reduced over |
20790 |
++ time, it notably protects important data structures like task structs. |
20791 |
+ |
20792 |
-+static unsigned int stackleak_final_execute(void) |
20793 |
-+{ |
20794 |
-+ rtx_insn *insn, *next; |
20795 |
++ If frame pointers are enabled on x86, this option will also restrict |
20796 |
++ copies into and out of the kernel stack to local variables within a |
20797 |
++ single frame. |
20798 |
+ |
20799 |
-+ if (cfun->calls_alloca) |
20800 |
-+ return 0; |
20801 |
++ Since this has a negligible performance impact, you should enable |
20802 |
++ this feature. |
20803 |
+ |
20804 |
-+ // keep calls only if function frame is big enough |
20805 |
-+ if (get_frame_size() >= track_frame_size) |
20806 |
-+ return 0; |
20807 |
++config PAX_USERCOPY_DEBUG |
20808 |
++ bool |
20809 |
++ depends on X86 && PAX_USERCOPY |
20810 |
++ default n |
20811 |
+ |
20812 |
-+ // 1. find pax_track_stack calls |
20813 |
-+ for (insn = get_insns(); insn; insn = next) { |
20814 |
-+ // rtl match: (call_insn 8 7 9 3 (call (mem (symbol_ref ("pax_track_stack") [flags 0x41] <function_decl 0xb7470e80 pax_track_stack>) [0 S1 A8]) (4)) -1 (nil) (nil)) |
20815 |
-+ rtx body; |
20816 |
++config PAX_SIZE_OVERFLOW |
20817 |
++ bool "Prevent various integer overflows in function size parameters" |
20818 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20819 |
++ depends on GCC_PLUGINS |
20820 |
++ help |
20821 |
++ By saying Y here the kernel recomputes expressions of function |
20822 |
++ arguments marked by a size_overflow attribute with double integer |
20823 |
++ precision (DImode/TImode for 32/64 bit integer types). |
20824 |
+ |
20825 |
-+ next = NEXT_INSN(insn); |
20826 |
-+ if (!CALL_P(insn)) |
20827 |
-+ continue; |
20828 |
-+ body = PATTERN(insn); |
20829 |
-+ if (GET_CODE(body) != CALL) |
20830 |
-+ continue; |
20831 |
-+ body = XEXP(body, 0); |
20832 |
-+ if (GET_CODE(body) != MEM) |
20833 |
-+ continue; |
20834 |
-+ body = XEXP(body, 0); |
20835 |
-+ if (GET_CODE(body) != SYMBOL_REF) |
20836 |
-+ continue; |
20837 |
-+// if (strcmp(XSTR(body, 0), track_function)) |
20838 |
-+ if (SYMBOL_REF_DECL(body) != track_function_decl) |
20839 |
-+ continue; |
20840 |
-+// warning(0, "track_frame_size: %d %ld %d", cfun->calls_alloca, get_frame_size(), track_frame_size); |
20841 |
-+ // 2. delete call |
20842 |
-+ delete_insn_and_edges(insn); |
20843 |
-+#if BUILDING_GCC_VERSION >= 4007 |
20844 |
-+ if (GET_CODE(next) == NOTE && NOTE_KIND(next) == NOTE_INSN_CALL_ARG_LOCATION) { |
20845 |
-+ insn = next; |
20846 |
-+ next = NEXT_INSN(insn); |
20847 |
-+ delete_insn_and_edges(insn); |
20848 |
-+ } |
20849 |
-+#endif |
20850 |
-+ } |
20851 |
++ The recomputed argument is checked against TYPE_MAX and an event |
20852 |
++ is logged on overflow and the triggering process is killed. |
20853 |
+ |
20854 |
-+// print_simple_rtl(stderr, get_insns()); |
20855 |
-+// print_rtl(stderr, get_insns()); |
20856 |
-+// warning(0, "track_frame_size: %d %ld %d", cfun->calls_alloca, get_frame_size(), track_frame_size); |
20857 |
++ Homepage: https://github.com/ephox-gcc-plugins |
20858 |
+ |
20859 |
-+ return 0; |
20860 |
-+} |
20861 |
++ Note that the implementation requires a gcc with plugin support, |
20862 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20863 |
++ headers explicitly in addition to the normal gcc package. |
20864 |
+ |
20865 |
-+static bool stackleak_track_stack_gate(void) |
20866 |
-+{ |
20867 |
-+ tree section; |
20868 |
++config PAX_LATENT_ENTROPY |
20869 |
++ bool "Generate some entropy during boot and runtime" |
20870 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20871 |
++ depends on GCC_PLUGINS |
20872 |
++ help |
20873 |
++ By saying Y here the kernel will instrument some kernel code to |
20874 |
++ extract some entropy from both original and artificially created |
20875 |
++ program state. This will help especially embedded systems where |
20876 |
++ there is little 'natural' source of entropy normally. The cost |
20877 |
++ is some slowdown of the boot process and fork and irq processing. |
20878 |
+ |
20879 |
-+ if (ix86_cmodel != CM_KERNEL) |
20880 |
-+ return false; |
20881 |
++ When pax_extra_latent_entropy is passed on the kernel command line, |
20882 |
++ entropy will be extracted from up to the first 4GB of RAM while the |
20883 |
++ runtime memory allocator is being initialized. This costs even more |
20884 |
++ slowdown of the boot process. |
20885 |
+ |
20886 |
-+ section = lookup_attribute("section", DECL_ATTRIBUTES(current_function_decl)); |
20887 |
-+ if (section && TREE_VALUE(section)) { |
20888 |
-+ section = TREE_VALUE(TREE_VALUE(section)); |
20889 |
++ Note that the implementation requires a gcc with plugin support, |
20890 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20891 |
++ headers explicitly in addition to the normal gcc package. |
20892 |
+ |
20893 |
-+ if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10)) |
20894 |
-+ return false; |
20895 |
-+ if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13)) |
20896 |
-+ return false; |
20897 |
-+ if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13)) |
20898 |
-+ return false; |
20899 |
-+ if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13)) |
20900 |
-+ return false; |
20901 |
-+ } |
20902 |
++ Note that entropy extracted this way is not cryptographically |
20903 |
++ secure! |
20904 |
+ |
20905 |
-+ return track_frame_size >= 0; |
20906 |
-+} |
20907 |
++config PAX_RAP |
20908 |
++ bool "Prevent code reuse attacks" |
20909 |
++ depends on X86_64 |
20910 |
++ default y if GRKERNSEC_CONFIG_AUTO |
20911 |
++ help |
20912 |
++ By saying Y here the kernel will check indirect control transfers |
20913 |
++ in order to detect and prevent attacks that try to hijack control |
20914 |
++ flow by overwriting code pointers. |
20915 |
+ |
20916 |
-+static void stackleak_start_unit(void *gcc_data, void *user_data) |
20917 |
-+{ |
20918 |
-+ tree fntype; |
20919 |
++ Note that binary modules cannot be instrumented by this approach. |
20920 |
+ |
20921 |
-+ // void pax_track_stack(void) |
20922 |
-+ fntype = build_function_type_list(void_type_node, NULL_TREE); |
20923 |
-+ track_function_decl = build_fn_decl(track_function, fntype); |
20924 |
-+ DECL_ASSEMBLER_NAME(track_function_decl); // for LTO |
20925 |
-+ TREE_PUBLIC(track_function_decl) = 1; |
20926 |
-+ TREE_USED(track_function_decl) = 1; |
20927 |
-+ DECL_EXTERNAL(track_function_decl) = 1; |
20928 |
-+ DECL_ARTIFICIAL(track_function_decl) = 1; |
20929 |
-+ DECL_PRESERVE_P(track_function_decl) = 1; |
20930 |
++ Note that the implementation requires a gcc with plugin support, |
20931 |
++ i.e., gcc 4.5 or newer. You may need to install the supporting |
20932 |
++ headers explicitly in addition to the normal gcc package. |
20933 |
+ |
20934 |
-+ // void pax_check_alloca(unsigned long) |
20935 |
-+ fntype = build_function_type_list(void_type_node, long_unsigned_type_node, NULL_TREE); |
20936 |
-+ check_function_decl = build_fn_decl(check_function, fntype); |
20937 |
-+ DECL_ASSEMBLER_NAME(check_function_decl); // for LTO |
20938 |
-+ TREE_PUBLIC(check_function_decl) = 1; |
20939 |
-+ TREE_USED(check_function_decl) = 1; |
20940 |
-+ DECL_EXTERNAL(check_function_decl) = 1; |
20941 |
-+ DECL_ARTIFICIAL(check_function_decl) = 1; |
20942 |
-+ DECL_PRESERVE_P(check_function_decl) = 1; |
20943 |
-+} |
20944 |
++endmenu |
20945 |
+ |
20946 |
-+static bool stackleak_tree_instrument_gate(void) |
20947 |
-+{ |
20948 |
-+ return stackleak_track_stack_gate(); |
20949 |
-+} |
20950 |
++endmenu |
20951 |
+ |
20952 |
-+#define PASS_NAME stackleak_tree_instrument |
20953 |
-+#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg |
20954 |
-+#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts |
20955 |
-+#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_update_ssa | TODO_rebuild_cgraph_edges |
20956 |
-+#include "gcc-generate-gimple-pass.h" |
20957 |
++source grsecurity/Kconfig |
20958 |
+ |
20959 |
-+static bool stackleak_final_gate(void) |
20960 |
-+{ |
20961 |
-+ return stackleak_track_stack_gate(); |
20962 |
-+} |
20963 |
++endmenu |
20964 |
+ |
20965 |
-+#define PASS_NAME stackleak_final |
20966 |
-+#define TODO_FLAGS_FINISH TODO_dump_func |
20967 |
-+#include "gcc-generate-rtl-pass.h" |
20968 |
++endmenu |
20969 |
+ |
20970 |
-+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
20971 |
+ source security/keys/Kconfig |
20972 |
+ |
20973 |
+ config SECURITY_DMESG_RESTRICT |
20974 |
+@@ -104,7 +1091,7 @@ config INTEL_TXT |
20975 |
+ config LSM_MMAP_MIN_ADDR |
20976 |
+ int "Low address space for LSM to protect from user allocation" |
20977 |
+ depends on SECURITY && SECURITY_SELINUX |
20978 |
+- default 32768 if ARM || (ARM64 && COMPAT) |
20979 |
++ default 32768 if ALPHA || ARM || (ARM64 && COMPAT) || PARISC || SPARC32 |
20980 |
+ default 65536 |
20981 |
+ help |
20982 |
+ This is the portion of low virtual memory which should be protected |
20983 |
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c |
20984 |
+index 913f377..6e392d5 100644 |
20985 |
+--- a/security/apparmor/file.c |
20986 |
++++ b/security/apparmor/file.c |
20987 |
+@@ -348,8 +348,8 @@ static inline bool xindex_is_subset(u32 link, u32 target) |
20988 |
+ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry, |
20989 |
+ struct path *new_dir, struct dentry *new_dentry) |
20990 |
+ { |
20991 |
+- struct path link = { new_dir->mnt, new_dentry }; |
20992 |
+- struct path target = { new_dir->mnt, old_dentry }; |
20993 |
++ struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry }; |
20994 |
++ struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry }; |
20995 |
+ struct path_cond cond = { |
20996 |
+ d_backing_inode(old_dentry)->i_uid, |
20997 |
+ d_backing_inode(old_dentry)->i_mode |
20998 |
+diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h |
20999 |
+index c28b0f2..3b9fee0 100644 |
21000 |
+--- a/security/apparmor/include/policy.h |
21001 |
++++ b/security/apparmor/include/policy.h |
21002 |
+@@ -134,7 +134,7 @@ struct aa_namespace { |
21003 |
+ struct aa_ns_acct acct; |
21004 |
+ struct aa_profile *unconfined; |
21005 |
+ struct list_head sub_ns; |
21006 |
+- atomic_t uniq_null; |
21007 |
++ atomic_unchecked_t uniq_null; |
21008 |
+ long uniq_id; |
21009 |
+ |
21010 |
+ struct dentry *dents[AAFS_NS_SIZEOF]; |
21011 |
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c |
21012 |
+index dec607c..37fe357 100644 |
21013 |
+--- a/security/apparmor/lsm.c |
21014 |
++++ b/security/apparmor/lsm.c |
21015 |
+@@ -176,7 +176,7 @@ static int common_perm_dir_dentry(int op, struct path *dir, |
21016 |
+ struct dentry *dentry, u32 mask, |
21017 |
+ struct path_cond *cond) |
21018 |
+ { |
21019 |
+- struct path path = { dir->mnt, dentry }; |
21020 |
++ struct path path = { .mnt = dir->mnt, .dentry = dentry }; |
21021 |
+ |
21022 |
+ return common_perm(op, &path, mask, cond); |
21023 |
+ } |
21024 |
+@@ -193,7 +193,7 @@ static int common_perm_dir_dentry(int op, struct path *dir, |
21025 |
+ static int common_perm_mnt_dentry(int op, struct vfsmount *mnt, |
21026 |
+ struct dentry *dentry, u32 mask) |
21027 |
+ { |
21028 |
+- struct path path = { mnt, dentry }; |
21029 |
++ struct path path = { .mnt = mnt, .dentry = dentry }; |
21030 |
+ struct path_cond cond = { d_backing_inode(dentry)->i_uid, |
21031 |
+ d_backing_inode(dentry)->i_mode |
21032 |
+ }; |
21033 |
+@@ -315,8 +315,8 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry, |
21034 |
+ |
21035 |
+ profile = aa_current_profile(); |
21036 |
+ if (!unconfined(profile)) { |
21037 |
+- struct path old_path = { old_dir->mnt, old_dentry }; |
21038 |
+- struct path new_path = { new_dir->mnt, new_dentry }; |
21039 |
++ struct path old_path = { .mnt = old_dir->mnt, .dentry = old_dentry }; |
21040 |
++ struct path new_path = { .mnt = new_dir->mnt, .dentry = new_dentry }; |
21041 |
+ struct path_cond cond = { d_backing_inode(old_dentry)->i_uid, |
21042 |
+ d_backing_inode(old_dentry)->i_mode |
21043 |
+ }; |
21044 |
+@@ -677,11 +677,11 @@ static const struct kernel_param_ops param_ops_aalockpolicy = { |
21045 |
+ .get = param_get_aalockpolicy |
21046 |
+ }; |
21047 |
+ |
21048 |
+-static int param_set_audit(const char *val, struct kernel_param *kp); |
21049 |
+-static int param_get_audit(char *buffer, struct kernel_param *kp); |
21050 |
++static int param_set_audit(const char *val, const struct kernel_param *kp); |
21051 |
++static int param_get_audit(char *buffer, const struct kernel_param *kp); |
21052 |
+ |
21053 |
+-static int param_set_mode(const char *val, struct kernel_param *kp); |
21054 |
+-static int param_get_mode(char *buffer, struct kernel_param *kp); |
21055 |
++static int param_set_mode(const char *val, const struct kernel_param *kp); |
21056 |
++static int param_get_mode(char *buffer, const struct kernel_param *kp); |
21057 |
+ |
21058 |
+ /* Flag values, also controllable via /sys/module/apparmor/parameters |
21059 |
+ * We define special types as we want to do additional mediation. |
21060 |
+@@ -791,7 +791,7 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp) |
21061 |
+ return param_get_uint(buffer, kp); |
21062 |
+ } |
21063 |
+ |
21064 |
+-static int param_get_audit(char *buffer, struct kernel_param *kp) |
21065 |
++static int param_get_audit(char *buffer, const struct kernel_param *kp) |
21066 |
+ { |
21067 |
+ if (!capable(CAP_MAC_ADMIN)) |
21068 |
+ return -EPERM; |
21069 |
+@@ -802,7 +802,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp) |
21070 |
+ return sprintf(buffer, "%s", audit_mode_names[aa_g_audit]); |
21071 |
+ } |
21072 |
+ |
21073 |
+-static int param_set_audit(const char *val, struct kernel_param *kp) |
21074 |
++static int param_set_audit(const char *val, const struct kernel_param *kp) |
21075 |
+ { |
21076 |
+ int i; |
21077 |
+ if (!capable(CAP_MAC_ADMIN)) |
21078 |
+@@ -824,7 +824,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp) |
21079 |
+ return -EINVAL; |
21080 |
+ } |
21081 |
+ |
21082 |
+-static int param_get_mode(char *buffer, struct kernel_param *kp) |
21083 |
++static int param_get_mode(char *buffer, const struct kernel_param *kp) |
21084 |
+ { |
21085 |
+ if (!capable(CAP_MAC_ADMIN)) |
21086 |
+ return -EPERM; |
21087 |
+@@ -835,7 +835,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp) |
21088 |
+ return sprintf(buffer, "%s", aa_profile_mode_names[aa_g_profile_mode]); |
21089 |
+ } |
21090 |
+ |
21091 |
+-static int param_set_mode(const char *val, struct kernel_param *kp) |
21092 |
++static int param_set_mode(const char *val, const struct kernel_param *kp) |
21093 |
+ { |
21094 |
+ int i; |
21095 |
+ if (!capable(CAP_MAC_ADMIN)) |
21096 |
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c |
21097 |
+index 705c287..81257f1 100644 |
21098 |
+--- a/security/apparmor/policy.c |
21099 |
++++ b/security/apparmor/policy.c |
21100 |
+@@ -298,7 +298,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix, |
21101 |
+ /* ns and ns->unconfined share ns->unconfined refcount */ |
21102 |
+ ns->unconfined->ns = ns; |
21103 |
+ |
21104 |
+- atomic_set(&ns->uniq_null, 0); |
21105 |
++ atomic_set_unchecked(&ns->uniq_null, 0); |
21106 |
+ |
21107 |
+ return ns; |
21108 |
+ |
21109 |
+@@ -689,7 +689,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat) |
21110 |
+ { |
21111 |
+ struct aa_profile *profile = NULL; |
21112 |
+ char *name; |
21113 |
+- int uniq = atomic_inc_return(&parent->ns->uniq_null); |
21114 |
++ int uniq = atomic_inc_return_unchecked(&parent->ns->uniq_null); |
21115 |
+ |
21116 |
+ /* freed below */ |
21117 |
+ name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL); |
21118 |
+diff --git a/security/commoncap.c b/security/commoncap.c |
21119 |
+index 48071ed..b805e0f 100644 |
21120 |
+--- a/security/commoncap.c |
21121 |
++++ b/security/commoncap.c |
21122 |
+@@ -438,6 +438,32 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data |
21123 |
+ return 0; |
21124 |
+ } |
21125 |
+ |
21126 |
++/* returns: |
21127 |
++ 1 for suid privilege |
21128 |
++ 2 for sgid privilege |
21129 |
++ 3 for fscap privilege |
21130 |
++*/ |
21131 |
++int is_privileged_binary(const struct dentry *dentry) |
21132 |
+{ |
21133 |
-+ const char * const plugin_name = plugin_info->base_name; |
21134 |
-+ const int argc = plugin_info->argc; |
21135 |
-+ const struct plugin_argument * const argv = plugin_info->argv; |
21136 |
-+ int i; |
21137 |
-+ struct register_pass_info stackleak_tree_instrument_pass_info; |
21138 |
-+ struct register_pass_info stackleak_final_pass_info; |
21139 |
-+ static const struct ggc_root_tab gt_ggc_r_gt_stackleak[] = { |
21140 |
-+ { |
21141 |
-+ .base = &track_function_decl, |
21142 |
-+ .nelt = 1, |
21143 |
-+ .stride = sizeof(track_function_decl), |
21144 |
-+ .cb = >_ggc_mx_tree_node, |
21145 |
-+ .pchw = >_pch_nx_tree_node |
21146 |
-+ }, |
21147 |
-+ { |
21148 |
-+ .base = &check_function_decl, |
21149 |
-+ .nelt = 1, |
21150 |
-+ .stride = sizeof(check_function_decl), |
21151 |
-+ .cb = >_ggc_mx_tree_node, |
21152 |
-+ .pchw = >_pch_nx_tree_node |
21153 |
-+ }, |
21154 |
-+ LAST_GGC_ROOT_TAB |
21155 |
-+ }; |
21156 |
-+ |
21157 |
-+ stackleak_tree_instrument_pass_info.pass = make_stackleak_tree_instrument_pass(); |
21158 |
-+// stackleak_tree_instrument_pass_info.reference_pass_name = "tree_profile"; |
21159 |
-+ stackleak_tree_instrument_pass_info.reference_pass_name = "optimized"; |
21160 |
-+ stackleak_tree_instrument_pass_info.ref_pass_instance_number = 1; |
21161 |
-+ stackleak_tree_instrument_pass_info.pos_op = PASS_POS_INSERT_BEFORE; |
21162 |
++ struct cpu_vfs_cap_data capdata; |
21163 |
++ struct inode *inode = dentry->d_inode; |
21164 |
+ |
21165 |
-+ stackleak_final_pass_info.pass = make_stackleak_final_pass(); |
21166 |
-+ stackleak_final_pass_info.reference_pass_name = "final"; |
21167 |
-+ stackleak_final_pass_info.ref_pass_instance_number = 1; |
21168 |
-+ stackleak_final_pass_info.pos_op = PASS_POS_INSERT_BEFORE; |
21169 |
++ if (!inode || S_ISDIR(inode->i_mode)) |
21170 |
++ return 0; |
21171 |
+ |
21172 |
-+ if (!plugin_default_version_check(version, &gcc_version)) { |
21173 |
-+ error(G_("incompatible gcc/plugin versions")); |
21174 |
++ if (inode->i_mode & S_ISUID) |
21175 |
+ return 1; |
21176 |
-+ } |
21177 |
-+ |
21178 |
-+ register_callback(plugin_name, PLUGIN_INFO, NULL, &stackleak_plugin_info); |
21179 |
++ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) |
21180 |
++ return 2; |
21181 |
+ |
21182 |
-+ for (i = 0; i < argc; ++i) { |
21183 |
-+ if (!strcmp(argv[i].key, "track-lowest-sp")) { |
21184 |
-+ if (!argv[i].value) { |
21185 |
-+ error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
21186 |
-+ continue; |
21187 |
-+ } |
21188 |
-+ track_frame_size = atoi(argv[i].value); |
21189 |
-+ if (argv[i].value[0] < '0' || argv[i].value[0] > '9' || track_frame_size < 0) |
21190 |
-+ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); |
21191 |
-+ continue; |
21192 |
-+ } |
21193 |
-+ if (!strcmp(argv[i].key, "initialize-locals")) { |
21194 |
-+ if (argv[i].value) { |
21195 |
-+ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); |
21196 |
-+ continue; |
21197 |
-+ } |
21198 |
-+ init_locals = true; |
21199 |
-+ continue; |
21200 |
-+ } |
21201 |
-+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
21202 |
++ if (!get_vfs_caps_from_disk(dentry, &capdata)) { |
21203 |
++ if (!cap_isclear(capdata.inheritable) || !cap_isclear(capdata.permitted)) |
21204 |
++ return 3; |
21205 |
+ } |
21206 |
+ |
21207 |
-+ register_callback(plugin_name, PLUGIN_START_UNIT, &stackleak_start_unit, NULL); |
21208 |
-+ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_stackleak); |
21209 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_tree_instrument_pass_info); |
21210 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_final_pass_info); |
21211 |
-+ |
21212 |
+ return 0; |
21213 |
+} |
21214 |
-diff --git a/tools/gcc/structleak_plugin.c b/tools/gcc/structleak_plugin.c |
21215 |
-new file mode 100644 |
21216 |
-index 0000000..d7596e6 |
21217 |
---- /dev/null |
21218 |
-+++ b/tools/gcc/structleak_plugin.c |
21219 |
-@@ -0,0 +1,239 @@ |
21220 |
-+/* |
21221 |
-+ * Copyright 2013-2016 by PaX Team <pageexec@××××××××.hu> |
21222 |
-+ * Licensed under the GPL v2 |
21223 |
-+ * |
21224 |
-+ * Note: the choice of the license means that the compilation process is |
21225 |
-+ * NOT 'eligible' as defined by gcc's library exception to the GPL v3, |
21226 |
-+ * but for the kernel it doesn't matter since it doesn't link against |
21227 |
-+ * any of the gcc libraries |
21228 |
-+ * |
21229 |
-+ * gcc plugin to forcibly initialize certain local variables that could |
21230 |
-+ * otherwise leak kernel stack to userland if they aren't properly initialized |
21231 |
-+ * by later code |
21232 |
-+ * |
21233 |
-+ * Homepage: http://pax.grsecurity.net/ |
21234 |
-+ * |
21235 |
-+ * Usage: |
21236 |
-+ * $ # for 4.5/4.6/C based 4.7 |
21237 |
-+ * $ gcc -I`gcc -print-file-name=plugin`/include -I`gcc -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o structleak_plugin.so structleak_plugin.c |
21238 |
-+ * $ # for C++ based 4.7/4.8+ |
21239 |
-+ * $ g++ -I`g++ -print-file-name=plugin`/include -I`g++ -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o structleak_plugin.so structleak_plugin.c |
21240 |
-+ * $ gcc -fplugin=./structleak_plugin.so test.c -O2 |
21241 |
-+ * |
21242 |
-+ * TODO: eliminate redundant initializers |
21243 |
-+ * increase type coverage |
21244 |
-+ */ |
21245 |
+ |
21246 |
-+#include "gcc-common.h" |
21247 |
+ /* |
21248 |
+ * Attempt to get the on-exec apply capability sets for an executable file from |
21249 |
+ * its xattrs and, if present, apply them to the proposed credentials being |
21250 |
+@@ -628,6 +654,9 @@ int cap_bprm_secureexec(struct linux_binprm *bprm) |
21251 |
+ const struct cred *cred = current_cred(); |
21252 |
+ kuid_t root_uid = make_kuid(cred->user_ns, 0); |
21253 |
+ |
21254 |
++ if (gr_acl_enable_at_secure()) |
21255 |
++ return 1; |
21256 |
+ |
21257 |
-+// unused C type flag in all versions 4.5-6 |
21258 |
-+#define TYPE_USERSPACE(TYPE) TYPE_LANG_FLAG_5(TYPE) |
21259 |
+ if (!uid_eq(cred->uid, root_uid)) { |
21260 |
+ if (bprm->cap_effective) |
21261 |
+ return 1; |
21262 |
+diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h |
21263 |
+index 585af61..b7d35ff 100644 |
21264 |
+--- a/security/integrity/ima/ima.h |
21265 |
++++ b/security/integrity/ima/ima.h |
21266 |
+@@ -125,8 +125,8 @@ int ima_init_template(void); |
21267 |
+ extern spinlock_t ima_queue_lock; |
21268 |
+ |
21269 |
+ struct ima_h_table { |
21270 |
+- atomic_long_t len; /* number of stored measurements in the list */ |
21271 |
+- atomic_long_t violations; |
21272 |
++ atomic_long_unchecked_t len; /* number of stored measurements in the list */ |
21273 |
++ atomic_long_unchecked_t violations; |
21274 |
+ struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; |
21275 |
+ }; |
21276 |
+ extern struct ima_h_table ima_htable; |
21277 |
+diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c |
21278 |
+index 1d950fb..a8f4eab 100644 |
21279 |
+--- a/security/integrity/ima/ima_api.c |
21280 |
++++ b/security/integrity/ima/ima_api.c |
21281 |
+@@ -137,7 +137,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, |
21282 |
+ int result; |
21283 |
+ |
21284 |
+ /* can overflow, only indicator */ |
21285 |
+- atomic_long_inc(&ima_htable.violations); |
21286 |
++ atomic_long_inc_unchecked(&ima_htable.violations); |
21287 |
+ |
21288 |
+ result = ima_alloc_init_template(&event_data, &entry); |
21289 |
+ if (result < 0) { |
21290 |
+diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c |
21291 |
+index f355231..c71f640 100644 |
21292 |
+--- a/security/integrity/ima/ima_fs.c |
21293 |
++++ b/security/integrity/ima/ima_fs.c |
21294 |
+@@ -30,12 +30,12 @@ static DEFINE_MUTEX(ima_write_mutex); |
21295 |
+ static int valid_policy = 1; |
21296 |
+ #define TMPBUFLEN 12 |
21297 |
+ static ssize_t ima_show_htable_value(char __user *buf, size_t count, |
21298 |
+- loff_t *ppos, atomic_long_t *val) |
21299 |
++ loff_t *ppos, atomic_long_unchecked_t *val) |
21300 |
+ { |
21301 |
+ char tmpbuf[TMPBUFLEN]; |
21302 |
+ ssize_t len; |
21303 |
+ |
21304 |
+- len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val)); |
21305 |
++ len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read_unchecked(val)); |
21306 |
+ return simple_read_from_buffer(buf, count, ppos, tmpbuf, len); |
21307 |
+ } |
21308 |
+ |
21309 |
+diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c |
21310 |
+index 552705d..9920f4fb 100644 |
21311 |
+--- a/security/integrity/ima/ima_queue.c |
21312 |
++++ b/security/integrity/ima/ima_queue.c |
21313 |
+@@ -83,7 +83,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry) |
21314 |
+ INIT_LIST_HEAD(&qe->later); |
21315 |
+ list_add_tail_rcu(&qe->later, &ima_measurements); |
21316 |
+ |
21317 |
+- atomic_long_inc(&ima_htable.len); |
21318 |
++ atomic_long_inc_unchecked(&ima_htable.len); |
21319 |
+ key = ima_hash_key(entry->digest); |
21320 |
+ hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]); |
21321 |
+ return 0; |
21322 |
+diff --git a/security/keys/internal.h b/security/keys/internal.h |
21323 |
+index 5105c2c..a5010e6 100644 |
21324 |
+--- a/security/keys/internal.h |
21325 |
++++ b/security/keys/internal.h |
21326 |
+@@ -90,12 +90,16 @@ extern void key_type_put(struct key_type *ktype); |
21327 |
+ |
21328 |
+ extern int __key_link_begin(struct key *keyring, |
21329 |
+ const struct keyring_index_key *index_key, |
21330 |
+- struct assoc_array_edit **_edit); |
21331 |
++ struct assoc_array_edit **_edit) |
21332 |
++ __acquires(&keyring->sem) |
21333 |
++ __acquires(&keyring_serialise_link_sem); |
21334 |
+ extern int __key_link_check_live_key(struct key *keyring, struct key *key); |
21335 |
+ extern void __key_link(struct key *key, struct assoc_array_edit **_edit); |
21336 |
+ extern void __key_link_end(struct key *keyring, |
21337 |
+ const struct keyring_index_key *index_key, |
21338 |
+- struct assoc_array_edit *edit); |
21339 |
++ struct assoc_array_edit *edit) |
21340 |
++ __releases(&keyring->sem) |
21341 |
++ __releases(&keyring_serialise_link_sem); |
21342 |
+ |
21343 |
+ extern key_ref_t find_key_to_update(key_ref_t keyring_ref, |
21344 |
+ const struct keyring_index_key *index_key); |
21345 |
+@@ -191,7 +195,7 @@ struct request_key_auth { |
21346 |
+ void *callout_info; |
21347 |
+ size_t callout_len; |
21348 |
+ pid_t pid; |
21349 |
+-}; |
21350 |
++} __randomize_layout; |
21351 |
+ |
21352 |
+ extern struct key_type key_type_request_key_auth; |
21353 |
+ extern struct key *request_key_auth_new(struct key *target, |
21354 |
+diff --git a/security/keys/key.c b/security/keys/key.c |
21355 |
+index 09ef276..ab2894f 100644 |
21356 |
+--- a/security/keys/key.c |
21357 |
++++ b/security/keys/key.c |
21358 |
+@@ -283,7 +283,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, |
21359 |
+ |
21360 |
+ atomic_set(&key->usage, 1); |
21361 |
+ init_rwsem(&key->sem); |
21362 |
+- lockdep_set_class(&key->sem, &type->lock_class); |
21363 |
++ lockdep_set_class(&key->sem, (struct lock_class_key *)&type->lock_class); |
21364 |
+ key->index_key.type = type; |
21365 |
+ key->user = user; |
21366 |
+ key->quotalen = quotalen; |
21367 |
+@@ -1077,7 +1077,9 @@ int register_key_type(struct key_type *ktype) |
21368 |
+ struct key_type *p; |
21369 |
+ int ret; |
21370 |
+ |
21371 |
+- memset(&ktype->lock_class, 0, sizeof(ktype->lock_class)); |
21372 |
++ pax_open_kernel(); |
21373 |
++ memset((void *)&ktype->lock_class, 0, sizeof(ktype->lock_class)); |
21374 |
++ pax_close_kernel(); |
21375 |
+ |
21376 |
+ ret = -EEXIST; |
21377 |
+ down_write(&key_types_sem); |
21378 |
+@@ -1089,7 +1091,7 @@ int register_key_type(struct key_type *ktype) |
21379 |
+ } |
21380 |
+ |
21381 |
+ /* store the type */ |
21382 |
+- list_add(&ktype->link, &key_types_list); |
21383 |
++ pax_list_add((struct list_head *)&ktype->link, &key_types_list); |
21384 |
+ |
21385 |
+ pr_notice("Key type %s registered\n", ktype->name); |
21386 |
+ ret = 0; |
21387 |
+@@ -1111,7 +1113,7 @@ EXPORT_SYMBOL(register_key_type); |
21388 |
+ void unregister_key_type(struct key_type *ktype) |
21389 |
+ { |
21390 |
+ down_write(&key_types_sem); |
21391 |
+- list_del_init(&ktype->link); |
21392 |
++ pax_list_del_init((struct list_head *)&ktype->link); |
21393 |
+ downgrade_write(&key_types_sem); |
21394 |
+ key_gc_keytype(ktype); |
21395 |
+ pr_notice("Key type %s unregistered\n", ktype->name); |
21396 |
+@@ -1129,10 +1131,10 @@ void __init key_init(void) |
21397 |
+ 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
21398 |
+ |
21399 |
+ /* add the special key types */ |
21400 |
+- list_add_tail(&key_type_keyring.link, &key_types_list); |
21401 |
+- list_add_tail(&key_type_dead.link, &key_types_list); |
21402 |
+- list_add_tail(&key_type_user.link, &key_types_list); |
21403 |
+- list_add_tail(&key_type_logon.link, &key_types_list); |
21404 |
++ pax_list_add_tail((struct list_head *)&key_type_keyring.link, &key_types_list); |
21405 |
++ pax_list_add_tail((struct list_head *)&key_type_dead.link, &key_types_list); |
21406 |
++ pax_list_add_tail((struct list_head *)&key_type_user.link, &key_types_list); |
21407 |
++ pax_list_add_tail((struct list_head *)&key_type_logon.link, &key_types_list); |
21408 |
+ |
21409 |
+ /* record the root user tracking */ |
21410 |
+ rb_link_node(&root_key_user.node, |
21411 |
+diff --git a/security/keys/keyring.c b/security/keys/keyring.c |
21412 |
+index f931ccf..ed9cd36 100644 |
21413 |
+--- a/security/keys/keyring.c |
21414 |
++++ b/security/keys/keyring.c |
21415 |
+@@ -1071,8 +1071,6 @@ static int keyring_detect_cycle(struct key *A, struct key *B) |
21416 |
+ int __key_link_begin(struct key *keyring, |
21417 |
+ const struct keyring_index_key *index_key, |
21418 |
+ struct assoc_array_edit **_edit) |
21419 |
+- __acquires(&keyring->sem) |
21420 |
+- __acquires(&keyring_serialise_link_sem) |
21421 |
+ { |
21422 |
+ struct assoc_array_edit *edit; |
21423 |
+ int ret; |
21424 |
+@@ -1172,8 +1170,6 @@ void __key_link(struct key *key, struct assoc_array_edit **_edit) |
21425 |
+ void __key_link_end(struct key *keyring, |
21426 |
+ const struct keyring_index_key *index_key, |
21427 |
+ struct assoc_array_edit *edit) |
21428 |
+- __releases(&keyring->sem) |
21429 |
+- __releases(&keyring_serialise_link_sem) |
21430 |
+ { |
21431 |
+ BUG_ON(index_key->type == NULL); |
21432 |
+ kenter("%d,%s,", keyring->serial, index_key->type->name); |
21433 |
+diff --git a/security/min_addr.c b/security/min_addr.c |
21434 |
+index f728728..6457a0c 100644 |
21435 |
+--- a/security/min_addr.c |
21436 |
++++ b/security/min_addr.c |
21437 |
+@@ -14,6 +14,7 @@ unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; |
21438 |
+ */ |
21439 |
+ static void update_mmap_min_addr(void) |
21440 |
+ { |
21441 |
++#ifndef SPARC |
21442 |
+ #ifdef CONFIG_LSM_MMAP_MIN_ADDR |
21443 |
+ if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) |
21444 |
+ mmap_min_addr = dac_mmap_min_addr; |
21445 |
+@@ -22,6 +23,7 @@ static void update_mmap_min_addr(void) |
21446 |
+ #else |
21447 |
+ mmap_min_addr = dac_mmap_min_addr; |
21448 |
+ #endif |
21449 |
++#endif |
21450 |
+ } |
21451 |
+ |
21452 |
+ /* |
21453 |
+diff --git a/security/selinux/avc.c b/security/selinux/avc.c |
21454 |
+index e60c79d..41fb721 100644 |
21455 |
+--- a/security/selinux/avc.c |
21456 |
++++ b/security/selinux/avc.c |
21457 |
+@@ -71,7 +71,7 @@ struct avc_xperms_node { |
21458 |
+ struct avc_cache { |
21459 |
+ struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */ |
21460 |
+ spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */ |
21461 |
+- atomic_t lru_hint; /* LRU hint for reclaim scan */ |
21462 |
++ atomic_unchecked_t lru_hint; /* LRU hint for reclaim scan */ |
21463 |
+ atomic_t active_nodes; |
21464 |
+ u32 latest_notif; /* latest revocation notification */ |
21465 |
+ }; |
21466 |
+@@ -183,7 +183,7 @@ void __init avc_init(void) |
21467 |
+ spin_lock_init(&avc_cache.slots_lock[i]); |
21468 |
+ } |
21469 |
+ atomic_set(&avc_cache.active_nodes, 0); |
21470 |
+- atomic_set(&avc_cache.lru_hint, 0); |
21471 |
++ atomic_set_unchecked(&avc_cache.lru_hint, 0); |
21472 |
+ |
21473 |
+ avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), |
21474 |
+ 0, SLAB_PANIC, NULL); |
21475 |
+@@ -521,7 +521,7 @@ static inline int avc_reclaim_node(void) |
21476 |
+ spinlock_t *lock; |
21477 |
+ |
21478 |
+ for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) { |
21479 |
+- hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); |
21480 |
++ hvalue = atomic_inc_return_unchecked(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); |
21481 |
+ head = &avc_cache.slots[hvalue]; |
21482 |
+ lock = &avc_cache.slots_lock[hvalue]; |
21483 |
+ |
21484 |
+diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h |
21485 |
+index 1450f85..a91e0bc 100644 |
21486 |
+--- a/security/selinux/include/xfrm.h |
21487 |
++++ b/security/selinux/include/xfrm.h |
21488 |
+@@ -48,7 +48,7 @@ static inline void selinux_xfrm_notify_policyload(void) |
21489 |
+ |
21490 |
+ rtnl_lock(); |
21491 |
+ for_each_net(net) { |
21492 |
+- atomic_inc(&net->xfrm.flow_cache_genid); |
21493 |
++ atomic_inc_unchecked(&net->xfrm.flow_cache_genid); |
21494 |
+ rt_genid_bump_all(net); |
21495 |
+ } |
21496 |
+ rtnl_unlock(); |
21497 |
+diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c |
21498 |
+index 2367b10..a0c3c51 100644 |
21499 |
+--- a/security/tomoyo/file.c |
21500 |
++++ b/security/tomoyo/file.c |
21501 |
+@@ -692,7 +692,7 @@ int tomoyo_path_number_perm(const u8 type, struct path *path, |
21502 |
+ { |
21503 |
+ struct tomoyo_request_info r; |
21504 |
+ struct tomoyo_obj_info obj = { |
21505 |
+- .path1 = *path, |
21506 |
++ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
21507 |
+ }; |
21508 |
+ int error = -ENOMEM; |
21509 |
+ struct tomoyo_path_info buf; |
21510 |
+@@ -740,7 +740,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, |
21511 |
+ struct tomoyo_path_info buf; |
21512 |
+ struct tomoyo_request_info r; |
21513 |
+ struct tomoyo_obj_info obj = { |
21514 |
+- .path1 = *path, |
21515 |
++ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
21516 |
+ }; |
21517 |
+ int idx; |
21518 |
+ |
21519 |
+@@ -786,7 +786,7 @@ int tomoyo_path_perm(const u8 operation, const struct path *path, const char *ta |
21520 |
+ { |
21521 |
+ struct tomoyo_request_info r; |
21522 |
+ struct tomoyo_obj_info obj = { |
21523 |
+- .path1 = *path, |
21524 |
++ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
21525 |
+ }; |
21526 |
+ int error; |
21527 |
+ struct tomoyo_path_info buf; |
21528 |
+@@ -843,7 +843,7 @@ int tomoyo_mkdev_perm(const u8 operation, struct path *path, |
21529 |
+ { |
21530 |
+ struct tomoyo_request_info r; |
21531 |
+ struct tomoyo_obj_info obj = { |
21532 |
+- .path1 = *path, |
21533 |
++ .path1 = { .mnt = path->mnt, .dentry = path->dentry }, |
21534 |
+ }; |
21535 |
+ int error = -ENOMEM; |
21536 |
+ struct tomoyo_path_info buf; |
21537 |
+@@ -890,8 +890,8 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, |
21538 |
+ struct tomoyo_path_info buf2; |
21539 |
+ struct tomoyo_request_info r; |
21540 |
+ struct tomoyo_obj_info obj = { |
21541 |
+- .path1 = *path1, |
21542 |
+- .path2 = *path2, |
21543 |
++ .path1 = { .mnt = path1->mnt, .dentry = path1->dentry }, |
21544 |
++ .path2 = { .mnt = path2->mnt, .dentry = path2->dentry } |
21545 |
+ }; |
21546 |
+ int idx; |
21547 |
+ |
21548 |
+diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c |
21549 |
+index 390c646..f2f8db3 100644 |
21550 |
+--- a/security/tomoyo/mount.c |
21551 |
++++ b/security/tomoyo/mount.c |
21552 |
+@@ -118,6 +118,10 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, |
21553 |
+ type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) { |
21554 |
+ need_dev = -1; /* dev_name is a directory */ |
21555 |
+ } else { |
21556 |
++ if (!capable(CAP_SYS_ADMIN)) { |
21557 |
++ error = -EPERM; |
21558 |
++ goto out; |
21559 |
++ } |
21560 |
+ fstype = get_fs_type(type); |
21561 |
+ if (!fstype) { |
21562 |
+ error = -ENODEV; |
21563 |
+diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c |
21564 |
+index cbf3df4..22b11df 100644 |
21565 |
+--- a/security/tomoyo/tomoyo.c |
21566 |
++++ b/security/tomoyo/tomoyo.c |
21567 |
+@@ -165,7 +165,7 @@ static int tomoyo_path_truncate(struct path *path) |
21568 |
+ */ |
21569 |
+ static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) |
21570 |
+ { |
21571 |
+- struct path path = { parent->mnt, dentry }; |
21572 |
++ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
21573 |
+ return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL); |
21574 |
+ } |
21575 |
+ |
21576 |
+@@ -181,7 +181,7 @@ static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) |
21577 |
+ static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, |
21578 |
+ umode_t mode) |
21579 |
+ { |
21580 |
+- struct path path = { parent->mnt, dentry }; |
21581 |
++ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
21582 |
+ return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path, |
21583 |
+ mode & S_IALLUGO); |
21584 |
+ } |
21585 |
+@@ -196,7 +196,7 @@ static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, |
21586 |
+ */ |
21587 |
+ static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) |
21588 |
+ { |
21589 |
+- struct path path = { parent->mnt, dentry }; |
21590 |
++ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
21591 |
+ return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL); |
21592 |
+ } |
21593 |
+ |
21594 |
+@@ -212,7 +212,7 @@ static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) |
21595 |
+ static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, |
21596 |
+ const char *old_name) |
21597 |
+ { |
21598 |
+- struct path path = { parent->mnt, dentry }; |
21599 |
++ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
21600 |
+ return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name); |
21601 |
+ } |
21602 |
+ |
21603 |
+@@ -229,7 +229,7 @@ static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, |
21604 |
+ static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, |
21605 |
+ umode_t mode, unsigned int dev) |
21606 |
+ { |
21607 |
+- struct path path = { parent->mnt, dentry }; |
21608 |
++ struct path path = { .mnt = parent->mnt, .dentry = dentry }; |
21609 |
+ int type = TOMOYO_TYPE_CREATE; |
21610 |
+ const unsigned int perm = mode & S_IALLUGO; |
21611 |
+ |
21612 |
+@@ -268,8 +268,8 @@ static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, |
21613 |
+ static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, |
21614 |
+ struct dentry *new_dentry) |
21615 |
+ { |
21616 |
+- struct path path1 = { new_dir->mnt, old_dentry }; |
21617 |
+- struct path path2 = { new_dir->mnt, new_dentry }; |
21618 |
++ struct path path1 = { .mnt = new_dir->mnt, .dentry = old_dentry }; |
21619 |
++ struct path path2 = { .mnt = new_dir->mnt, .dentry = new_dentry }; |
21620 |
+ return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2); |
21621 |
+ } |
21622 |
+ |
21623 |
+@@ -288,8 +288,8 @@ static int tomoyo_path_rename(struct path *old_parent, |
21624 |
+ struct path *new_parent, |
21625 |
+ struct dentry *new_dentry) |
21626 |
+ { |
21627 |
+- struct path path1 = { old_parent->mnt, old_dentry }; |
21628 |
+- struct path path2 = { new_parent->mnt, new_dentry }; |
21629 |
++ struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry }; |
21630 |
++ struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry }; |
21631 |
+ return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); |
21632 |
+ } |
21633 |
+ |
21634 |
+@@ -417,7 +417,7 @@ static int tomoyo_sb_mount(const char *dev_name, struct path *path, |
21635 |
+ */ |
21636 |
+ static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) |
21637 |
+ { |
21638 |
+- struct path path = { mnt, mnt->mnt_root }; |
21639 |
++ struct path path = { .mnt = mnt, .dentry = mnt->mnt_root }; |
21640 |
+ return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL); |
21641 |
+ } |
21642 |
+ |
21643 |
+diff --git a/security/yama/Kconfig b/security/yama/Kconfig |
21644 |
+index 90c605e..bf3a29a 100644 |
21645 |
+--- a/security/yama/Kconfig |
21646 |
++++ b/security/yama/Kconfig |
21647 |
+@@ -1,6 +1,6 @@ |
21648 |
+ config SECURITY_YAMA |
21649 |
+ bool "Yama support" |
21650 |
+- depends on SECURITY |
21651 |
++ depends on SECURITY && !GRKERNSEC |
21652 |
+ default n |
21653 |
+ help |
21654 |
+ This selects Yama, which extends DAC support with additional |
21655 |
+diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c |
21656 |
+index cb6ed10..fb00554 100644 |
21657 |
+--- a/security/yama/yama_lsm.c |
21658 |
++++ b/security/yama/yama_lsm.c |
21659 |
+@@ -357,7 +357,7 @@ static struct security_hook_list yama_hooks[] = { |
21660 |
+ static int yama_dointvec_minmax(struct ctl_table *table, int write, |
21661 |
+ void __user *buffer, size_t *lenp, loff_t *ppos) |
21662 |
+ { |
21663 |
+- struct ctl_table table_copy; |
21664 |
++ ctl_table_no_const table_copy; |
21665 |
+ |
21666 |
+ if (write && !capable(CAP_SYS_PTRACE)) |
21667 |
+ return -EPERM; |
21668 |
+diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c |
21669 |
+index a04edff..6811b91 100644 |
21670 |
+--- a/sound/aoa/codecs/onyx.c |
21671 |
++++ b/sound/aoa/codecs/onyx.c |
21672 |
+@@ -54,7 +54,7 @@ struct onyx { |
21673 |
+ spdif_locked:1, |
21674 |
+ analog_locked:1, |
21675 |
+ original_mute:2; |
21676 |
+- int open_count; |
21677 |
++ local_t open_count; |
21678 |
+ struct codec_info *codec_info; |
21679 |
+ |
21680 |
+ /* mutex serializes concurrent access to the device |
21681 |
+@@ -747,7 +747,7 @@ static int onyx_open(struct codec_info_item *cii, |
21682 |
+ struct onyx *onyx = cii->codec_data; |
21683 |
+ |
21684 |
+ mutex_lock(&onyx->mutex); |
21685 |
+- onyx->open_count++; |
21686 |
++ local_inc(&onyx->open_count); |
21687 |
+ mutex_unlock(&onyx->mutex); |
21688 |
+ |
21689 |
+ return 0; |
21690 |
+@@ -759,8 +759,7 @@ static int onyx_close(struct codec_info_item *cii, |
21691 |
+ struct onyx *onyx = cii->codec_data; |
21692 |
+ |
21693 |
+ mutex_lock(&onyx->mutex); |
21694 |
+- onyx->open_count--; |
21695 |
+- if (!onyx->open_count) |
21696 |
++ if (local_dec_and_test(&onyx->open_count)) |
21697 |
+ onyx->spdif_locked = onyx->analog_locked = 0; |
21698 |
+ mutex_unlock(&onyx->mutex); |
21699 |
+ |
21700 |
+diff --git a/sound/aoa/codecs/onyx.h b/sound/aoa/codecs/onyx.h |
21701 |
+index ffd2025..df062c9 100644 |
21702 |
+--- a/sound/aoa/codecs/onyx.h |
21703 |
++++ b/sound/aoa/codecs/onyx.h |
21704 |
+@@ -11,6 +11,7 @@ |
21705 |
+ #include <linux/i2c.h> |
21706 |
+ #include <asm/pmac_low_i2c.h> |
21707 |
+ #include <asm/prom.h> |
21708 |
++#include <asm/local.h> |
21709 |
+ |
21710 |
+ /* PCM3052 register definitions */ |
21711 |
+ |
21712 |
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c |
21713 |
+index ebc9fdf..61f491e 100644 |
21714 |
+--- a/sound/core/oss/pcm_oss.c |
21715 |
++++ b/sound/core/oss/pcm_oss.c |
21716 |
+@@ -1193,10 +1193,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const |
21717 |
+ if (in_kernel) { |
21718 |
+ mm_segment_t fs; |
21719 |
+ fs = snd_enter_user(); |
21720 |
+- ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames); |
21721 |
++ ret = snd_pcm_lib_write(substream, (void __force_user *)ptr, frames); |
21722 |
+ snd_leave_user(fs); |
21723 |
+ } else { |
21724 |
+- ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames); |
21725 |
++ ret = snd_pcm_lib_write(substream, (void __force_user *)ptr, frames); |
21726 |
+ } |
21727 |
+ if (ret != -EPIPE && ret != -ESTRPIPE) |
21728 |
+ break; |
21729 |
+@@ -1236,10 +1236,10 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p |
21730 |
+ if (in_kernel) { |
21731 |
+ mm_segment_t fs; |
21732 |
+ fs = snd_enter_user(); |
21733 |
+- ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames); |
21734 |
++ ret = snd_pcm_lib_read(substream, (void __force_user *)ptr, frames); |
21735 |
+ snd_leave_user(fs); |
21736 |
+ } else { |
21737 |
+- ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames); |
21738 |
++ ret = snd_pcm_lib_read(substream, (void __force_user *)ptr, frames); |
21739 |
+ } |
21740 |
+ if (ret == -EPIPE) { |
21741 |
+ if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { |
21742 |
+@@ -1335,7 +1335,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha |
21743 |
+ struct snd_pcm_plugin_channel *channels; |
21744 |
+ size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; |
21745 |
+ if (!in_kernel) { |
21746 |
+- if (copy_from_user(runtime->oss.buffer, (const char __force __user *)buf, bytes)) |
21747 |
++ if (copy_from_user(runtime->oss.buffer, (const char __force_user *)buf, bytes)) |
21748 |
+ return -EFAULT; |
21749 |
+ buf = runtime->oss.buffer; |
21750 |
+ } |
21751 |
+@@ -1405,7 +1405,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha |
21752 |
+ } |
21753 |
+ } else { |
21754 |
+ tmp = snd_pcm_oss_write2(substream, |
21755 |
+- (const char __force *)buf, |
21756 |
++ (const char __force_kernel *)buf, |
21757 |
+ runtime->oss.period_bytes, 0); |
21758 |
+ if (tmp <= 0) |
21759 |
+ goto err; |
21760 |
+@@ -1431,7 +1431,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, |
21761 |
+ struct snd_pcm_runtime *runtime = substream->runtime; |
21762 |
+ snd_pcm_sframes_t frames, frames1; |
21763 |
+ #ifdef CONFIG_SND_PCM_OSS_PLUGINS |
21764 |
+- char __user *final_dst = (char __force __user *)buf; |
21765 |
++ char __user *final_dst = (char __force_user *)buf; |
21766 |
+ if (runtime->oss.plugin_first) { |
21767 |
+ struct snd_pcm_plugin_channel *channels; |
21768 |
+ size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8; |
21769 |
+@@ -1493,7 +1493,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use |
21770 |
+ xfer += tmp; |
21771 |
+ runtime->oss.buffer_used -= tmp; |
21772 |
+ } else { |
21773 |
+- tmp = snd_pcm_oss_read2(substream, (char __force *)buf, |
21774 |
++ tmp = snd_pcm_oss_read2(substream, (char __force_kernel *)buf, |
21775 |
+ runtime->oss.period_bytes, 0); |
21776 |
+ if (tmp <= 0) |
21777 |
+ goto err; |
21778 |
+@@ -1662,7 +1662,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) |
21779 |
+ size1); |
21780 |
+ size1 /= runtime->channels; /* frames */ |
21781 |
+ fs = snd_enter_user(); |
21782 |
+- snd_pcm_lib_write(substream, (void __force __user *)runtime->oss.buffer, size1); |
21783 |
++ snd_pcm_lib_write(substream, (void __force_user *)runtime->oss.buffer, size1); |
21784 |
+ snd_leave_user(fs); |
21785 |
+ } |
21786 |
+ } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) { |
21787 |
+diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c |
21788 |
+index 1f64ab0..26a7233 100644 |
21789 |
+--- a/sound/core/pcm_compat.c |
21790 |
++++ b/sound/core/pcm_compat.c |
21791 |
+@@ -31,7 +31,7 @@ static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream, |
21792 |
+ int err; |
21793 |
+ |
21794 |
+ fs = snd_enter_user(); |
21795 |
+- err = snd_pcm_delay(substream, &delay); |
21796 |
++ err = snd_pcm_delay(substream, (snd_pcm_sframes_t __force_user *)&delay); |
21797 |
+ snd_leave_user(fs); |
21798 |
+ if (err < 0) |
21799 |
+ return err; |
21800 |
+diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c |
21801 |
+index 3a9b66c..2b38b21 100644 |
21802 |
+--- a/sound/core/pcm_lib.c |
21803 |
++++ b/sound/core/pcm_lib.c |
21804 |
+@@ -1867,8 +1867,9 @@ EXPORT_SYMBOL(snd_pcm_lib_ioctl); |
21805 |
+ * Even if more than one periods have elapsed since the last call, you |
21806 |
+ * have to call this only once. |
21807 |
+ */ |
21808 |
+-void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) |
21809 |
++void snd_pcm_period_elapsed(void *_substream) |
21810 |
+ { |
21811 |
++ struct snd_pcm_substream *substream = _substream; |
21812 |
+ struct snd_pcm_runtime *runtime; |
21813 |
+ unsigned long flags; |
21814 |
+ |
21815 |
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c |
21816 |
+index 9106d8e..e7e2e3c 100644 |
21817 |
+--- a/sound/core/pcm_native.c |
21818 |
++++ b/sound/core/pcm_native.c |
21819 |
+@@ -3014,11 +3014,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, |
21820 |
+ switch (substream->stream) { |
21821 |
+ case SNDRV_PCM_STREAM_PLAYBACK: |
21822 |
+ result = snd_pcm_playback_ioctl1(NULL, substream, cmd, |
21823 |
+- (void __user *)arg); |
21824 |
++ (void __force_user *)arg); |
21825 |
+ break; |
21826 |
+ case SNDRV_PCM_STREAM_CAPTURE: |
21827 |
+ result = snd_pcm_capture_ioctl1(NULL, substream, cmd, |
21828 |
+- (void __user *)arg); |
21829 |
++ (void __force_user *)arg); |
21830 |
+ break; |
21831 |
+ default: |
21832 |
+ result = -EINVAL; |
21833 |
+diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c |
21834 |
+index 795437b..3650746 100644 |
21835 |
+--- a/sound/core/rawmidi.c |
21836 |
++++ b/sound/core/rawmidi.c |
21837 |
+@@ -871,9 +871,10 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, |
21838 |
+ * |
21839 |
+ * Return: The size of read data, or a negative error code on failure. |
21840 |
+ */ |
21841 |
+-int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, |
21842 |
+- const unsigned char *buffer, int count) |
21843 |
++int snd_rawmidi_receive(void *_substream, const void *_buffer, int count) |
21844 |
+ { |
21845 |
++ struct snd_rawmidi_substream *substream = _substream; |
21846 |
++ const unsigned char *buffer = _buffer; |
21847 |
+ unsigned long flags; |
21848 |
+ int result = 0, count1; |
21849 |
+ struct snd_rawmidi_runtime *runtime = substream->runtime; |
21850 |
+diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c |
21851 |
+index b16dbef04..8eb05a4 100644 |
21852 |
+--- a/sound/core/seq/oss/seq_oss_synth.c |
21853 |
++++ b/sound/core/seq/oss/seq_oss_synth.c |
21854 |
+@@ -653,8 +653,8 @@ snd_seq_oss_synth_info_read(struct snd_info_buffer *buf) |
21855 |
+ rec->synth_type, rec->synth_subtype, |
21856 |
+ rec->nr_voices); |
21857 |
+ snd_iprintf(buf, " capabilities : ioctl %s / load_patch %s\n", |
21858 |
+- enabled_str((long)rec->oper.ioctl), |
21859 |
+- enabled_str((long)rec->oper.load_patch)); |
21860 |
++ enabled_str(!!rec->oper.ioctl), |
21861 |
++ enabled_str(!!rec->oper.load_patch)); |
21862 |
+ snd_use_lock_free(&rec->use_lock); |
21863 |
+ } |
21864 |
+ } |
21865 |
+diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c |
21866 |
+index 58e79e0..19751d1 100644 |
21867 |
+--- a/sound/core/seq/seq_clientmgr.c |
21868 |
++++ b/sound/core/seq/seq_clientmgr.c |
21869 |
+@@ -416,7 +416,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, |
21870 |
+ if (!client->accept_input || (fifo = client->data.user.fifo) == NULL) |
21871 |
+ return -ENXIO; |
21872 |
+ |
21873 |
+- if (atomic_read(&fifo->overflow) > 0) { |
21874 |
++ if (atomic_read_unchecked(&fifo->overflow) > 0) { |
21875 |
+ /* buffer overflow is detected */ |
21876 |
+ snd_seq_fifo_clear(fifo); |
21877 |
+ /* return error code */ |
21878 |
+@@ -446,7 +446,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, |
21879 |
+ count -= sizeof(struct snd_seq_event); |
21880 |
+ buf += sizeof(struct snd_seq_event); |
21881 |
+ err = snd_seq_expand_var_event(&cell->event, count, |
21882 |
+- (char __force *)buf, 0, |
21883 |
++ (char __force_kernel *)buf, 0, |
21884 |
+ sizeof(struct snd_seq_event)); |
21885 |
+ if (err < 0) |
21886 |
+ break; |
21887 |
+@@ -1062,13 +1062,13 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, |
21888 |
+ } |
21889 |
+ /* set user space pointer */ |
21890 |
+ event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR; |
21891 |
+- event.data.ext.ptr = (char __force *)buf |
21892 |
++ event.data.ext.ptr = (char __force_kernel *)buf |
21893 |
+ + sizeof(struct snd_seq_event); |
21894 |
+ len += extlen; /* increment data length */ |
21895 |
+ } else { |
21896 |
+ #ifdef CONFIG_COMPAT |
21897 |
+ if (client->convert32 && snd_seq_ev_is_varusr(&event)) { |
21898 |
+- void *ptr = (void __force *)compat_ptr(event.data.raw32.d[1]); |
21899 |
++ void *ptr = (void __force_kernel *)compat_ptr(event.data.raw32.d[1]); |
21900 |
+ event.data.ext.ptr = ptr; |
21901 |
+ } |
21902 |
+ #endif |
21903 |
+@@ -2423,7 +2423,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) |
21904 |
+ if (client == NULL) |
21905 |
+ return -ENXIO; |
21906 |
+ fs = snd_enter_user(); |
21907 |
+- result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg); |
21908 |
++ result = snd_seq_do_ioctl(client, cmd, (void __force_user *)arg); |
21909 |
+ snd_leave_user(fs); |
21910 |
+ return result; |
21911 |
+ } |
21912 |
+diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c |
21913 |
+index 6517590..9905cee 100644 |
21914 |
+--- a/sound/core/seq/seq_compat.c |
21915 |
++++ b/sound/core/seq/seq_compat.c |
21916 |
+@@ -60,7 +60,7 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned |
21917 |
+ data->kernel = NULL; |
21918 |
+ |
21919 |
+ fs = snd_enter_user(); |
21920 |
+- err = snd_seq_do_ioctl(client, cmd, data); |
21921 |
++ err = snd_seq_do_ioctl(client, cmd, (void __force_user *)data); |
21922 |
+ snd_leave_user(fs); |
21923 |
+ if (err < 0) |
21924 |
+ goto error; |
21925 |
+diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c |
21926 |
+index 1d5acbe..5f55223 100644 |
21927 |
+--- a/sound/core/seq/seq_fifo.c |
21928 |
++++ b/sound/core/seq/seq_fifo.c |
21929 |
+@@ -50,7 +50,7 @@ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize) |
21930 |
+ spin_lock_init(&f->lock); |
21931 |
+ snd_use_lock_init(&f->use_lock); |
21932 |
+ init_waitqueue_head(&f->input_sleep); |
21933 |
+- atomic_set(&f->overflow, 0); |
21934 |
++ atomic_set_unchecked(&f->overflow, 0); |
21935 |
+ |
21936 |
+ f->head = NULL; |
21937 |
+ f->tail = NULL; |
21938 |
+@@ -96,7 +96,7 @@ void snd_seq_fifo_clear(struct snd_seq_fifo *f) |
21939 |
+ unsigned long flags; |
21940 |
+ |
21941 |
+ /* clear overflow flag */ |
21942 |
+- atomic_set(&f->overflow, 0); |
21943 |
++ atomic_set_unchecked(&f->overflow, 0); |
21944 |
+ |
21945 |
+ snd_use_lock_sync(&f->use_lock); |
21946 |
+ spin_lock_irqsave(&f->lock, flags); |
21947 |
+@@ -123,7 +123,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, |
21948 |
+ err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ |
21949 |
+ if (err < 0) { |
21950 |
+ if ((err == -ENOMEM) || (err == -EAGAIN)) |
21951 |
+- atomic_inc(&f->overflow); |
21952 |
++ atomic_inc_unchecked(&f->overflow); |
21953 |
+ snd_use_lock_free(&f->use_lock); |
21954 |
+ return err; |
21955 |
+ } |
21956 |
+diff --git a/sound/core/seq/seq_fifo.h b/sound/core/seq/seq_fifo.h |
21957 |
+index 062c446..a4b6f4c 100644 |
21958 |
+--- a/sound/core/seq/seq_fifo.h |
21959 |
++++ b/sound/core/seq/seq_fifo.h |
21960 |
+@@ -35,7 +35,7 @@ struct snd_seq_fifo { |
21961 |
+ spinlock_t lock; |
21962 |
+ snd_use_lock_t use_lock; |
21963 |
+ wait_queue_head_t input_sleep; |
21964 |
+- atomic_t overflow; |
21965 |
++ atomic_unchecked_t overflow; |
21966 |
+ |
21967 |
+ }; |
21968 |
+ |
21969 |
+diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c |
21970 |
+index c850345..ec0a853 100644 |
21971 |
+--- a/sound/core/seq/seq_memory.c |
21972 |
++++ b/sound/core/seq/seq_memory.c |
21973 |
+@@ -87,7 +87,7 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event, |
21974 |
+ |
21975 |
+ if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { |
21976 |
+ char buf[32]; |
21977 |
+- char __user *curptr = (char __force __user *)event->data.ext.ptr; |
21978 |
++ char __user *curptr = (char __force_user *)event->data.ext.ptr; |
21979 |
+ while (len > 0) { |
21980 |
+ int size = sizeof(buf); |
21981 |
+ if (len < size) |
21982 |
+@@ -126,15 +126,19 @@ EXPORT_SYMBOL(snd_seq_dump_var_event); |
21983 |
+ * expand the variable length event to linear buffer space. |
21984 |
+ */ |
21985 |
+ |
21986 |
+-static int seq_copy_in_kernel(char **bufptr, const void *src, int size) |
21987 |
++static int seq_copy_in_kernel(void *_bufptr, const void *src, int size) |
21988 |
+ { |
21989 |
++ char **bufptr = (char **)_bufptr; |
21990 |
++ |
21991 |
+ memcpy(*bufptr, src, size); |
21992 |
+ *bufptr += size; |
21993 |
+ return 0; |
21994 |
+ } |
21995 |
+ |
21996 |
+-static int seq_copy_in_user(char __user **bufptr, const void *src, int size) |
21997 |
++static int seq_copy_in_user(void *_bufptr, const void *src, int size) |
21998 |
+ { |
21999 |
++ char __user **bufptr = (char __user **)_bufptr; |
22000 |
++ |
22001 |
+ if (copy_to_user(*bufptr, src, size)) |
22002 |
+ return -EFAULT; |
22003 |
+ *bufptr += size; |
22004 |
+@@ -158,13 +162,13 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char |
22005 |
+ if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { |
22006 |
+ if (! in_kernel) |
22007 |
+ return -EINVAL; |
22008 |
+- if (copy_from_user(buf, (void __force __user *)event->data.ext.ptr, len)) |
22009 |
++ if (copy_from_user(buf, (void __force_user *)event->data.ext.ptr, len)) |
22010 |
+ return -EFAULT; |
22011 |
+ return newlen; |
22012 |
+ } |
22013 |
+ err = snd_seq_dump_var_event(event, |
22014 |
+- in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel : |
22015 |
+- (snd_seq_dump_func_t)seq_copy_in_user, |
22016 |
++ in_kernel ? seq_copy_in_kernel : |
22017 |
++ seq_copy_in_user, |
22018 |
+ &buf); |
22019 |
+ return err < 0 ? err : newlen; |
22020 |
+ } |
22021 |
+@@ -344,7 +348,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, |
22022 |
+ tmp->event = src->event; |
22023 |
+ src = src->next; |
22024 |
+ } else if (is_usrptr) { |
22025 |
+- if (copy_from_user(&tmp->event, (char __force __user *)buf, size)) { |
22026 |
++ if (copy_from_user(&tmp->event, (char __force_user *)buf, size)) { |
22027 |
+ err = -EFAULT; |
22028 |
+ goto __error; |
22029 |
+ } |
22030 |
+diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c |
22031 |
+index 5dd0ee2..0208e35 100644 |
22032 |
+--- a/sound/core/seq/seq_midi.c |
22033 |
++++ b/sound/core/seq/seq_midi.c |
22034 |
+@@ -111,8 +111,9 @@ static void snd_midi_input_event(struct snd_rawmidi_substream *substream) |
22035 |
+ } |
22036 |
+ } |
22037 |
+ |
22038 |
+-static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, int count) |
22039 |
++static int dump_midi(void *_substream, const void *buf, int count) |
22040 |
+ { |
22041 |
++ struct snd_rawmidi_substream *substream = _substream; |
22042 |
+ struct snd_rawmidi_runtime *runtime; |
22043 |
+ int tmp; |
22044 |
+ |
22045 |
+@@ -148,7 +149,7 @@ static int event_process_midi(struct snd_seq_event *ev, int direct, |
22046 |
+ pr_debug("ALSA: seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); |
22047 |
+ return 0; |
22048 |
+ } |
22049 |
+- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); |
22050 |
++ snd_seq_dump_var_event(ev, dump_midi, substream); |
22051 |
+ snd_midi_event_reset_decode(msynth->parser); |
22052 |
+ } else { |
22053 |
+ if (msynth->parser == NULL) |
22054 |
+diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c |
22055 |
+index c82ed3e..e11d039 100644 |
22056 |
+--- a/sound/core/seq/seq_virmidi.c |
22057 |
++++ b/sound/core/seq/seq_virmidi.c |
22058 |
+@@ -90,7 +90,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, |
22059 |
+ if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { |
22060 |
+ if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) |
22061 |
+ continue; |
22062 |
+- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream); |
22063 |
++ snd_seq_dump_var_event(ev, snd_rawmidi_receive, vmidi->substream); |
22064 |
+ } else { |
22065 |
+ len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); |
22066 |
+ if (len > 0) |
22067 |
+diff --git a/sound/core/sound.c b/sound/core/sound.c |
22068 |
+index 175f9e4..3518d31 100644 |
22069 |
+--- a/sound/core/sound.c |
22070 |
++++ b/sound/core/sound.c |
22071 |
+@@ -86,7 +86,7 @@ static void snd_request_other(int minor) |
22072 |
+ case SNDRV_MINOR_TIMER: str = "snd-timer"; break; |
22073 |
+ default: return; |
22074 |
+ } |
22075 |
+- request_module(str); |
22076 |
++ request_module("%s", str); |
22077 |
+ } |
22078 |
+ |
22079 |
+ #endif /* modular kernel */ |
22080 |
+diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c |
22081 |
+index 2a008a9..a1efb3f 100644 |
22082 |
+--- a/sound/drivers/mts64.c |
22083 |
++++ b/sound/drivers/mts64.c |
22084 |
+@@ -29,6 +29,7 @@ |
22085 |
+ #include <sound/initval.h> |
22086 |
+ #include <sound/rawmidi.h> |
22087 |
+ #include <sound/control.h> |
22088 |
++#include <asm/local.h> |
22089 |
+ |
22090 |
+ #define CARD_NAME "Miditerminal 4140" |
22091 |
+ #define DRIVER_NAME "MTS64" |
22092 |
+@@ -67,7 +68,7 @@ struct mts64 { |
22093 |
+ struct pardevice *pardev; |
22094 |
+ int pardev_claimed; |
22095 |
+ |
22096 |
+- int open_count; |
22097 |
++ local_t open_count; |
22098 |
+ int current_midi_output_port; |
22099 |
+ int current_midi_input_port; |
22100 |
+ u8 mode[MTS64_NUM_INPUT_PORTS]; |
22101 |
+@@ -687,7 +688,7 @@ static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream) |
22102 |
+ { |
22103 |
+ struct mts64 *mts = substream->rmidi->private_data; |
22104 |
+ |
22105 |
+- if (mts->open_count == 0) { |
22106 |
++ if (local_read(&mts->open_count) == 0) { |
22107 |
+ /* We don't need a spinlock here, because this is just called |
22108 |
+ if the device has not been opened before. |
22109 |
+ So there aren't any IRQs from the device */ |
22110 |
+@@ -695,7 +696,7 @@ static int snd_mts64_rawmidi_open(struct snd_rawmidi_substream *substream) |
22111 |
+ |
22112 |
+ msleep(50); |
22113 |
+ } |
22114 |
+- ++(mts->open_count); |
22115 |
++ local_inc(&mts->open_count); |
22116 |
+ |
22117 |
+ return 0; |
22118 |
+ } |
22119 |
+@@ -705,8 +706,7 @@ static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream) |
22120 |
+ struct mts64 *mts = substream->rmidi->private_data; |
22121 |
+ unsigned long flags; |
22122 |
+ |
22123 |
+- --(mts->open_count); |
22124 |
+- if (mts->open_count == 0) { |
22125 |
++ if (local_dec_return(&mts->open_count) == 0) { |
22126 |
+ /* We need the spinlock_irqsave here because we can still |
22127 |
+ have IRQs at this point */ |
22128 |
+ spin_lock_irqsave(&mts->lock, flags); |
22129 |
+@@ -715,8 +715,8 @@ static int snd_mts64_rawmidi_close(struct snd_rawmidi_substream *substream) |
22130 |
+ |
22131 |
+ msleep(500); |
22132 |
+ |
22133 |
+- } else if (mts->open_count < 0) |
22134 |
+- mts->open_count = 0; |
22135 |
++ } else if (local_read(&mts->open_count) < 0) |
22136 |
++ local_set(&mts->open_count, 0); |
22137 |
+ |
22138 |
+ return 0; |
22139 |
+ } |
22140 |
+diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c |
22141 |
+index 89c7aa0..6d75e49 100644 |
22142 |
+--- a/sound/drivers/opl4/opl4_lib.c |
22143 |
++++ b/sound/drivers/opl4/opl4_lib.c |
22144 |
+@@ -29,7 +29,7 @@ MODULE_AUTHOR("Clemens Ladisch <clemens@×××××××.de>"); |
22145 |
+ MODULE_DESCRIPTION("OPL4 driver"); |
22146 |
+ MODULE_LICENSE("GPL"); |
22147 |
+ |
22148 |
+-static void inline snd_opl4_wait(struct snd_opl4 *opl4) |
22149 |
++static inline void snd_opl4_wait(struct snd_opl4 *opl4) |
22150 |
+ { |
22151 |
+ int timeout = 10; |
22152 |
+ while ((inb(opl4->fm_port) & OPL4_STATUS_BUSY) && --timeout > 0) |
22153 |
+diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c |
22154 |
+index 464385a..46ab3f6 100644 |
22155 |
+--- a/sound/drivers/portman2x4.c |
22156 |
++++ b/sound/drivers/portman2x4.c |
22157 |
+@@ -48,6 +48,7 @@ |
22158 |
+ #include <sound/initval.h> |
22159 |
+ #include <sound/rawmidi.h> |
22160 |
+ #include <sound/control.h> |
22161 |
++#include <asm/local.h> |
22162 |
+ |
22163 |
+ #define CARD_NAME "Portman 2x4" |
22164 |
+ #define DRIVER_NAME "portman" |
22165 |
+@@ -85,7 +86,7 @@ struct portman { |
22166 |
+ struct pardevice *pardev; |
22167 |
+ int pardev_claimed; |
22168 |
+ |
22169 |
+- int open_count; |
22170 |
++ local_t open_count; |
22171 |
+ int mode[PORTMAN_NUM_INPUT_PORTS]; |
22172 |
+ struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS]; |
22173 |
+ }; |
22174 |
+diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c |
22175 |
+index bebddc6..f5976be 100644 |
22176 |
+--- a/sound/firewire/amdtp-am824.c |
22177 |
++++ b/sound/firewire/amdtp-am824.c |
22178 |
+@@ -314,7 +314,7 @@ void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port, |
22179 |
+ struct amdtp_am824 *p = s->protocol; |
22180 |
+ |
22181 |
+ if (port < p->midi_ports) |
22182 |
+- ACCESS_ONCE(p->midi[port]) = midi; |
22183 |
++ ACCESS_ONCE_RW(p->midi[port]) = midi; |
22184 |
+ } |
22185 |
+ EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger); |
22186 |
+ |
22187 |
+diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c |
22188 |
+index ed29026..933d2ae 100644 |
22189 |
+--- a/sound/firewire/amdtp-stream.c |
22190 |
++++ b/sound/firewire/amdtp-stream.c |
22191 |
+@@ -344,7 +344,7 @@ static void update_pcm_pointers(struct amdtp_stream *s, |
22192 |
+ ptr = s->pcm_buffer_pointer + frames; |
22193 |
+ if (ptr >= pcm->runtime->buffer_size) |
22194 |
+ ptr -= pcm->runtime->buffer_size; |
22195 |
+- ACCESS_ONCE(s->pcm_buffer_pointer) = ptr; |
22196 |
++ ACCESS_ONCE_RW(s->pcm_buffer_pointer) = ptr; |
22197 |
+ |
22198 |
+ s->pcm_period_pointer += frames; |
22199 |
+ if (s->pcm_period_pointer >= pcm->runtime->period_size) { |
22200 |
+@@ -811,7 +811,7 @@ EXPORT_SYMBOL(amdtp_stream_pcm_pointer); |
22201 |
+ void amdtp_stream_update(struct amdtp_stream *s) |
22202 |
+ { |
22203 |
+ /* Precomputing. */ |
22204 |
+- ACCESS_ONCE(s->source_node_id_field) = |
22205 |
++ ACCESS_ONCE_RW(s->source_node_id_field) = |
22206 |
+ (fw_parent_device(s->unit)->card->node_id << CIP_SID_SHIFT) & |
22207 |
+ CIP_SID_MASK; |
22208 |
+ } |
22209 |
+diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h |
22210 |
+index 8775704..8fea566 100644 |
22211 |
+--- a/sound/firewire/amdtp-stream.h |
22212 |
++++ b/sound/firewire/amdtp-stream.h |
22213 |
+@@ -215,7 +215,7 @@ static inline bool amdtp_stream_pcm_running(struct amdtp_stream *s) |
22214 |
+ static inline void amdtp_stream_pcm_trigger(struct amdtp_stream *s, |
22215 |
+ struct snd_pcm_substream *pcm) |
22216 |
+ { |
22217 |
+- ACCESS_ONCE(s->pcm) = pcm; |
22218 |
++ ACCESS_ONCE_RW(s->pcm) = pcm; |
22219 |
+ } |
22220 |
+ |
22221 |
+ static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc) |
22222 |
+diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c |
22223 |
+index 0ac92ab..a2081aa 100644 |
22224 |
+--- a/sound/firewire/digi00x/amdtp-dot.c |
22225 |
++++ b/sound/firewire/digi00x/amdtp-dot.c |
22226 |
+@@ -365,7 +365,7 @@ void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, |
22227 |
+ struct amdtp_dot *p = s->protocol; |
22228 |
+ |
22229 |
+ if (port < p->midi_ports) |
22230 |
+- ACCESS_ONCE(p->midi[port]) = midi; |
22231 |
++ ACCESS_ONCE_RW(p->midi[port]) = midi; |
22232 |
+ } |
22233 |
+ |
22234 |
+ static unsigned int process_tx_data_blocks(struct amdtp_stream *s, |
22235 |
+diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c |
22236 |
+index 48d6dca..a0266c23 100644 |
22237 |
+--- a/sound/firewire/isight.c |
22238 |
++++ b/sound/firewire/isight.c |
22239 |
+@@ -96,7 +96,7 @@ static void isight_update_pointers(struct isight *isight, unsigned int count) |
22240 |
+ ptr += count; |
22241 |
+ if (ptr >= runtime->buffer_size) |
22242 |
+ ptr -= runtime->buffer_size; |
22243 |
+- ACCESS_ONCE(isight->buffer_pointer) = ptr; |
22244 |
++ ACCESS_ONCE_RW(isight->buffer_pointer) = ptr; |
22245 |
+ |
22246 |
+ isight->period_counter += count; |
22247 |
+ if (isight->period_counter >= runtime->period_size) { |
22248 |
+@@ -293,7 +293,7 @@ static int isight_hw_params(struct snd_pcm_substream *substream, |
22249 |
+ if (err < 0) |
22250 |
+ return err; |
22251 |
+ |
22252 |
+- ACCESS_ONCE(isight->pcm_active) = true; |
22253 |
++ ACCESS_ONCE_RW(isight->pcm_active) = true; |
22254 |
+ |
22255 |
+ return 0; |
22256 |
+ } |
22257 |
+@@ -331,7 +331,7 @@ static int isight_hw_free(struct snd_pcm_substream *substream) |
22258 |
+ { |
22259 |
+ struct isight *isight = substream->private_data; |
22260 |
+ |
22261 |
+- ACCESS_ONCE(isight->pcm_active) = false; |
22262 |
++ ACCESS_ONCE_RW(isight->pcm_active) = false; |
22263 |
+ |
22264 |
+ mutex_lock(&isight->mutex); |
22265 |
+ isight_stop_streaming(isight); |
22266 |
+@@ -424,10 +424,10 @@ static int isight_trigger(struct snd_pcm_substream *substream, int cmd) |
22267 |
+ |
22268 |
+ switch (cmd) { |
22269 |
+ case SNDRV_PCM_TRIGGER_START: |
22270 |
+- ACCESS_ONCE(isight->pcm_running) = true; |
22271 |
++ ACCESS_ONCE_RW(isight->pcm_running) = true; |
22272 |
+ break; |
22273 |
+ case SNDRV_PCM_TRIGGER_STOP: |
22274 |
+- ACCESS_ONCE(isight->pcm_running) = false; |
22275 |
++ ACCESS_ONCE_RW(isight->pcm_running) = false; |
22276 |
+ break; |
22277 |
+ default: |
22278 |
+ return -EINVAL; |
22279 |
+diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c |
22280 |
+index bb53eb3..670cd89 100644 |
22281 |
+--- a/sound/firewire/oxfw/oxfw-scs1x.c |
22282 |
++++ b/sound/firewire/oxfw/oxfw-scs1x.c |
22283 |
+@@ -278,9 +278,9 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up) |
22284 |
+ |
22285 |
+ if (up) { |
22286 |
+ scs->input_escape_count = 0; |
22287 |
+- ACCESS_ONCE(scs->input) = stream; |
22288 |
++ ACCESS_ONCE_RW(scs->input) = stream; |
22289 |
+ } else { |
22290 |
+- ACCESS_ONCE(scs->input) = NULL; |
22291 |
++ ACCESS_ONCE_RW(scs->input) = NULL; |
22292 |
+ } |
22293 |
+ } |
22294 |
+ |
22295 |
+@@ -310,10 +310,10 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *stream, int up) |
22296 |
+ scs->output_escaped = false; |
22297 |
+ scs->output_idle = false; |
22298 |
+ |
22299 |
+- ACCESS_ONCE(scs->output) = stream; |
22300 |
++ ACCESS_ONCE_RW(scs->output) = stream; |
22301 |
+ tasklet_schedule(&scs->tasklet); |
22302 |
+ } else { |
22303 |
+- ACCESS_ONCE(scs->output) = NULL; |
22304 |
++ ACCESS_ONCE_RW(scs->output) = NULL; |
22305 |
+ } |
22306 |
+ } |
22307 |
+ static void midi_playback_drain(struct snd_rawmidi_substream *stream) |
22308 |
+diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c |
22309 |
+index dc91072..d85a10a 100644 |
22310 |
+--- a/sound/oss/sb_audio.c |
22311 |
++++ b/sound/oss/sb_audio.c |
22312 |
+@@ -900,7 +900,7 @@ sb16_copy_from_user(int dev, |
22313 |
+ buf16 = (signed short *)(localbuf + localoffs); |
22314 |
+ while (c) |
22315 |
+ { |
22316 |
+- locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c); |
22317 |
++ locallen = ((unsigned)c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c); |
22318 |
+ if (copy_from_user(lbuf8, |
22319 |
+ userbuf+useroffs + p, |
22320 |
+ locallen)) |
22321 |
+diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c |
22322 |
+index 213a416..aeab5c9 100644 |
22323 |
+--- a/sound/oss/swarm_cs4297a.c |
22324 |
++++ b/sound/oss/swarm_cs4297a.c |
22325 |
+@@ -2623,7 +2623,6 @@ static int __init cs4297a_init(void) |
22326 |
+ { |
22327 |
+ struct cs4297a_state *s; |
22328 |
+ u32 pwr, id; |
22329 |
+- mm_segment_t fs; |
22330 |
+ int rval; |
22331 |
+ u64 cfg; |
22332 |
+ int mdio_val; |
22333 |
+@@ -2709,22 +2708,23 @@ static int __init cs4297a_init(void) |
22334 |
+ if (!rval) { |
22335 |
+ char *sb1250_duart_present; |
22336 |
+ |
22337 |
++#if 0 |
22338 |
++ mm_segment_t fs; |
22339 |
+ fs = get_fs(); |
22340 |
+ set_fs(KERNEL_DS); |
22341 |
+-#if 0 |
22342 |
+ val = SOUND_MASK_LINE; |
22343 |
+ mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val); |
22344 |
+ for (i = 0; i < ARRAY_SIZE(initvol); i++) { |
22345 |
+ val = initvol[i].vol; |
22346 |
+ mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val); |
22347 |
+ } |
22348 |
++ set_fs(fs); |
22349 |
+ // cs4297a_write_ac97(s, 0x18, 0x0808); |
22350 |
+ #else |
22351 |
+ // cs4297a_write_ac97(s, 0x5e, 0x180); |
22352 |
+ cs4297a_write_ac97(s, 0x02, 0x0808); |
22353 |
+ cs4297a_write_ac97(s, 0x18, 0x0808); |
22354 |
+ #endif |
22355 |
+- set_fs(fs); |
22356 |
+ |
22357 |
+ list_add(&s->list, &cs4297a_devs); |
22358 |
+ |
22359 |
+diff --git a/sound/pci/als300.c b/sound/pci/als300.c |
22360 |
+index add3176..c9394d9 100644 |
22361 |
+--- a/sound/pci/als300.c |
22362 |
++++ b/sound/pci/als300.c |
22363 |
+@@ -647,7 +647,7 @@ static int snd_als300_create(struct snd_card *card, |
22364 |
+ struct snd_als300 **rchip) |
22365 |
+ { |
22366 |
+ struct snd_als300 *chip; |
22367 |
+- void *irq_handler; |
22368 |
++ irq_handler_t irq_handler; |
22369 |
+ int err; |
22370 |
+ |
22371 |
+ static struct snd_device_ops ops = { |
22372 |
+diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c |
22373 |
+index 1677143..85aca1d 100644 |
22374 |
+--- a/sound/pci/aw2/aw2-alsa.c |
22375 |
++++ b/sound/pci/aw2/aw2-alsa.c |
22376 |
+@@ -458,7 +458,6 @@ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) |
22377 |
+ |
22378 |
+ /* Define Interrupt callback */ |
22379 |
+ snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number, |
22380 |
+- (snd_aw2_saa7146_it_cb) |
22381 |
+ snd_pcm_period_elapsed, |
22382 |
+ (void *)substream); |
22383 |
+ |
22384 |
+@@ -487,7 +486,6 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) |
22385 |
+ |
22386 |
+ /* Define Interrupt callback */ |
22387 |
+ snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number, |
22388 |
+- (snd_aw2_saa7146_it_cb) |
22389 |
+ snd_pcm_period_elapsed, |
22390 |
+ (void *)substream); |
22391 |
+ |
22392 |
+diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c |
22393 |
+index 1d78904..d9c1056 100644 |
22394 |
+--- a/sound/pci/aw2/aw2-saa7146.c |
22395 |
++++ b/sound/pci/aw2/aw2-saa7146.c |
22396 |
+@@ -262,7 +262,7 @@ void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number, |
22397 |
+ { |
22398 |
+ if (stream_number < NB_STREAM_PLAYBACK) { |
22399 |
+ arr_substream_it_playback_cb[stream_number].p_it_callback = |
22400 |
+- (snd_aw2_saa7146_it_cb) p_it_callback; |
22401 |
++ p_it_callback; |
22402 |
+ arr_substream_it_playback_cb[stream_number].p_callback_param = |
22403 |
+ (void *)p_callback_param; |
22404 |
+ } |
22405 |
+@@ -275,7 +275,7 @@ void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number, |
22406 |
+ { |
22407 |
+ if (stream_number < NB_STREAM_CAPTURE) { |
22408 |
+ arr_substream_it_capture_cb[stream_number].p_it_callback = |
22409 |
+- (snd_aw2_saa7146_it_cb) p_it_callback; |
22410 |
++ p_it_callback; |
22411 |
+ arr_substream_it_capture_cb[stream_number].p_callback_param = |
22412 |
+ (void *)p_callback_param; |
22413 |
+ } |
22414 |
+diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c |
22415 |
+index 5fcbb06..f4b85df 100644 |
22416 |
+--- a/sound/pci/ctxfi/ctamixer.c |
22417 |
++++ b/sound/pci/ctxfi/ctamixer.c |
22418 |
+@@ -297,8 +297,9 @@ static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer) |
22419 |
+ return 0; |
22420 |
+ } |
22421 |
+ |
22422 |
+-int amixer_mgr_create(struct hw *hw, struct amixer_mgr **ramixer_mgr) |
22423 |
++int amixer_mgr_create(struct hw *hw, void **_ramixer_mgr) |
22424 |
+ { |
22425 |
++ struct amixer_mgr **ramixer_mgr = (struct amixer_mgr **)_ramixer_mgr; |
22426 |
+ int err; |
22427 |
+ struct amixer_mgr *amixer_mgr; |
22428 |
+ |
22429 |
+@@ -326,8 +327,10 @@ error: |
22430 |
+ return err; |
22431 |
+ } |
22432 |
+ |
22433 |
+-int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr) |
22434 |
++int amixer_mgr_destroy(void *_amixer_mgr) |
22435 |
+ { |
22436 |
++ struct amixer_mgr *amixer_mgr = _amixer_mgr; |
22437 |
+ |
22438 |
-+int plugin_is_GPL_compatible; |
22439 |
+ rsc_mgr_uninit(&amixer_mgr->mgr); |
22440 |
+ kfree(amixer_mgr); |
22441 |
+ return 0; |
22442 |
+@@ -452,8 +455,9 @@ static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum) |
22443 |
+ return 0; |
22444 |
+ } |
22445 |
+ |
22446 |
+-int sum_mgr_create(struct hw *hw, struct sum_mgr **rsum_mgr) |
22447 |
++int sum_mgr_create(struct hw *hw, void **_rsum_mgr) |
22448 |
+ { |
22449 |
++ struct sum_mgr **rsum_mgr = (struct sum_mgr **)_rsum_mgr; |
22450 |
+ int err; |
22451 |
+ struct sum_mgr *sum_mgr; |
22452 |
+ |
22453 |
+@@ -481,8 +485,10 @@ error: |
22454 |
+ return err; |
22455 |
+ } |
22456 |
+ |
22457 |
+-int sum_mgr_destroy(struct sum_mgr *sum_mgr) |
22458 |
++int sum_mgr_destroy(void *_sum_mgr) |
22459 |
+ { |
22460 |
++ struct sum_mgr *sum_mgr = _sum_mgr; |
22461 |
+ |
22462 |
-+static struct plugin_info structleak_plugin_info = { |
22463 |
-+ .version = "201602181345", |
22464 |
-+ .help = "disable\tdo not activate plugin\n", |
22465 |
-+}; |
22466 |
+ rsc_mgr_uninit(&sum_mgr->mgr); |
22467 |
+ kfree(sum_mgr); |
22468 |
+ return 0; |
22469 |
+diff --git a/sound/pci/ctxfi/ctamixer.h b/sound/pci/ctxfi/ctamixer.h |
22470 |
+index 2de18aa..2fbd01b 100644 |
22471 |
+--- a/sound/pci/ctxfi/ctamixer.h |
22472 |
++++ b/sound/pci/ctxfi/ctamixer.h |
22473 |
+@@ -47,8 +47,8 @@ struct sum_mgr { |
22474 |
+ }; |
22475 |
+ |
22476 |
+ /* Constructor and destructor of daio resource manager */ |
22477 |
+-int sum_mgr_create(struct hw *hw, struct sum_mgr **rsum_mgr); |
22478 |
+-int sum_mgr_destroy(struct sum_mgr *sum_mgr); |
22479 |
++int sum_mgr_create(struct hw *hw, void **rsum_mgr); |
22480 |
++int sum_mgr_destroy(void *sum_mgr); |
22481 |
+ |
22482 |
+ /* Define the descriptor of a amixer resource */ |
22483 |
+ struct amixer_rsc_ops; |
22484 |
+@@ -93,7 +93,7 @@ struct amixer_mgr { |
22485 |
+ }; |
22486 |
+ |
22487 |
+ /* Constructor and destructor of amixer resource manager */ |
22488 |
+-int amixer_mgr_create(struct hw *hw, struct amixer_mgr **ramixer_mgr); |
22489 |
+-int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr); |
22490 |
++int amixer_mgr_create(struct hw *hw, void **ramixer_mgr); |
22491 |
++int amixer_mgr_destroy(void *amixer_mgr); |
22492 |
+ |
22493 |
+ #endif /* CTAMIXER_H */ |
22494 |
+diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c |
22495 |
+index 977a598..a787004 100644 |
22496 |
+--- a/sound/pci/ctxfi/ctatc.c |
22497 |
++++ b/sound/pci/ctxfi/ctatc.c |
22498 |
+@@ -113,16 +113,16 @@ static struct { |
22499 |
+ int (*create)(struct hw *hw, void **rmgr); |
22500 |
+ int (*destroy)(void *mgr); |
22501 |
+ } rsc_mgr_funcs[NUM_RSCTYP] = { |
22502 |
+- [SRC] = { .create = (create_t)src_mgr_create, |
22503 |
+- .destroy = (destroy_t)src_mgr_destroy }, |
22504 |
+- [SRCIMP] = { .create = (create_t)srcimp_mgr_create, |
22505 |
+- .destroy = (destroy_t)srcimp_mgr_destroy }, |
22506 |
+- [AMIXER] = { .create = (create_t)amixer_mgr_create, |
22507 |
+- .destroy = (destroy_t)amixer_mgr_destroy }, |
22508 |
+- [SUM] = { .create = (create_t)sum_mgr_create, |
22509 |
+- .destroy = (destroy_t)sum_mgr_destroy }, |
22510 |
+- [DAIO] = { .create = (create_t)daio_mgr_create, |
22511 |
+- .destroy = (destroy_t)daio_mgr_destroy } |
22512 |
++ [SRC] = { .create = src_mgr_create, |
22513 |
++ .destroy = src_mgr_destroy }, |
22514 |
++ [SRCIMP] = { .create = srcimp_mgr_create, |
22515 |
++ .destroy = srcimp_mgr_destroy }, |
22516 |
++ [AMIXER] = { .create = amixer_mgr_create, |
22517 |
++ .destroy = amixer_mgr_destroy }, |
22518 |
++ [SUM] = { .create = sum_mgr_create, |
22519 |
++ .destroy = sum_mgr_destroy }, |
22520 |
++ [DAIO] = { .create = daio_mgr_create, |
22521 |
++ .destroy = daio_mgr_destroy } |
22522 |
+ }; |
22523 |
+ |
22524 |
+ static int |
22525 |
+diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c |
22526 |
+index 7f089cb..6bea28e 100644 |
22527 |
+--- a/sound/pci/ctxfi/ctdaio.c |
22528 |
++++ b/sound/pci/ctxfi/ctdaio.c |
22529 |
+@@ -687,8 +687,9 @@ static int daio_mgr_commit_write(struct daio_mgr *mgr) |
22530 |
+ return 0; |
22531 |
+ } |
22532 |
+ |
22533 |
+-int daio_mgr_create(struct hw *hw, struct daio_mgr **rdaio_mgr) |
22534 |
++int daio_mgr_create(struct hw *hw, void **_rdaio_mgr) |
22535 |
+ { |
22536 |
++ struct daio_mgr **rdaio_mgr = (struct daio_mgr **)_rdaio_mgr; |
22537 |
+ int err, i; |
22538 |
+ struct daio_mgr *daio_mgr; |
22539 |
+ struct imapper *entry; |
22540 |
+@@ -741,8 +742,9 @@ error1: |
22541 |
+ return err; |
22542 |
+ } |
22543 |
+ |
22544 |
+-int daio_mgr_destroy(struct daio_mgr *daio_mgr) |
22545 |
++int daio_mgr_destroy(void *_daio_mgr) |
22546 |
+ { |
22547 |
++ struct daio_mgr *daio_mgr = _daio_mgr; |
22548 |
+ unsigned long flags; |
22549 |
+ |
22550 |
+ /* free daio input mapper list */ |
22551 |
+diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h |
22552 |
+index a30be73..91b8dbd 100644 |
22553 |
+--- a/sound/pci/ctxfi/ctdaio.h |
22554 |
++++ b/sound/pci/ctxfi/ctdaio.h |
22555 |
+@@ -119,7 +119,7 @@ struct daio_mgr { |
22556 |
+ }; |
22557 |
+ |
22558 |
+ /* Constructor and destructor of daio resource manager */ |
22559 |
+-int daio_mgr_create(struct hw *hw, struct daio_mgr **rdaio_mgr); |
22560 |
+-int daio_mgr_destroy(struct daio_mgr *daio_mgr); |
22561 |
++int daio_mgr_create(struct hw *hw, void **rdaio_mgr); |
22562 |
++int daio_mgr_destroy(void *daio_mgr); |
22563 |
+ |
22564 |
+ #endif /* CTDAIO_H */ |
22565 |
+diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c |
22566 |
+index a5a72df..f86edb8 100644 |
22567 |
+--- a/sound/pci/ctxfi/ctsrc.c |
22568 |
++++ b/sound/pci/ctxfi/ctsrc.c |
22569 |
+@@ -544,8 +544,9 @@ static int src_mgr_commit_write(struct src_mgr *mgr) |
22570 |
+ return 0; |
22571 |
+ } |
22572 |
+ |
22573 |
+-int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr) |
22574 |
++int src_mgr_create(struct hw *hw, void **_rsrc_mgr) |
22575 |
+ { |
22576 |
++ struct src_mgr **rsrc_mgr = (struct src_mgr **)_rsrc_mgr; |
22577 |
+ int err, i; |
22578 |
+ struct src_mgr *src_mgr; |
22579 |
+ |
22580 |
+@@ -584,8 +585,10 @@ error1: |
22581 |
+ return err; |
22582 |
+ } |
22583 |
+ |
22584 |
+-int src_mgr_destroy(struct src_mgr *src_mgr) |
22585 |
++int src_mgr_destroy(void *_src_mgr) |
22586 |
+ { |
22587 |
++ struct src_mgr *src_mgr = _src_mgr; |
22588 |
+ |
22589 |
-+static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) |
22590 |
+ rsc_mgr_uninit(&src_mgr->mgr); |
22591 |
+ kfree(src_mgr); |
22592 |
+ |
22593 |
+@@ -828,8 +831,9 @@ static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry) |
22594 |
+ return err; |
22595 |
+ } |
22596 |
+ |
22597 |
+-int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrcimp_mgr) |
22598 |
++int srcimp_mgr_create(struct hw *hw, void **_rsrcimp_mgr) |
22599 |
+ { |
22600 |
++ struct srcimp_mgr **rsrcimp_mgr = (struct srcimp_mgr **)_rsrcimp_mgr; |
22601 |
+ int err; |
22602 |
+ struct srcimp_mgr *srcimp_mgr; |
22603 |
+ struct imapper *entry; |
22604 |
+@@ -873,8 +877,9 @@ error1: |
22605 |
+ return err; |
22606 |
+ } |
22607 |
+ |
22608 |
+-int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr) |
22609 |
++int srcimp_mgr_destroy(void *_srcimp_mgr) |
22610 |
+ { |
22611 |
++ struct srcimp_mgr *srcimp_mgr = _srcimp_mgr; |
22612 |
+ unsigned long flags; |
22613 |
+ |
22614 |
+ /* free src input mapper list */ |
22615 |
+diff --git a/sound/pci/ctxfi/ctsrc.h b/sound/pci/ctxfi/ctsrc.h |
22616 |
+index 92944a0..fc78ed4 100644 |
22617 |
+--- a/sound/pci/ctxfi/ctsrc.h |
22618 |
++++ b/sound/pci/ctxfi/ctsrc.h |
22619 |
+@@ -143,10 +143,10 @@ struct srcimp_mgr { |
22620 |
+ }; |
22621 |
+ |
22622 |
+ /* Constructor and destructor of SRC resource manager */ |
22623 |
+-int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr); |
22624 |
+-int src_mgr_destroy(struct src_mgr *src_mgr); |
22625 |
++int src_mgr_create(struct hw *hw, void **rsrc_mgr); |
22626 |
++int src_mgr_destroy(void *src_mgr); |
22627 |
+ /* Constructor and destructor of SRCIMP resource manager */ |
22628 |
+-int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrc_mgr); |
22629 |
+-int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr); |
22630 |
++int srcimp_mgr_create(struct hw *hw, void **rsrc_mgr); |
22631 |
++int srcimp_mgr_destroy(void *srcimp_mgr); |
22632 |
+ |
22633 |
+ #endif /* CTSRC_H */ |
22634 |
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c |
22635 |
+index 8374188..f073778 100644 |
22636 |
+--- a/sound/pci/hda/hda_codec.c |
22637 |
++++ b/sound/pci/hda/hda_codec.c |
22638 |
+@@ -1743,7 +1743,7 @@ static int get_kctl_0dB_offset(struct hda_codec *codec, |
22639 |
+ /* FIXME: set_fs() hack for obtaining user-space TLV data */ |
22640 |
+ mm_segment_t fs = get_fs(); |
22641 |
+ set_fs(get_ds()); |
22642 |
+- if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv)) |
22643 |
++ if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), (unsigned int __force_user *)_tlv)) |
22644 |
+ tlv = _tlv; |
22645 |
+ set_fs(fs); |
22646 |
+ } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) |
22647 |
+diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h |
22648 |
+index 149d4cb..7784769 100644 |
22649 |
+--- a/sound/pci/ymfpci/ymfpci.h |
22650 |
++++ b/sound/pci/ymfpci/ymfpci.h |
22651 |
+@@ -358,7 +358,7 @@ struct snd_ymfpci { |
22652 |
+ spinlock_t reg_lock; |
22653 |
+ spinlock_t voice_lock; |
22654 |
+ wait_queue_head_t interrupt_sleep; |
22655 |
+- atomic_t interrupt_sleep_count; |
22656 |
++ atomic_unchecked_t interrupt_sleep_count; |
22657 |
+ struct snd_info_entry *proc_entry; |
22658 |
+ const struct firmware *dsp_microcode; |
22659 |
+ const struct firmware *controller_microcode; |
22660 |
+diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c |
22661 |
+index 4c26076..a13f370 100644 |
22662 |
+--- a/sound/pci/ymfpci/ymfpci_main.c |
22663 |
++++ b/sound/pci/ymfpci/ymfpci_main.c |
22664 |
+@@ -204,8 +204,8 @@ static void snd_ymfpci_hw_stop(struct snd_ymfpci *chip) |
22665 |
+ if ((snd_ymfpci_readl(chip, YDSXGR_STATUS) & 2) == 0) |
22666 |
+ break; |
22667 |
+ } |
22668 |
+- if (atomic_read(&chip->interrupt_sleep_count)) { |
22669 |
+- atomic_set(&chip->interrupt_sleep_count, 0); |
22670 |
++ if (atomic_read_unchecked(&chip->interrupt_sleep_count)) { |
22671 |
++ atomic_set_unchecked(&chip->interrupt_sleep_count, 0); |
22672 |
+ wake_up(&chip->interrupt_sleep); |
22673 |
+ } |
22674 |
+ __end: |
22675 |
+@@ -789,7 +789,7 @@ static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip) |
22676 |
+ continue; |
22677 |
+ init_waitqueue_entry(&wait, current); |
22678 |
+ add_wait_queue(&chip->interrupt_sleep, &wait); |
22679 |
+- atomic_inc(&chip->interrupt_sleep_count); |
22680 |
++ atomic_inc_unchecked(&chip->interrupt_sleep_count); |
22681 |
+ schedule_timeout_uninterruptible(msecs_to_jiffies(50)); |
22682 |
+ remove_wait_queue(&chip->interrupt_sleep, &wait); |
22683 |
+ } |
22684 |
+@@ -827,8 +827,8 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id) |
22685 |
+ snd_ymfpci_writel(chip, YDSXGR_MODE, mode); |
22686 |
+ spin_unlock(&chip->reg_lock); |
22687 |
+ |
22688 |
+- if (atomic_read(&chip->interrupt_sleep_count)) { |
22689 |
+- atomic_set(&chip->interrupt_sleep_count, 0); |
22690 |
++ if (atomic_read_unchecked(&chip->interrupt_sleep_count)) { |
22691 |
++ atomic_set_unchecked(&chip->interrupt_sleep_count, 0); |
22692 |
+ wake_up(&chip->interrupt_sleep); |
22693 |
+ } |
22694 |
+ } |
22695 |
+@@ -2384,7 +2384,7 @@ int snd_ymfpci_create(struct snd_card *card, |
22696 |
+ spin_lock_init(&chip->reg_lock); |
22697 |
+ spin_lock_init(&chip->voice_lock); |
22698 |
+ init_waitqueue_head(&chip->interrupt_sleep); |
22699 |
+- atomic_set(&chip->interrupt_sleep_count, 0); |
22700 |
++ atomic_set_unchecked(&chip->interrupt_sleep_count, 0); |
22701 |
+ chip->card = card; |
22702 |
+ chip->pci = pci; |
22703 |
+ chip->irq = -1; |
22704 |
+diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c |
22705 |
+index d6f4abb..5d59f0c 100644 |
22706 |
+--- a/sound/soc/codecs/cx20442.c |
22707 |
++++ b/sound/soc/codecs/cx20442.c |
22708 |
+@@ -263,6 +263,12 @@ static int v253_hangup(struct tty_struct *tty) |
22709 |
+ return 0; |
22710 |
+ } |
22711 |
+ |
22712 |
++static int v253_hw_write(void *client, const char *buf, int count) |
22713 |
+{ |
22714 |
-+ *no_add_attrs = true; |
22715 |
-+ |
22716 |
-+ // check for types? for now accept everything linux has to offer |
22717 |
-+ if (TREE_CODE(*node) != FIELD_DECL) |
22718 |
-+ return NULL_TREE; |
22719 |
-+ |
22720 |
-+ *no_add_attrs = false; |
22721 |
-+ return NULL_TREE; |
22722 |
++ struct tty_struct *tty = client; |
22723 |
++ return tty->ops->write(client, buf, count); |
22724 |
+} |
22725 |
+ |
22726 |
-+static struct attribute_spec user_attr = { |
22727 |
-+ .name = "user", |
22728 |
-+ .min_length = 0, |
22729 |
-+ .max_length = 0, |
22730 |
-+ .decl_required = false, |
22731 |
-+ .type_required = false, |
22732 |
-+ .function_type_required = false, |
22733 |
-+ .handler = handle_user_attribute, |
22734 |
-+#if BUILDING_GCC_VERSION >= 4007 |
22735 |
-+ .affects_type_identity = true |
22736 |
-+#endif |
22737 |
-+}; |
22738 |
-+ |
22739 |
-+static void register_attributes(void *event_data, void *data) |
22740 |
+ /* Line discipline .receive_buf() */ |
22741 |
+ static void v253_receive(struct tty_struct *tty, |
22742 |
+ const unsigned char *cp, char *fp, int count) |
22743 |
+@@ -280,7 +286,7 @@ static void v253_receive(struct tty_struct *tty, |
22744 |
+ |
22745 |
+ /* Set up codec driver access to modem controls */ |
22746 |
+ cx20442->control_data = tty; |
22747 |
+- codec->hw_write = (hw_write_t)tty->ops->write; |
22748 |
++ codec->hw_write = v253_hw_write; |
22749 |
+ codec->component.card->pop_time = 1; |
22750 |
+ } |
22751 |
+ } |
22752 |
+diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c |
22753 |
+index 160d61a..cd7a4ac 100644 |
22754 |
+--- a/sound/soc/codecs/sti-sas.c |
22755 |
++++ b/sound/soc/codecs/sti-sas.c |
22756 |
+@@ -591,11 +591,13 @@ static int sti_sas_driver_probe(struct platform_device *pdev) |
22757 |
+ sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; |
22758 |
+ |
22759 |
+ /* Set dapms*/ |
22760 |
+- sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; |
22761 |
+- sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; |
22762 |
++ pax_open_kernel(); |
22763 |
++ const_cast(sti_sas_driver.dapm_widgets) = drvdata->dev_data->dapm_widgets; |
22764 |
++ const_cast(sti_sas_driver.num_dapm_widgets) = drvdata->dev_data->num_dapm_widgets; |
22765 |
+ |
22766 |
+- sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes; |
22767 |
+- sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; |
22768 |
++ const_cast(sti_sas_driver.dapm_routes) = drvdata->dev_data->dapm_routes; |
22769 |
++ const_cast(sti_sas_driver.num_dapm_routes) = drvdata->dev_data->num_dapm_routes; |
22770 |
++ pax_close_kernel(); |
22771 |
+ |
22772 |
+ /* Store context */ |
22773 |
+ dev_set_drvdata(&pdev->dev, drvdata); |
22774 |
+diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c |
22775 |
+index f7a6ce7..82310c8 100644 |
22776 |
+--- a/sound/soc/codecs/tlv320dac33.c |
22777 |
++++ b/sound/soc/codecs/tlv320dac33.c |
22778 |
+@@ -1375,13 +1375,18 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai, |
22779 |
+ return 0; |
22780 |
+ } |
22781 |
+ |
22782 |
++static int dac33_hw_write(void *client, const char *buf, int count) |
22783 |
+{ |
22784 |
-+ register_attribute(&user_attr); |
22785 |
-+// register_attribute(&force_attr); |
22786 |
++ return i2c_master_send(client, buf, count); |
22787 |
+} |
22788 |
+ |
22789 |
-+static tree get_field_type(tree field) |
22790 |
+ static int dac33_soc_probe(struct snd_soc_codec *codec) |
22791 |
+ { |
22792 |
+ struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
22793 |
+ int ret = 0; |
22794 |
+ |
22795 |
+ codec->control_data = dac33->control_data; |
22796 |
+- codec->hw_write = (hw_write_t) i2c_master_send; |
22797 |
++ codec->hw_write = dac33_hw_write; |
22798 |
+ dac33->codec = codec; |
22799 |
+ |
22800 |
+ /* Read the tlv320dac33 ID registers */ |
22801 |
+diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c |
22802 |
+index 35f0469..7c25cd5 100644 |
22803 |
+--- a/sound/soc/codecs/uda1380.c |
22804 |
++++ b/sound/soc/codecs/uda1380.c |
22805 |
+@@ -687,6 +687,11 @@ static struct snd_soc_dai_driver uda1380_dai[] = { |
22806 |
+ }, |
22807 |
+ }; |
22808 |
+ |
22809 |
++static int uda1380_hw_write(void *client, const char *buf, int count) |
22810 |
+{ |
22811 |
-+ return strip_array_types(TREE_TYPE(field)); |
22812 |
++ return i2c_master_send(client, buf, count); |
22813 |
+} |
22814 |
+ |
22815 |
-+static bool is_userspace_type(tree type) |
22816 |
-+{ |
22817 |
-+ tree field; |
22818 |
-+ |
22819 |
-+ for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { |
22820 |
-+ tree fieldtype = get_field_type(field); |
22821 |
-+ enum tree_code code = TREE_CODE(fieldtype); |
22822 |
-+ |
22823 |
-+ if (code == RECORD_TYPE || code == UNION_TYPE) |
22824 |
-+ if (is_userspace_type(fieldtype)) |
22825 |
-+ return true; |
22826 |
-+ |
22827 |
-+ if (lookup_attribute("user", DECL_ATTRIBUTES(field))) |
22828 |
-+ return true; |
22829 |
-+ } |
22830 |
-+ return false; |
22831 |
-+} |
22832 |
+ static int uda1380_probe(struct snd_soc_codec *codec) |
22833 |
+ { |
22834 |
+ struct uda1380_platform_data *pdata =codec->dev->platform_data; |
22835 |
+@@ -695,7 +700,7 @@ static int uda1380_probe(struct snd_soc_codec *codec) |
22836 |
+ |
22837 |
+ uda1380->codec = codec; |
22838 |
+ |
22839 |
+- codec->hw_write = (hw_write_t)i2c_master_send; |
22840 |
++ codec->hw_write = uda1380_hw_write; |
22841 |
+ codec->control_data = uda1380->control_data; |
22842 |
+ |
22843 |
+ if (!pdata) |
22844 |
+diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h |
22845 |
+index cbb4075..edda3dd 100644 |
22846 |
+--- a/sound/soc/intel/skylake/skl-sst-dsp.h |
22847 |
++++ b/sound/soc/intel/skylake/skl-sst-dsp.h |
22848 |
+@@ -117,14 +117,14 @@ struct skl_dsp_fw_ops { |
22849 |
+ int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, char *mod_name); |
22850 |
+ int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); |
22851 |
+ |
22852 |
+-}; |
22853 |
++} __no_const; |
22854 |
+ |
22855 |
+ struct skl_dsp_loader_ops { |
22856 |
+ int (*alloc_dma_buf)(struct device *dev, |
22857 |
+ struct snd_dma_buffer *dmab, size_t size); |
22858 |
+ int (*free_dma_buf)(struct device *dev, |
22859 |
+ struct snd_dma_buffer *dmab); |
22860 |
+-}; |
22861 |
++} __no_const; |
22862 |
+ |
22863 |
+ struct skl_load_module_info { |
22864 |
+ u16 mod_id; |
22865 |
+diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c |
22866 |
+index 7e0acd8..b4b2acb 100644 |
22867 |
+--- a/sound/soc/soc-ac97.c |
22868 |
++++ b/sound/soc/soc-ac97.c |
22869 |
+@@ -416,8 +416,10 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, |
22870 |
+ if (ret) |
22871 |
+ return ret; |
22872 |
+ |
22873 |
+- ops->warm_reset = snd_soc_ac97_warm_reset; |
22874 |
+- ops->reset = snd_soc_ac97_reset; |
22875 |
++ pax_open_kernel(); |
22876 |
++ const_cast(ops->warm_reset) = snd_soc_ac97_warm_reset; |
22877 |
++ const_cast(ops->reset) = snd_soc_ac97_reset; |
22878 |
++ pax_close_kernel(); |
22879 |
+ |
22880 |
+ snd_ac97_rst_cfg = cfg; |
22881 |
+ return 0; |
22882 |
+diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c |
22883 |
+index 8382ffa..86af7d0 100644 |
22884 |
+--- a/sound/soc/xtensa/xtfpga-i2s.c |
22885 |
++++ b/sound/soc/xtensa/xtfpga-i2s.c |
22886 |
+@@ -437,7 +437,7 @@ static int xtfpga_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
22887 |
+ case SNDRV_PCM_TRIGGER_START: |
22888 |
+ case SNDRV_PCM_TRIGGER_RESUME: |
22889 |
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
22890 |
+- ACCESS_ONCE(i2s->tx_ptr) = 0; |
22891 |
++ ACCESS_ONCE_RW(i2s->tx_ptr) = 0; |
22892 |
+ rcu_assign_pointer(i2s->tx_substream, substream); |
22893 |
+ xtfpga_pcm_refill_fifo(i2s); |
22894 |
+ break; |
22895 |
+diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c |
22896 |
+index a020920..55579f6 100644 |
22897 |
+--- a/sound/synth/emux/emux_seq.c |
22898 |
++++ b/sound/synth/emux/emux_seq.c |
22899 |
+@@ -33,13 +33,13 @@ static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *inf |
22900 |
+ * MIDI emulation operators |
22901 |
+ */ |
22902 |
+ static struct snd_midi_op emux_ops = { |
22903 |
+- snd_emux_note_on, |
22904 |
+- snd_emux_note_off, |
22905 |
+- snd_emux_key_press, |
22906 |
+- snd_emux_terminate_note, |
22907 |
+- snd_emux_control, |
22908 |
+- snd_emux_nrpn, |
22909 |
+- snd_emux_sysex, |
22910 |
++ .note_on = snd_emux_note_on, |
22911 |
++ .note_off = snd_emux_note_off, |
22912 |
++ .key_press = snd_emux_key_press, |
22913 |
++ .note_terminate = snd_emux_terminate_note, |
22914 |
++ .control = snd_emux_control, |
22915 |
++ .nrpn = snd_emux_nrpn, |
22916 |
++ .sysex = snd_emux_sysex, |
22917 |
+ }; |
22918 |
+ |
22919 |
+ |
22920 |
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c |
22921 |
+index 81b7da8..bb2676f 100644 |
22922 |
+--- a/sound/usb/line6/driver.c |
22923 |
++++ b/sound/usb/line6/driver.c |
22924 |
+@@ -307,7 +307,7 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, |
22925 |
+ { |
22926 |
+ struct usb_device *usbdev = line6->usbdev; |
22927 |
+ int ret; |
22928 |
+- unsigned char len; |
22929 |
++ unsigned char *plen; |
22930 |
+ unsigned count; |
22931 |
+ |
22932 |
+ if (address > 0xffff || datalen > 0xff) |
22933 |
+@@ -324,6 +324,10 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, |
22934 |
+ return ret; |
22935 |
+ } |
22936 |
+ |
22937 |
++ plen = kmalloc(1, GFP_KERNEL); |
22938 |
++ if (plen == NULL) |
22939 |
++ return -ENOMEM; |
22940 |
+ |
22941 |
-+static void finish_type(void *event_data, void *data) |
22942 |
-+{ |
22943 |
-+ tree type = (tree)event_data; |
22944 |
+ /* Wait for data length. We'll get 0xff until length arrives. */ |
22945 |
+ for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { |
22946 |
+ mdelay(LINE6_READ_WRITE_STATUS_DELAY); |
22947 |
+@@ -331,30 +335,35 @@ int line6_read_data(struct usb_line6 *line6, unsigned address, void *data, |
22948 |
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, |
22949 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | |
22950 |
+ USB_DIR_IN, |
22951 |
+- 0x0012, 0x0000, &len, 1, |
22952 |
++ 0x0012, 0x0000, plen, 1, |
22953 |
+ LINE6_TIMEOUT * HZ); |
22954 |
+ if (ret < 0) { |
22955 |
+ dev_err(line6->ifcdev, |
22956 |
+ "receive length failed (error %d)\n", ret); |
22957 |
++ kfree(plen); |
22958 |
+ return ret; |
22959 |
+ } |
22960 |
+ |
22961 |
+- if (len != 0xff) |
22962 |
++ if (*plen != 0xff) |
22963 |
+ break; |
22964 |
+ } |
22965 |
+ |
22966 |
+- if (len == 0xff) { |
22967 |
++ if (*plen == 0xff) { |
22968 |
+ dev_err(line6->ifcdev, "read failed after %d retries\n", |
22969 |
+ count); |
22970 |
++ kfree(plen); |
22971 |
+ return -EIO; |
22972 |
+- } else if (len != datalen) { |
22973 |
++ } else if (*plen != datalen) { |
22974 |
+ /* should be equal or something went wrong */ |
22975 |
+ dev_err(line6->ifcdev, |
22976 |
+ "length mismatch (expected %d, got %d)\n", |
22977 |
+- (int)datalen, (int)len); |
22978 |
++ (int)datalen, (int)*plen); |
22979 |
++ kfree(plen); |
22980 |
+ return -EIO; |
22981 |
+ } |
22982 |
+ |
22983 |
++ kfree(plen); |
22984 |
+ |
22985 |
-+ if (type == NULL_TREE || type == error_mark_node) |
22986 |
-+ return; |
22987 |
+ /* receive the result: */ |
22988 |
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, |
22989 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
22990 |
+@@ -378,7 +387,7 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, |
22991 |
+ { |
22992 |
+ struct usb_device *usbdev = line6->usbdev; |
22993 |
+ int ret; |
22994 |
+- unsigned char status; |
22995 |
++ unsigned char *status; |
22996 |
+ int count; |
22997 |
+ |
22998 |
+ if (address > 0xffff || datalen > 0xffff) |
22999 |
+@@ -395,6 +404,10 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, |
23000 |
+ return ret; |
23001 |
+ } |
23002 |
+ |
23003 |
++ status = kmalloc(1, GFP_KERNEL); |
23004 |
++ if (status == NULL) |
23005 |
++ return -ENOMEM; |
23006 |
+ |
23007 |
-+#if BUILDING_GCC_VERSION >= 5000 |
23008 |
-+ if (TREE_CODE(type) == ENUMERAL_TYPE) |
23009 |
-+ return; |
23010 |
-+#endif |
23011 |
+ for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { |
23012 |
+ mdelay(LINE6_READ_WRITE_STATUS_DELAY); |
23013 |
+ |
23014 |
+@@ -403,27 +416,32 @@ int line6_write_data(struct usb_line6 *line6, unsigned address, void *data, |
23015 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | |
23016 |
+ USB_DIR_IN, |
23017 |
+ 0x0012, 0x0000, |
23018 |
+- &status, 1, LINE6_TIMEOUT * HZ); |
23019 |
++ status, 1, LINE6_TIMEOUT * HZ); |
23020 |
+ |
23021 |
+ if (ret < 0) { |
23022 |
+ dev_err(line6->ifcdev, |
23023 |
+ "receiving status failed (error %d)\n", ret); |
23024 |
++ kfree(status); |
23025 |
+ return ret; |
23026 |
+ } |
23027 |
+ |
23028 |
+- if (status != 0xff) |
23029 |
++ if (*status != 0xff) |
23030 |
+ break; |
23031 |
+ } |
23032 |
+ |
23033 |
+- if (status == 0xff) { |
23034 |
++ if (*status == 0xff) { |
23035 |
+ dev_err(line6->ifcdev, "write failed after %d retries\n", |
23036 |
+ count); |
23037 |
++ kfree(status); |
23038 |
+ return -EIO; |
23039 |
+- } else if (status != 0) { |
23040 |
++ } else if (*status != 0) { |
23041 |
+ dev_err(line6->ifcdev, "write failed (error %d)\n", ret); |
23042 |
++ kfree(status); |
23043 |
+ return -EIO; |
23044 |
+ } |
23045 |
+ |
23046 |
++ kfree(status); |
23047 |
+ |
23048 |
-+ if (TYPE_USERSPACE(type)) |
23049 |
+ return 0; |
23050 |
+ } |
23051 |
+ EXPORT_SYMBOL_GPL(line6_write_data); |
23052 |
+diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c |
23053 |
+index 6d4c50c..aa658c8 100644 |
23054 |
+--- a/sound/usb/line6/toneport.c |
23055 |
++++ b/sound/usb/line6/toneport.c |
23056 |
+@@ -367,13 +367,19 @@ static bool toneport_has_source_select(struct usb_line6_toneport *toneport) |
23057 |
+ */ |
23058 |
+ static void toneport_setup(struct usb_line6_toneport *toneport) |
23059 |
+ { |
23060 |
+- int ticks; |
23061 |
++ int *ticks; |
23062 |
+ struct usb_line6 *line6 = &toneport->line6; |
23063 |
+ struct usb_device *usbdev = line6->usbdev; |
23064 |
+ |
23065 |
++ ticks = kmalloc(sizeof(int), GFP_KERNEL); |
23066 |
++ if (ticks == NULL) |
23067 |
+ return; |
23068 |
+ |
23069 |
-+ if (is_userspace_type(type)) |
23070 |
-+ TYPE_USERSPACE(type) = 1; |
23071 |
-+} |
23072 |
-+ |
23073 |
-+static void initialize(tree var) |
23074 |
-+{ |
23075 |
-+ basic_block bb; |
23076 |
-+ gimple_stmt_iterator gsi; |
23077 |
-+ tree initializer; |
23078 |
-+ gimple init_stmt; |
23079 |
-+ |
23080 |
-+ // this is the original entry bb before the forced split |
23081 |
-+ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
23082 |
-+ |
23083 |
-+ // first check if the variable is already initialized, warn otherwise |
23084 |
-+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { |
23085 |
-+ gimple stmt = gsi_stmt(gsi); |
23086 |
-+ tree rhs1; |
23087 |
-+ |
23088 |
-+ // we're looking for an assignment of a single rhs... |
23089 |
-+ if (!gimple_assign_single_p(stmt)) |
23090 |
-+ continue; |
23091 |
-+ rhs1 = gimple_assign_rhs1(stmt); |
23092 |
-+#if BUILDING_GCC_VERSION >= 4007 |
23093 |
-+ // ... of a non-clobbering expression... |
23094 |
-+ if (TREE_CLOBBER_P(rhs1)) |
23095 |
-+ continue; |
23096 |
-+#endif |
23097 |
-+ // ... to our variable... |
23098 |
-+ if (gimple_get_lhs(stmt) != var) |
23099 |
-+ continue; |
23100 |
-+ // if it's an initializer then we're good |
23101 |
-+ if (TREE_CODE(rhs1) == CONSTRUCTOR) |
23102 |
-+ return; |
23103 |
-+ } |
23104 |
-+ |
23105 |
-+ // these aren't the 0days you're looking for |
23106 |
-+// inform(DECL_SOURCE_LOCATION(var), "userspace variable will be forcibly initialized"); |
23107 |
-+ |
23108 |
-+ // build the initializer expression |
23109 |
-+ initializer = build_constructor(TREE_TYPE(var), NULL); |
23110 |
-+ |
23111 |
-+ // build the initializer stmt |
23112 |
-+ init_stmt = gimple_build_assign(var, initializer); |
23113 |
-+ gsi = gsi_after_labels(single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
23114 |
-+ gsi_insert_before(&gsi, init_stmt, GSI_NEW_STMT); |
23115 |
-+ update_stmt(init_stmt); |
23116 |
-+} |
23117 |
-+ |
23118 |
-+static unsigned int structleak_execute(void) |
23119 |
-+{ |
23120 |
-+ basic_block bb; |
23121 |
-+ unsigned int ret = 0; |
23122 |
-+ tree var; |
23123 |
-+ unsigned int i; |
23124 |
-+ |
23125 |
-+ // split the first bb where we can put the forced initializers |
23126 |
-+ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
23127 |
-+ bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); |
23128 |
-+ if (!single_pred_p(bb)) { |
23129 |
-+// gcc_assert(bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP)); |
23130 |
-+ split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
23131 |
-+ gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); |
23132 |
-+ } |
23133 |
-+ |
23134 |
-+ // enumarate all local variables and forcibly initialize our targets |
23135 |
-+ FOR_EACH_LOCAL_DECL(cfun, i, var) { |
23136 |
-+ tree type = TREE_TYPE(var); |
23137 |
-+ |
23138 |
-+ gcc_assert(DECL_P(var)); |
23139 |
-+ if (!auto_var_in_fn_p(var, current_function_decl)) |
23140 |
-+ continue; |
23141 |
-+ |
23142 |
-+ // only care about structure types |
23143 |
-+ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) |
23144 |
-+ continue; |
23145 |
-+ |
23146 |
-+ // if the type is of interest, examine the variable |
23147 |
-+ if (TYPE_USERSPACE(type)) |
23148 |
-+ initialize(var); |
23149 |
-+ } |
23150 |
-+ |
23151 |
-+ return ret; |
23152 |
-+} |
23153 |
-+ |
23154 |
-+#define PASS_NAME structleak |
23155 |
-+#define NO_GATE |
23156 |
-+#define PROPERTIES_REQUIRED PROP_cfg |
23157 |
-+#define TODO_FLAGS_FINISH TODO_verify_il | TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_remove_unused_locals | TODO_update_ssa | TODO_ggc_collect | TODO_verify_flow |
23158 |
-+#include "gcc-generate-gimple-pass.h" |
23159 |
-+ |
23160 |
-+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) |
23161 |
-+{ |
23162 |
-+ int i; |
23163 |
-+ const char * const plugin_name = plugin_info->base_name; |
23164 |
-+ const int argc = plugin_info->argc; |
23165 |
-+ const struct plugin_argument * const argv = plugin_info->argv; |
23166 |
-+ bool enable = true; |
23167 |
-+ struct register_pass_info structleak_pass_info; |
23168 |
-+ |
23169 |
-+ structleak_pass_info.pass = make_structleak_pass(); |
23170 |
-+ structleak_pass_info.reference_pass_name = "ssa"; |
23171 |
-+ structleak_pass_info.ref_pass_instance_number = 1; |
23172 |
-+ structleak_pass_info.pos_op = PASS_POS_INSERT_AFTER; |
23173 |
-+ |
23174 |
-+ if (!plugin_default_version_check(version, &gcc_version)) { |
23175 |
-+ error(G_("incompatible gcc/plugin versions")); |
23176 |
-+ return 1; |
23177 |
-+ } |
23178 |
-+ |
23179 |
-+ if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) { |
23180 |
-+ inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name); |
23181 |
-+ enable = false; |
23182 |
-+ } |
23183 |
-+ |
23184 |
-+ for (i = 0; i < argc; ++i) { |
23185 |
-+ if (!strcmp(argv[i].key, "disable")) { |
23186 |
-+ enable = false; |
23187 |
-+ continue; |
23188 |
-+ } |
23189 |
-+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); |
23190 |
-+ } |
23191 |
-+ |
23192 |
-+ register_callback(plugin_name, PLUGIN_INFO, NULL, &structleak_plugin_info); |
23193 |
-+ if (enable) { |
23194 |
-+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &structleak_pass_info); |
23195 |
-+ register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); |
23196 |
-+ } |
23197 |
-+ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); |
23198 |
+ /* sync time on device with host: */ |
23199 |
+- ticks = (int)get_seconds(); |
23200 |
+- line6_write_data(line6, 0x80c6, &ticks, 4); |
23201 |
++ *ticks = (int)get_seconds(); |
23202 |
++ line6_write_data(line6, 0x80c6, ticks, sizeof(int)); |
23203 |
+ |
23204 |
-+ return 0; |
23205 |
-+} |
23206 |
++ kfree(ticks); |
23207 |
+ |
23208 |
+ /* enable device: */ |
23209 |
+ toneport_send_cmd(usbdev, 0x0301, 0x0000); |
23210 |
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h |
23211 |
index fa7208a..d568e71 100644 |
23212 |
--- a/tools/include/linux/compiler.h |