Gentoo Archives: gentoo-commits

From: "Anthony G. Basile" <blueness@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/hardened-patchset:master commit in: 4.5.5/
Date: Mon, 30 May 2016 07:59:31
Message-Id: 1464595217.91c3b96e63792590118e17193061908a07017497.blueness@gentoo
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 *)&centrino_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 = &gt_ggc_mx_tree_node,
6579 ++ .pchw = &gt_pch_nx_tree_node
6580 ++ },
6581 ++ {
6582 ++ .base = &context_error_decl,
6583 ++ .nelt = 1,
6584 ++ .stride = sizeof(context_error_decl),
6585 ++ .cb = &gt_ggc_mx_tree_node,
6586 ++ .pchw = &gt_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 *)&gt_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 = &gt_ggc_mx_tree_node,
10210 -+ .pchw = &gt_pch_nx_tree_node
10211 -+ },
10212 -+ {
10213 -+ .base = &context_error_decl,
10214 -+ .nelt = 1,
10215 -+ .stride = sizeof(context_error_decl),
10216 -+ .cb = &gt_ggc_mx_tree_node,
10217 -+ .pchw = &gt_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 *)&gt_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 *)&gt_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 *)&gt_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 = &gt_ggc_mx_tree_node,
13968 ++ .pchw = &gt_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 *)&gt_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 = &gt_ggc_mx_tree_node,
16076 -+ .pchw = &gt_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 *)&gt_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 = &gt_ggc_mx_tree_node,
18095 ++ .pchw = &gt_pch_nx_tree_node
18096 ++ },
18097 ++ {
18098 ++ .base = &check_function_decl,
18099 ++ .nelt = 1,
18100 ++ .stride = sizeof(check_function_decl),
18101 ++ .cb = &gt_ggc_mx_tree_node,
18102 ++ .pchw = &gt_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 *)&gt_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 = &gt_ggc_mx_tree_node,
21145 -+ .pchw = &gt_pch_nx_tree_node
21146 -+ },
21147 -+ {
21148 -+ .base = &check_function_decl,
21149 -+ .nelt = 1,
21150 -+ .stride = sizeof(check_function_decl),
21151 -+ .cb = &gt_ggc_mx_tree_node,
21152 -+ .pchw = &gt_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 *)&gt_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