1 |
commit: 1fcb85d82cad5b7b799e05df97d774548925a2e2 |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Jul 7 07:56:33 2016 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Jul 7 07:56:33 2016 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=1fcb85d8 |
7 |
|
8 |
grsecurity-3.1-4.6.3-201607062159 |
9 |
|
10 |
4.6.3/0000_README | 2 +- |
11 |
...> 4420_grsecurity-3.1-4.6.3-201607062159.patch} | 546 ++++++++++++++++----- |
12 |
2 files changed, 413 insertions(+), 135 deletions(-) |
13 |
|
14 |
diff --git a/4.6.3/0000_README b/4.6.3/0000_README |
15 |
index a40de90..00f1875 100644 |
16 |
--- a/4.6.3/0000_README |
17 |
+++ b/4.6.3/0000_README |
18 |
@@ -6,7 +6,7 @@ Patch: 1002_linux-4.6.3.patch |
19 |
From: http://www.kernel.org |
20 |
Desc: Linux 4.6.3 |
21 |
|
22 |
-Patch: 4420_grsecurity-3.1-4.6.3-201607060823.patch |
23 |
+Patch: 4420_grsecurity-3.1-4.6.3-201607062159.patch |
24 |
From: http://www.grsecurity.net |
25 |
Desc: hardened-sources base patch from upstream grsecurity |
26 |
|
27 |
|
28 |
diff --git a/4.6.3/4420_grsecurity-3.1-4.6.3-201607060823.patch b/4.6.3/4420_grsecurity-3.1-4.6.3-201607062159.patch |
29 |
similarity index 99% |
30 |
rename from 4.6.3/4420_grsecurity-3.1-4.6.3-201607060823.patch |
31 |
rename to 4.6.3/4420_grsecurity-3.1-4.6.3-201607062159.patch |
32 |
index 92e7d0d..169d0af 100644 |
33 |
--- a/4.6.3/4420_grsecurity-3.1-4.6.3-201607060823.patch |
34 |
+++ b/4.6.3/4420_grsecurity-3.1-4.6.3-201607062159.patch |
35 |
@@ -3541,7 +3541,7 @@ index ff0a68c..b312aa0 100644 |
36 |
sizeof(struct omap_wd_timer_platform_data)); |
37 |
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", |
38 |
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c |
39 |
-index 92ec8c3..3df2546 100644 |
40 |
+index 92ec8c3..3b09472 100644 |
41 |
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c |
42 |
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c |
43 |
@@ -240,7 +240,7 @@ static struct platform_device smdk6410_b_pwr_5v = { |
44 |
@@ -3549,7 +3549,7 @@ index 92ec8c3..3df2546 100644 |
45 |
#endif |
46 |
|
47 |
-static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = { |
48 |
-+static struct s3c_ide_platdata smdk6410_ide_pdata __initconst = { |
49 |
++static const struct s3c_ide_platdata smdk6410_ide_pdata __initconst = { |
50 |
.setup_gpio = s3c64xx_ide_setup_gpio, |
51 |
}; |
52 |
|
53 |
@@ -3795,7 +3795,7 @@ index c8c8b9e..c55cc79 100644 |
54 |
atomic64_set(&mm->context.id, asid); |
55 |
} |
56 |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c |
57 |
-index ad58418..c0349f4 100644 |
58 |
+index ad58418..8267ca5 100644 |
59 |
--- a/arch/arm/mm/fault.c |
60 |
+++ b/arch/arm/mm/fault.c |
61 |
@@ -25,6 +25,7 @@ |
62 |
@@ -4010,7 +4010,7 @@ index ad58418..c0349f4 100644 |
63 |
+#else |
64 |
+ unsigned int bkpt; |
65 |
+ |
66 |
-+ if (!probe_kernel_address((const void *)pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) { |
67 |
++ if (!probe_kernel_address((const unsigned int *)pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) { |
68 |
+#endif |
69 |
+ current->thread.error_code = ifsr; |
70 |
+ current->thread.trap_no = 0; |
71 |
@@ -20635,6 +20635,22 @@ index fe884e1..46149ae 100644 |
72 |
static inline void release_dma_lock(unsigned long flags) |
73 |
{ |
74 |
spin_unlock_irqrestore(&dma_spin_lock, flags); |
75 |
+diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h |
76 |
+index 53748c4..283147d 100644 |
77 |
+--- a/arch/x86/include/asm/efi.h |
78 |
++++ b/arch/x86/include/asm/efi.h |
79 |
+@@ -168,6 +168,11 @@ static inline bool efi_is_native(void) |
80 |
+ |
81 |
+ static inline bool efi_runtime_supported(void) |
82 |
+ { |
83 |
++ |
84 |
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) |
85 |
++ return false; |
86 |
++#endif |
87 |
++ |
88 |
+ if (efi_is_native()) |
89 |
+ return true; |
90 |
+ |
91 |
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h |
92 |
index 15340e3..f338653 100644 |
93 |
--- a/arch/x86/include/asm/elf.h |
94 |
@@ -22128,7 +22144,7 @@ index cdaa58c..ae30f0d 100644 |
95 |
|
96 |
static inline void pud_clear(pud_t *pudp) |
97 |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h |
98 |
-index 97f3242..0d17a84 100644 |
99 |
+index 97f3242..2603a59 100644 |
100 |
--- a/arch/x86/include/asm/pgtable.h |
101 |
+++ b/arch/x86/include/asm/pgtable.h |
102 |
@@ -54,6 +54,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); |
103 |
@@ -22236,6 +22252,15 @@ index 97f3242..0d17a84 100644 |
104 |
} |
105 |
|
106 |
static inline pte_t pte_mkdirty(pte_t pte) |
107 |
+@@ -430,7 +497,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) |
108 |
+ |
109 |
+ #define canon_pgprot(p) __pgprot(massage_pgprot(p)) |
110 |
+ |
111 |
+-static inline int is_new_memtype_allowed(u64 paddr, unsigned long size, |
112 |
++static inline int is_new_memtype_allowed(u64 paddr, u64 size, |
113 |
+ enum page_cache_mode pcm, |
114 |
+ enum page_cache_mode new_pcm) |
115 |
+ { |
116 |
@@ -473,6 +540,16 @@ pte_t *populate_extra_pte(unsigned long vaddr); |
117 |
#endif |
118 |
|
119 |
@@ -34983,6 +35008,103 @@ index f989132..7c590d6 100644 |
120 |
+quote:=" |
121 |
+obj-$(CONFIG_X86_64) += uderef_64.o |
122 |
+CFLAGS_uderef_64.o := $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) -fcall-saved-rax |
123 |
+diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c |
124 |
+index 99bfb19..237fb1d 100644 |
125 |
+--- a/arch/x86/mm/dump_pagetables.c |
126 |
++++ b/arch/x86/mm/dump_pagetables.c |
127 |
+@@ -27,6 +27,7 @@ |
128 |
+ struct pg_state { |
129 |
+ int level; |
130 |
+ pgprot_t current_prot; |
131 |
++ pgprot_t current_prots[5]; |
132 |
+ unsigned long start_address; |
133 |
+ unsigned long current_address; |
134 |
+ const struct addr_marker *marker; |
135 |
+@@ -184,6 +185,23 @@ static unsigned long normalize_addr(unsigned long u) |
136 |
+ #endif |
137 |
+ } |
138 |
+ |
139 |
++static pgprot_t merge_prot(pgprot_t old_prot, pgprot_t new_prot) |
140 |
++{ |
141 |
++ if (!(pgprot_val(new_prot) & _PAGE_PRESENT)) |
142 |
++ return new_prot; |
143 |
++ |
144 |
++ if (!(pgprot_val(old_prot) & _PAGE_PRESENT)) |
145 |
++ return new_prot; |
146 |
++ |
147 |
++ if (pgprot_val(old_prot) & _PAGE_NX) |
148 |
++ pgprot_val(new_prot) |= _PAGE_NX; |
149 |
++ |
150 |
++ if (!(pgprot_val(old_prot) & _PAGE_RW)) |
151 |
++ pgprot_val(new_prot) &= ~_PAGE_RW; |
152 |
++ |
153 |
++ return new_prot; |
154 |
++} |
155 |
++ |
156 |
+ /* |
157 |
+ * This function gets called on a break in a continuous series |
158 |
+ * of PTE entries; the next one is different so we need to |
159 |
+@@ -200,11 +218,13 @@ static void note_page(struct seq_file *m, struct pg_state *st, |
160 |
+ * we have now. "break" is either changing perms, levels or |
161 |
+ * address space marker. |
162 |
+ */ |
163 |
++ new_prot = merge_prot(st->current_prots[level - 1], new_prot); |
164 |
+ prot = pgprot_val(new_prot); |
165 |
+ cur = pgprot_val(st->current_prot); |
166 |
+ |
167 |
+ if (!st->level) { |
168 |
+ /* First entry */ |
169 |
++ st->current_prots[0] = __pgprot(_PAGE_RW); |
170 |
+ st->current_prot = new_prot; |
171 |
+ st->level = level; |
172 |
+ st->marker = address_markers; |
173 |
+@@ -216,9 +236,8 @@ static void note_page(struct seq_file *m, struct pg_state *st, |
174 |
+ const char *unit = units; |
175 |
+ unsigned long delta; |
176 |
+ int width = sizeof(unsigned long) * 2; |
177 |
+- pgprotval_t pr = pgprot_val(st->current_prot); |
178 |
+ |
179 |
+- if (st->check_wx && (pr & _PAGE_RW) && !(pr & _PAGE_NX)) { |
180 |
++ if (st->check_wx && (cur & _PAGE_RW) && !(cur & _PAGE_NX)) { |
181 |
+ WARN_ONCE(1, |
182 |
+ "x86/mm: Found insecure W+X mapping at address %p/%pS\n", |
183 |
+ (void *)st->start_address, |
184 |
+@@ -304,9 +323,10 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr, |
185 |
+ start = (pmd_t *) pud_page_vaddr(addr); |
186 |
+ for (i = 0; i < PTRS_PER_PMD; i++) { |
187 |
+ st->current_address = normalize_addr(P + i * PMD_LEVEL_MULT); |
188 |
++ prot = pmd_flags(*start); |
189 |
++ st->current_prots[3] = merge_prot(st->current_prots[2], __pgprot(prot)); |
190 |
+ if (!pmd_none(*start)) { |
191 |
+ if (pmd_large(*start) || !pmd_present(*start)) { |
192 |
+- prot = pmd_flags(*start); |
193 |
+ note_page(m, st, __pgprot(prot), 3); |
194 |
+ } else { |
195 |
+ walk_pte_level(m, st, *start, |
196 |
+@@ -337,9 +357,10 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr, |
197 |
+ |
198 |
+ for (i = 0; i < PTRS_PER_PUD; i++) { |
199 |
+ st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT); |
200 |
++ prot = pud_flags(*start); |
201 |
++ st->current_prots[2] = merge_prot(st->current_prots[1], __pgprot(start->pud)); |
202 |
+ if (!pud_none(*start)) { |
203 |
+ if (pud_large(*start) || !pud_present(*start)) { |
204 |
+- prot = pud_flags(*start); |
205 |
+ note_page(m, st, __pgprot(prot), 2); |
206 |
+ } else { |
207 |
+ walk_pmd_level(m, st, *start, |
208 |
+@@ -395,9 +416,10 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, |
209 |
+ |
210 |
+ for (i = 0; i < PTRS_PER_PGD; i++) { |
211 |
+ st.current_address = normalize_addr(i * PGD_LEVEL_MULT); |
212 |
++ prot = pgd_flags(*start); |
213 |
++ st.current_prots[1] = __pgprot(prot); |
214 |
+ if (!pgd_none(*start) && !is_hypervisor_range(i)) { |
215 |
+ if (pgd_large(*start) || !pgd_present(*start)) { |
216 |
+- prot = pgd_flags(*start); |
217 |
+ note_page(m, &st, __pgprot(prot), 1); |
218 |
+ } else { |
219 |
+ walk_pud_level(m, &st, *start, |
220 |
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c |
221 |
index 82447b3..95c2b03 100644 |
222 |
--- a/arch/x86/mm/extable.c |
223 |
@@ -36034,7 +36156,7 @@ index 9d56f27..0d15fff 100644 |
224 |
(unsigned long)(&__init_begin), |
225 |
(unsigned long)(&__init_end)); |
226 |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c |
227 |
-index bd7a9b9..2cc3f46 100644 |
228 |
+index bd7a9b9..94d80a5 100644 |
229 |
--- a/arch/x86/mm/init_32.c |
230 |
+++ b/arch/x86/mm/init_32.c |
231 |
@@ -62,33 +62,6 @@ static noinline int do_test_wp_bit(void); |
232 |
@@ -36262,6 +36384,15 @@ index bd7a9b9..2cc3f46 100644 |
233 |
((unsigned long)&_etext - (unsigned long)&_text) >> 10); |
234 |
|
235 |
/* |
236 |
+@@ -871,7 +873,7 @@ static noinline int do_test_wp_bit(void) |
237 |
+ const int rodata_test_data = 0xC3; |
238 |
+ EXPORT_SYMBOL_GPL(rodata_test_data); |
239 |
+ |
240 |
+-int kernel_set_to_readonly __read_mostly; |
241 |
++int kernel_set_to_readonly __read_only; |
242 |
+ |
243 |
+ void set_kernel_text_rw(void) |
244 |
+ { |
245 |
@@ -881,6 +883,7 @@ void set_kernel_text_rw(void) |
246 |
if (!kernel_set_to_readonly) |
247 |
return; |
248 |
@@ -36287,7 +36418,7 @@ index bd7a9b9..2cc3f46 100644 |
249 |
/* |
250 |
* This comes from is_kernel_text upper limit. Also HPAGE where used: |
251 |
*/ |
252 |
-@@ -923,26 +927,49 @@ void mark_rodata_ro(void) |
253 |
+@@ -923,26 +927,52 @@ void mark_rodata_ro(void) |
254 |
unsigned long start = PFN_ALIGN(_text); |
255 |
unsigned long size = PFN_ALIGN(_etext) - start; |
256 |
|
257 |
@@ -36295,49 +36426,48 @@ index bd7a9b9..2cc3f46 100644 |
258 |
- printk(KERN_INFO "Write protecting the kernel text: %luk\n", |
259 |
- size >> 10); |
260 |
+#ifdef CONFIG_PAX_KERNEXEC |
261 |
-+ { |
262 |
-+ /* PaX: limit KERNEL_CS to actual size */ |
263 |
-+ unsigned long limit; |
264 |
-+ struct desc_struct d; |
265 |
-+ int cpu; |
266 |
++ /* PaX: limit KERNEL_CS to actual size */ |
267 |
++ unsigned long limit; |
268 |
++ struct desc_struct d; |
269 |
++ int cpu; |
270 |
|
271 |
-- kernel_set_to_readonly = 1; |
272 |
-+ limit = paravirt_enabled() ? ktva_ktla(0xffffffff) : (unsigned long)&_etext; |
273 |
-+ limit = (limit - 1UL) >> PAGE_SHIFT; |
274 |
++ limit = paravirt_enabled() ? ktva_ktla(0xffffffff) : (unsigned long)&_etext; |
275 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
276 |
+ |
277 |
-+ memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE); |
278 |
-+ for (cpu = 0; cpu < nr_cpu_ids; cpu++) { |
279 |
-+ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC); |
280 |
-+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S); |
281 |
-+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEXEC_KERNEL_CS, &d, DESCTYPE_S); |
282 |
-+ } |
283 |
-+ |
284 |
-+ if (config_enabled(CONFIG_MODULES)) |
285 |
-+ set_memory_4k((unsigned long)MODULES_EXEC_VADDR, (MODULES_EXEC_END - MODULES_EXEC_VADDR) >> PAGE_SHIFT); |
286 |
++ memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE); |
287 |
++ for (cpu = 0; cpu < nr_cpu_ids; cpu++) { |
288 |
++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC); |
289 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S); |
290 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEXEC_KERNEL_CS, &d, DESCTYPE_S); |
291 |
+ } |
292 |
++ |
293 |
++#ifdef CONFIG_MODULES |
294 |
++ set_memory_4k((unsigned long)MODULES_EXEC_VADDR, (MODULES_EXEC_END - MODULES_EXEC_VADDR) >> PAGE_SHIFT); |
295 |
++#endif |
296 |
+#endif |
297 |
+ |
298 |
+ start = ktla_ktva(start); |
299 |
++#ifdef CONFIG_PAX_KERNEXEC |
300 |
+ /* PaX: make KERNEL_CS read-only */ |
301 |
-+ if (config_enabled(CONFIG_PAX_KERNEXEC) && !paravirt_enabled()) { |
302 |
-+ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); |
303 |
-+ printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); |
304 |
-+ |
305 |
-+ kernel_set_to_readonly = 1; |
306 |
++ if (!paravirt_enabled()) { |
307 |
++#endif |
308 |
+ kernel_set_to_readonly = 1; |
309 |
|
310 |
++ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); |
311 |
++ printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); |
312 |
++ |
313 |
#ifdef CONFIG_CPA_DEBUG |
314 |
- printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n", |
315 |
- start, start+size); |
316 |
-- set_pages_rw(virt_to_page(start), size>>PAGE_SHIFT); |
317 |
-+ printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n", start, start+size); |
318 |
-+ set_pages_rw(virt_to_page(start), size>>PAGE_SHIFT); |
319 |
++ printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n", start, start+size); |
320 |
+ set_pages_rw(virt_to_page(start), size>>PAGE_SHIFT); |
321 |
|
322 |
-- printk(KERN_INFO "Testing CPA: write protecting again\n"); |
323 |
-- set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); |
324 |
-+ printk(KERN_INFO "Testing CPA: write protecting again\n"); |
325 |
-+ set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); |
326 |
+ printk(KERN_INFO "Testing CPA: write protecting again\n"); |
327 |
+ set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); |
328 |
#endif |
329 |
++#ifdef CONFIG_PAX_KERNEXEC |
330 |
+ } |
331 |
++#endif |
332 |
|
333 |
start += size; |
334 |
- size = (unsigned long)__end_rodata - start; |
335 |
@@ -36350,7 +36480,7 @@ index bd7a9b9..2cc3f46 100644 |
336 |
|
337 |
#ifdef CONFIG_CPA_DEBUG |
338 |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c |
339 |
-index 214afda..444aa18 100644 |
340 |
+index 214afda..7fd6c3f 100644 |
341 |
--- a/arch/x86/mm/init_64.c |
342 |
+++ b/arch/x86/mm/init_64.c |
343 |
@@ -138,7 +138,7 @@ int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, |
344 |
@@ -36483,6 +36613,15 @@ index 214afda..444aa18 100644 |
345 |
spin_unlock(&init_mm.page_table_lock); |
346 |
pgd_changed = true; |
347 |
} |
348 |
+@@ -1078,7 +1106,7 @@ void __init mem_init(void) |
349 |
+ const int rodata_test_data = 0xC3; |
350 |
+ EXPORT_SYMBOL_GPL(rodata_test_data); |
351 |
+ |
352 |
+-int kernel_set_to_readonly; |
353 |
++int kernel_set_to_readonly __read_only; |
354 |
+ |
355 |
+ void set_kernel_text_rw(void) |
356 |
+ { |
357 |
@@ -1107,8 +1135,7 @@ void set_kernel_text_ro(void) |
358 |
if (!kernel_set_to_readonly) |
359 |
return; |
360 |
@@ -36493,29 +36632,34 @@ index 214afda..444aa18 100644 |
361 |
|
362 |
/* |
363 |
* Set the kernel identity mapping for text RO. |
364 |
-@@ -1118,15 +1145,20 @@ void set_kernel_text_ro(void) |
365 |
- |
366 |
+@@ -1119,18 +1146,23 @@ void set_kernel_text_ro(void) |
367 |
void mark_rodata_ro(void) |
368 |
{ |
369 |
-+ unsigned long addr; |
370 |
unsigned long start = PFN_ALIGN(_text); |
371 |
- unsigned long rodata_start = PFN_ALIGN(__start_rodata); |
372 |
+#ifdef CONFIG_PAX_KERNEXEC |
373 |
++ unsigned long addr; |
374 |
+ unsigned long end = PFN_ALIGN(_sdata); |
375 |
+ unsigned long text_end = end; |
376 |
+#else |
377 |
+ unsigned long rodata_start = PFN_ALIGN(__start_rodata); |
378 |
unsigned long end = (unsigned long) &__end_rodata_hpage_align; |
379 |
unsigned long text_end = PFN_ALIGN(&__stop___ex_table); |
380 |
-+#endif |
381 |
unsigned long rodata_end = PFN_ALIGN(&__end_rodata); |
382 |
++#endif |
383 |
unsigned long all_end; |
384 |
|
385 |
- printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", |
386 |
- (end - start) >> 10); |
387 |
-+ printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", (end - start) >> 10); |
388 |
- set_memory_ro(start, (end - start) >> PAGE_SHIFT); |
389 |
- |
390 |
+- set_memory_ro(start, (end - start) >> PAGE_SHIFT); |
391 |
+- |
392 |
kernel_set_to_readonly = 1; |
393 |
+ |
394 |
++ printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", (end - start) >> 10); |
395 |
++ set_memory_ro(start, (end - start) >> PAGE_SHIFT); |
396 |
++ |
397 |
+ /* |
398 |
+ * The rodata/data/bss/brk section (but not the kernel text!) |
399 |
+ * should also be not-executable. |
400 |
@@ -1156,12 +1188,54 @@ void mark_rodata_ro(void) |
401 |
set_memory_ro(start, (end-start) >> PAGE_SHIFT); |
402 |
#endif |
403 |
@@ -36588,7 +36732,7 @@ index 9c0ff04..9020d5f 100644 |
404 |
|
405 |
return (void *)vaddr; |
406 |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c |
407 |
-index 0d8d53d..5f7315c 100644 |
408 |
+index 0d8d53d..74815a4 100644 |
409 |
--- a/arch/x86/mm/ioremap.c |
410 |
+++ b/arch/x86/mm/ioremap.c |
411 |
@@ -59,8 +59,8 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, |
412 |
@@ -36602,6 +36746,15 @@ index 0d8d53d..5f7315c 100644 |
413 |
return 1; |
414 |
|
415 |
return 0; |
416 |
+@@ -81,7 +81,7 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, |
417 |
+ * caller shouldn't need to know that small detail. |
418 |
+ */ |
419 |
+ static void __iomem *__ioremap_caller(resource_size_t phys_addr, |
420 |
+- unsigned long size, enum page_cache_mode pcm, void *caller) |
421 |
++ resource_size_t size, enum page_cache_mode pcm, void *caller) |
422 |
+ { |
423 |
+ unsigned long offset, vaddr; |
424 |
+ resource_size_t pfn, last_pfn, last_addr; |
425 |
@@ -332,7 +332,7 @@ EXPORT_SYMBOL(ioremap_prot); |
426 |
* |
427 |
* Caller must ensure there is only one unmapping for the same pointer. |
428 |
@@ -36876,7 +37029,7 @@ index f70c1ff..fdb449c 100644 |
429 |
unsigned long uninitialized_var(pfn_align); |
430 |
int i, nid; |
431 |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c |
432 |
-index 01be9ec..f4643d7 100644 |
433 |
+index 01be9ec..2b8c8c7 100644 |
434 |
--- a/arch/x86/mm/pageattr.c |
435 |
+++ b/arch/x86/mm/pageattr.c |
436 |
@@ -258,7 +258,7 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, |
437 |
@@ -36888,7 +37041,7 @@ index 01be9ec..f4643d7 100644 |
438 |
#endif |
439 |
|
440 |
/* |
441 |
-@@ -266,8 +266,8 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, |
442 |
+@@ -266,14 +266,14 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, |
443 |
* Does not cover __inittext since that is gone later on. On |
444 |
* 64bit we do not enforce !NX on the low mapping |
445 |
*/ |
446 |
@@ -36899,6 +37052,13 @@ index 01be9ec..f4643d7 100644 |
447 |
|
448 |
/* |
449 |
* The .rodata section needs to be read-only. Using the pfn |
450 |
+ * catches all aliases. |
451 |
+ */ |
452 |
+- if (within(pfn, __pa_symbol(__start_rodata) >> PAGE_SHIFT, |
453 |
++ if (kernel_set_to_readonly && within(pfn, __pa_symbol(__start_rodata) >> PAGE_SHIFT, |
454 |
+ __pa_symbol(__end_rodata) >> PAGE_SHIFT)) |
455 |
+ pgprot_val(forbidden) |= _PAGE_RW; |
456 |
+ |
457 |
@@ -314,6 +314,13 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, |
458 |
} |
459 |
#endif |
460 |
@@ -48037,7 +48197,7 @@ index 93ad8a5..48f0a57 100644 |
461 |
-int sis_max_ioctl = ARRAY_SIZE(sis_ioctls); |
462 |
+const int sis_max_ioctl = ARRAY_SIZE(sis_ioctls); |
463 |
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c |
464 |
-index 3abb400..4fd8a65 100644 |
465 |
+index 3abb400..47ff1c9 100644 |
466 |
--- a/drivers/gpu/drm/sti/sti_cursor.c |
467 |
+++ b/drivers/gpu/drm/sti/sti_cursor.c |
468 |
@@ -131,7 +131,7 @@ static int cursor_dbg_show(struct seq_file *s, void *data) |
469 |
@@ -48045,7 +48205,7 @@ index 3abb400..4fd8a65 100644 |
470 |
} |
471 |
|
472 |
-static struct drm_info_list cursor_debugfs_files[] = { |
473 |
-+static struct drm_info_list cursor_debugfs_files[] __read_only = { |
474 |
++static drm_info_list_no_const cursor_debugfs_files[] __read_only = { |
475 |
{ "cursor", cursor_dbg_show, 0, NULL }, |
476 |
}; |
477 |
|
478 |
@@ -48055,14 +48215,13 @@ index 3abb400..4fd8a65 100644 |
479 |
|
480 |
+ pax_open_kernel(); |
481 |
for (i = 0; i < ARRAY_SIZE(cursor_debugfs_files); i++) |
482 |
-- cursor_debugfs_files[i].data = cursor; |
483 |
-+ const_cast(cursor_debugfs_files[i].data) = cursor; |
484 |
+ cursor_debugfs_files[i].data = cursor; |
485 |
+ pax_close_kernel(); |
486 |
|
487 |
return drm_debugfs_create_files(cursor_debugfs_files, |
488 |
ARRAY_SIZE(cursor_debugfs_files), |
489 |
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c |
490 |
-index 25f7663..7ea4bf9 100644 |
491 |
+index 25f7663..db8f927 100644 |
492 |
--- a/drivers/gpu/drm/sti/sti_dvo.c |
493 |
+++ b/drivers/gpu/drm/sti/sti_dvo.c |
494 |
@@ -197,7 +197,7 @@ static int dvo_dbg_show(struct seq_file *s, void *data) |
495 |
@@ -48080,16 +48239,42 @@ index 25f7663..7ea4bf9 100644 |
496 |
|
497 |
+ pax_open_kernel(); |
498 |
for (i = 0; i < ARRAY_SIZE(dvo_debugfs_files); i++) |
499 |
-- dvo_debugfs_files[i].data = dvo; |
500 |
-+ const_cast(dvo_debugfs_files[i].data) = dvo; |
501 |
+ dvo_debugfs_files[i].data = dvo; |
502 |
+ pax_close_kernel(); |
503 |
|
504 |
return drm_debugfs_create_files(dvo_debugfs_files, |
505 |
ARRAY_SIZE(dvo_debugfs_files), |
506 |
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c |
507 |
-index ff3d3e7..be8c837 100644 |
508 |
+index ff3d3e7..da4db0f 100644 |
509 |
--- a/drivers/gpu/drm/sti/sti_gdp.c |
510 |
+++ b/drivers/gpu/drm/sti/sti_gdp.c |
511 |
+@@ -297,22 +297,22 @@ static int gdp_node_dbg_show(struct seq_file *s, void *arg) |
512 |
+ return 0; |
513 |
+ } |
514 |
+ |
515 |
+-static struct drm_info_list gdp0_debugfs_files[] = { |
516 |
++static drm_info_list_no_const gdp0_debugfs_files[] __read_only = { |
517 |
+ { "gdp0", gdp_dbg_show, 0, NULL }, |
518 |
+ { "gdp0_node", gdp_node_dbg_show, 0, NULL }, |
519 |
+ }; |
520 |
+ |
521 |
+-static struct drm_info_list gdp1_debugfs_files[] = { |
522 |
++static drm_info_list_no_const gdp1_debugfs_files[] __read_only = { |
523 |
+ { "gdp1", gdp_dbg_show, 0, NULL }, |
524 |
+ { "gdp1_node", gdp_node_dbg_show, 0, NULL }, |
525 |
+ }; |
526 |
+ |
527 |
+-static struct drm_info_list gdp2_debugfs_files[] = { |
528 |
++static drm_info_list_no_const gdp2_debugfs_files[] __read_only = { |
529 |
+ { "gdp2", gdp_dbg_show, 0, NULL }, |
530 |
+ { "gdp2_node", gdp_node_dbg_show, 0, NULL }, |
531 |
+ }; |
532 |
+ |
533 |
+-static struct drm_info_list gdp3_debugfs_files[] = { |
534 |
++static drm_info_list_no_const gdp3_debugfs_files[] __read_only = { |
535 |
+ { "gdp3", gdp_dbg_show, 0, NULL }, |
536 |
+ { "gdp3_node", gdp_node_dbg_show, 0, NULL }, |
537 |
+ }; |
538 |
@@ -320,7 +320,7 @@ static struct drm_info_list gdp3_debugfs_files[] = { |
539 |
static int gdp_debugfs_init(struct sti_gdp *gdp, struct drm_minor *minor) |
540 |
{ |
541 |
@@ -48105,8 +48290,7 @@ index ff3d3e7..be8c837 100644 |
542 |
|
543 |
+ pax_open_kernel(); |
544 |
for (i = 0; i < nb_files; i++) |
545 |
-- gdp_debugfs_files[i].data = gdp; |
546 |
-+ const_cast(gdp_debugfs_files[i].data) = gdp; |
547 |
+ gdp_debugfs_files[i].data = gdp; |
548 |
+ pax_close_kernel(); |
549 |
|
550 |
return drm_debugfs_create_files(gdp_debugfs_files, |
551 |
@@ -48137,7 +48321,7 @@ index ec0d017..0fe03fd 100644 |
552 |
return drm_debugfs_create_files(hda_debugfs_files, |
553 |
ARRAY_SIZE(hda_debugfs_files), |
554 |
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c |
555 |
-index 6ef0715..b5a9e51 100644 |
556 |
+index 6ef0715..dbc27b0 100644 |
557 |
--- a/drivers/gpu/drm/sti/sti_hdmi.c |
558 |
+++ b/drivers/gpu/drm/sti/sti_hdmi.c |
559 |
@@ -694,7 +694,7 @@ static int hdmi_dbg_show(struct seq_file *s, void *data) |
560 |
@@ -48155,8 +48339,7 @@ index 6ef0715..b5a9e51 100644 |
561 |
|
562 |
+ pax_open_kernel(); |
563 |
for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_files); i++) |
564 |
-- hdmi_debugfs_files[i].data = hdmi; |
565 |
-+ const_cast(hdmi_debugfs_files[i].data) = hdmi; |
566 |
+ hdmi_debugfs_files[i].data = hdmi; |
567 |
+ pax_close_kernel(); |
568 |
|
569 |
return drm_debugfs_create_files(hdmi_debugfs_files, |
570 |
@@ -48187,10 +48370,23 @@ index e05b0dc..a40a642 100644 |
571 |
return drm_debugfs_create_files(hqvdp_debugfs_files, |
572 |
ARRAY_SIZE(hqvdp_debugfs_files), |
573 |
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c |
574 |
-index e7425c3..ce9dada 100644 |
575 |
+index e7425c3..d53380c 100644 |
576 |
--- a/drivers/gpu/drm/sti/sti_mixer.c |
577 |
+++ b/drivers/gpu/drm/sti/sti_mixer.c |
578 |
-@@ -190,7 +190,7 @@ static struct drm_info_list mixer1_debugfs_files[] = { |
579 |
+@@ -179,18 +179,18 @@ static int mixer_dbg_show(struct seq_file *s, void *arg) |
580 |
+ return 0; |
581 |
+ } |
582 |
+ |
583 |
+-static struct drm_info_list mixer0_debugfs_files[] = { |
584 |
++static drm_info_list_no_const mixer0_debugfs_files[] __read_only = { |
585 |
+ { "mixer_main", mixer_dbg_show, 0, NULL }, |
586 |
+ }; |
587 |
+ |
588 |
+-static struct drm_info_list mixer1_debugfs_files[] = { |
589 |
++static drm_info_list_no_const mixer1_debugfs_files[] __read_only = { |
590 |
+ { "mixer_aux", mixer_dbg_show, 0, NULL }, |
591 |
+ }; |
592 |
+ |
593 |
static int mixer_debugfs_init(struct sti_mixer *mixer, struct drm_minor *minor) |
594 |
{ |
595 |
unsigned int i; |
596 |
@@ -48205,8 +48401,7 @@ index e7425c3..ce9dada 100644 |
597 |
|
598 |
+ pax_open_kernel(); |
599 |
for (i = 0; i < nb_files; i++) |
600 |
-- mixer_debugfs_files[i].data = mixer; |
601 |
-+ const_cast(mixer_debugfs_files[i].data) = mixer; |
602 |
+ mixer_debugfs_files[i].data = mixer; |
603 |
+ pax_close_kernel(); |
604 |
|
605 |
return drm_debugfs_create_files(mixer_debugfs_files, |
606 |
@@ -48237,7 +48432,7 @@ index 2c99016..62597fd 100644 |
607 |
return drm_debugfs_create_files(tvout_debugfs_files, |
608 |
ARRAY_SIZE(tvout_debugfs_files), |
609 |
diff --git a/drivers/gpu/drm/sti/sti_vid.c b/drivers/gpu/drm/sti/sti_vid.c |
610 |
-index 5a2c5dc..315979b0 100644 |
611 |
+index 5a2c5dc..c4f2be6 100644 |
612 |
--- a/drivers/gpu/drm/sti/sti_vid.c |
613 |
+++ b/drivers/gpu/drm/sti/sti_vid.c |
614 |
@@ -125,7 +125,7 @@ static int vid_dbg_show(struct seq_file *s, void *arg) |
615 |
@@ -48255,8 +48450,7 @@ index 5a2c5dc..315979b0 100644 |
616 |
|
617 |
+ pax_open_kernel(); |
618 |
for (i = 0; i < ARRAY_SIZE(vid_debugfs_files); i++) |
619 |
-- vid_debugfs_files[i].data = vid; |
620 |
-+ const_cast(vid_debugfs_files[i].data) = vid; |
621 |
+ vid_debugfs_files[i].data = vid; |
622 |
+ pax_close_kernel(); |
623 |
|
624 |
return drm_debugfs_create_files(vid_debugfs_files, |
625 |
@@ -51999,7 +52193,7 @@ index 6b304eb..6e3a1413 100644 |
626 |
* Theoretically we do not have to handle this IRQ, |
627 |
* but in Linux this does not cause problems and is |
628 |
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c |
629 |
-index 013fc96..756ae4a 100644 |
630 |
+index 013fc96..36a9a97 100644 |
631 |
--- a/drivers/irqchip/irq-mmp.c |
632 |
+++ b/drivers/irqchip/irq-mmp.c |
633 |
@@ -122,7 +122,7 @@ static void icu_unmask_irq(struct irq_data *d) |
634 |
@@ -52007,7 +52201,7 @@ index 013fc96..756ae4a 100644 |
635 |
} |
636 |
|
637 |
-struct irq_chip icu_irq_chip = { |
638 |
-+struct irq_chip icu_irq_chip __read_only = { |
639 |
++irq_chip_no_const icu_irq_chip __read_only = { |
640 |
.name = "icu_irq", |
641 |
.irq_mask = icu_mask_irq, |
642 |
.irq_mask_ack = icu_mask_ack_irq, |
643 |
@@ -60975,6 +61169,19 @@ index 4048fc5..333809f 100644 |
644 |
|
645 |
/** |
646 |
* bnx2x_config_rx_mode - Send and RX_MODE ramrod according to the provided parameters. |
647 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
648 |
+index c39a7f5..f145270 100644 |
649 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
650 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
651 |
+@@ -6149,7 +6149,7 @@ init_err_free: |
652 |
+ * this device has been detected. |
653 |
+ */ |
654 |
+ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev, |
655 |
+- pci_channel_state_t state) |
656 |
++ enum pci_channel_state state) |
657 |
+ { |
658 |
+ struct net_device *netdev = pci_get_drvdata(pdev); |
659 |
+ |
660 |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c |
661 |
index 3010080..49824f1 100644 |
662 |
--- a/drivers/net/ethernet/broadcom/tg3.c |
663 |
@@ -112642,10 +112849,48 @@ index cc514da..2895466 100644 |
664 |
if (res < 0) { |
665 |
free_page((unsigned long) buf); |
666 |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c |
667 |
-index a4ff5d0..6034cb5 100644 |
668 |
+index a4ff5d0..43d5748 100644 |
669 |
--- a/fs/overlayfs/inode.c |
670 |
+++ b/fs/overlayfs/inode.c |
671 |
-@@ -347,6 +347,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) |
672 |
+@@ -59,16 +59,37 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) |
673 |
+ if (err) |
674 |
+ goto out; |
675 |
+ |
676 |
++ if (attr->ia_valid & ATTR_SIZE) { |
677 |
++ struct inode *realinode = d_inode(ovl_dentry_real(dentry)); |
678 |
++ |
679 |
++ err = -ETXTBSY; |
680 |
++ if (atomic_read(&realinode->i_writecount) < 0) |
681 |
++ goto out_drop_write; |
682 |
++ } |
683 |
++ |
684 |
+ err = ovl_copy_up(dentry); |
685 |
+ if (!err) { |
686 |
++ struct inode *winode = NULL; |
687 |
++ |
688 |
+ upperdentry = ovl_dentry_upper(dentry); |
689 |
+ |
690 |
++ if (attr->ia_valid & ATTR_SIZE) { |
691 |
++ winode = d_inode(upperdentry); |
692 |
++ err = get_write_access(winode); |
693 |
++ if (err) |
694 |
++ goto out_drop_write; |
695 |
++ } |
696 |
++ |
697 |
+ inode_lock(upperdentry->d_inode); |
698 |
+ err = notify_change(upperdentry, attr, NULL); |
699 |
+ if (!err) |
700 |
+ ovl_copyattr(upperdentry->d_inode, dentry->d_inode); |
701 |
+ inode_unlock(upperdentry->d_inode); |
702 |
++ |
703 |
++ if (winode) |
704 |
++ put_write_access(winode); |
705 |
+ } |
706 |
++out_drop_write: |
707 |
+ ovl_drop_write(dentry); |
708 |
+ out: |
709 |
+ return err; |
710 |
+@@ -347,6 +368,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) |
711 |
if (d_is_dir(dentry)) |
712 |
return d_backing_inode(dentry); |
713 |
|
714 |
@@ -112656,7 +112901,7 @@ index a4ff5d0..6034cb5 100644 |
715 |
if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { |
716 |
err = ovl_want_write(dentry); |
717 |
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c |
718 |
-index 791235e..46ecd93 100644 |
719 |
+index 791235e..f6aecf4 100644 |
720 |
--- a/fs/overlayfs/super.c |
721 |
+++ b/fs/overlayfs/super.c |
722 |
@@ -194,7 +194,7 @@ void ovl_path_lower(struct dentry *dentry, struct path *path) |
723 |
@@ -112679,6 +112924,25 @@ index 791235e..46ecd93 100644 |
724 |
struct dentry *root_dentry; |
725 |
struct ovl_entry *oe; |
726 |
struct ovl_fs *ufs; |
727 |
+@@ -1070,11 +1070,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) |
728 |
+ if (err < 0) |
729 |
+ goto out_put_workdir; |
730 |
+ |
731 |
+- if (!err) { |
732 |
+- pr_err("overlayfs: upper fs needs to support d_type.\n"); |
733 |
+- err = -EINVAL; |
734 |
+- goto out_put_workdir; |
735 |
+- } |
736 |
++ /* |
737 |
++ * We allowed this configuration and don't want to |
738 |
++ * break users over kernel upgrade. So warn instead |
739 |
++ * of erroring out. |
740 |
++ */ |
741 |
++ if (!err) |
742 |
++ pr_warn("overlayfs: upper fs needs to support d_type.\n"); |
743 |
+ } |
744 |
+ |
745 |
+ err = -ENOMEM; |
746 |
diff --git a/fs/pipe.c b/fs/pipe.c |
747 |
index 0d3f516..91735ad 100644 |
748 |
--- a/fs/pipe.c |
749 |
@@ -120479,10 +120743,10 @@ index 0000000..9adc75c |
750 |
+} |
751 |
diff --git a/grsecurity/gracl_cap.c b/grsecurity/gracl_cap.c |
752 |
new file mode 100644 |
753 |
-index 0000000..1a94c11 |
754 |
+index 0000000..8747091 |
755 |
--- /dev/null |
756 |
+++ b/grsecurity/gracl_cap.c |
757 |
-@@ -0,0 +1,127 @@ |
758 |
+@@ -0,0 +1,96 @@ |
759 |
+#include <linux/kernel.h> |
760 |
+#include <linux/module.h> |
761 |
+#include <linux/sched.h> |
762 |
@@ -120493,7 +120757,7 @@ index 0000000..1a94c11 |
763 |
+extern const char *captab_log[]; |
764 |
+extern int captab_log_entries; |
765 |
+ |
766 |
-+int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap) |
767 |
++int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap, bool log) |
768 |
+{ |
769 |
+ struct acl_subject_label *curracl; |
770 |
+ |
771 |
@@ -120503,7 +120767,8 @@ index 0000000..1a94c11 |
772 |
+ curracl = task->acl; |
773 |
+ |
774 |
+ if (curracl->mode & (GR_LEARN | GR_INHERITLEARN)) { |
775 |
-+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, |
776 |
++ if (log) |
777 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, |
778 |
+ task->role->roletype, GR_GLOBAL_UID(cred->uid), |
779 |
+ GR_GLOBAL_GID(cred->gid), task->exec_file ? |
780 |
+ gr_to_filename(task->exec_file->f_path.dentry, |
781 |
@@ -120516,7 +120781,7 @@ index 0000000..1a94c11 |
782 |
+ return 0; |
783 |
+} |
784 |
+ |
785 |
-+int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap) |
786 |
++int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap, bool log) |
787 |
+{ |
788 |
+ struct acl_subject_label *curracl; |
789 |
+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set; |
790 |
@@ -120547,7 +120812,7 @@ index 0000000..1a94c11 |
791 |
+ } |
792 |
+ |
793 |
+ if (!cap_raised(cap_drop, cap)) { |
794 |
-+ if (cap_raised(cap_audit, cap)) |
795 |
++ if (log && cap_raised(cap_audit, cap)) |
796 |
+ gr_log_cap(GR_DO_AUDIT, GR_CAP_ACL_MSG2, task, captab_log[cap]); |
797 |
+ return 1; |
798 |
+ } |
799 |
@@ -120557,10 +120822,10 @@ index 0000000..1a94c11 |
800 |
+ to this rule to ensure any role transition involves what the full-learned |
801 |
+ policy believes in a privileged process |
802 |
+ */ |
803 |
-+ if (cap_raised(cred->cap_effective, cap) && gr_learn_cap(task, cred, cap)) |
804 |
++ if (cap_raised(cred->cap_effective, cap) && gr_learn_cap(task, cred, cap, log)) |
805 |
+ return 1; |
806 |
+ |
807 |
-+ if ((cap >= 0) && (cap < captab_log_entries) && cap_raised(cred->cap_effective, cap) && !cap_raised(cap_audit, cap)) |
808 |
++ if (log && (cap >= 0) && (cap < captab_log_entries) && cap_raised(cred->cap_effective, cap) && !cap_raised(cap_audit, cap)) |
809 |
+ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]); |
810 |
+ |
811 |
+ return 0; |
812 |
@@ -120569,45 +120834,13 @@ index 0000000..1a94c11 |
813 |
+int |
814 |
+gr_acl_is_capable(const int cap) |
815 |
+{ |
816 |
-+ return gr_task_acl_is_capable(current, current_cred(), cap); |
817 |
-+} |
818 |
-+ |
819 |
-+int gr_task_acl_is_capable_nolog(const struct task_struct *task, const int cap) |
820 |
-+{ |
821 |
-+ struct acl_subject_label *curracl; |
822 |
-+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set; |
823 |
-+ |
824 |
-+ if (!gr_acl_is_enabled()) |
825 |
-+ return 1; |
826 |
-+ |
827 |
-+ curracl = task->acl; |
828 |
-+ |
829 |
-+ cap_drop = curracl->cap_lower; |
830 |
-+ cap_mask = curracl->cap_mask; |
831 |
-+ |
832 |
-+ while ((curracl = curracl->parent_subject)) { |
833 |
-+ /* if the cap isn't specified in the current computed mask but is specified in the |
834 |
-+ current level subject, and is lowered in the current level subject, then add |
835 |
-+ it to the set of dropped capabilities |
836 |
-+ otherwise, add the current level subject's mask to the current computed mask |
837 |
-+ */ |
838 |
-+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) { |
839 |
-+ cap_raise(cap_mask, cap); |
840 |
-+ if (cap_raised(curracl->cap_lower, cap)) |
841 |
-+ cap_raise(cap_drop, cap); |
842 |
-+ } |
843 |
-+ } |
844 |
-+ |
845 |
-+ if (!cap_raised(cap_drop, cap)) |
846 |
-+ return 1; |
847 |
-+ |
848 |
-+ return 0; |
849 |
++ return gr_task_acl_is_capable(current, current_cred(), cap, true); |
850 |
+} |
851 |
+ |
852 |
+int |
853 |
+gr_acl_is_capable_nolog(const int cap) |
854 |
+{ |
855 |
-+ return gr_task_acl_is_capable_nolog(current, cap); |
856 |
++ return gr_task_acl_is_capable(current, current_cred(), cap, false); |
857 |
+} |
858 |
+ |
859 |
diff --git a/grsecurity/gracl_compat.c b/grsecurity/gracl_compat.c |
860 |
@@ -124706,7 +124939,7 @@ index 0000000..1964ab1c |
861 |
+} |
862 |
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c |
863 |
new file mode 100644 |
864 |
-index 0000000..0589fe2 |
865 |
+index 0000000..ba8d997 |
866 |
--- /dev/null |
867 |
+++ b/grsecurity/grsec_disabled.c |
868 |
@@ -0,0 +1,445 @@ |
869 |
@@ -124752,7 +124985,7 @@ index 0000000..0589fe2 |
870 |
+} |
871 |
+ |
872 |
+int |
873 |
-+gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap) |
874 |
++gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap, bool log) |
875 |
+{ |
876 |
+ return 0; |
877 |
+} |
878 |
@@ -125157,10 +125390,10 @@ index 0000000..0589fe2 |
879 |
+#endif |
880 |
diff --git a/grsecurity/grsec_exec.c b/grsecurity/grsec_exec.c |
881 |
new file mode 100644 |
882 |
-index 0000000..fb7531e |
883 |
+index 0000000..808006e |
884 |
--- /dev/null |
885 |
+++ b/grsecurity/grsec_exec.c |
886 |
-@@ -0,0 +1,189 @@ |
887 |
+@@ -0,0 +1,188 @@ |
888 |
+#include <linux/kernel.h> |
889 |
+#include <linux/sched.h> |
890 |
+#include <linux/file.h> |
891 |
@@ -125251,8 +125484,7 @@ index 0000000..fb7531e |
892 |
+#ifdef CONFIG_GRKERNSEC |
893 |
+extern int gr_acl_is_capable(const int cap); |
894 |
+extern int gr_acl_is_capable_nolog(const int cap); |
895 |
-+extern int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap); |
896 |
-+extern int gr_task_acl_is_capable_nolog(const struct task_struct *task, const int cap); |
897 |
++extern int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap, bool log); |
898 |
+extern int gr_chroot_is_capable(const int cap); |
899 |
+extern int gr_chroot_is_capable_nolog(const int cap); |
900 |
+extern int gr_task_chroot_is_capable(const struct task_struct *task, const struct cred *cred, const int cap); |
901 |
@@ -125316,7 +125548,7 @@ index 0000000..fb7531e |
902 |
+int gr_task_is_capable(const struct task_struct *task, const struct cred *cred, const int cap) |
903 |
+{ |
904 |
+#ifdef CONFIG_GRKERNSEC |
905 |
-+ if (gr_task_acl_is_capable(task, cred, cap) && gr_task_chroot_is_capable(task, cred, cap)) |
906 |
++ if (gr_task_acl_is_capable(task, cred, cap, true) && gr_task_chroot_is_capable(task, cred, cap)) |
907 |
+ return 1; |
908 |
+ return 0; |
909 |
+#else |
910 |
@@ -125335,10 +125567,10 @@ index 0000000..fb7531e |
911 |
+#endif |
912 |
+} |
913 |
+ |
914 |
-+int gr_task_is_capable_nolog(const struct task_struct *task, const int cap) |
915 |
++int gr_task_is_capable_nolog(const struct task_struct *task, const struct cred *cred, const int cap) |
916 |
+{ |
917 |
+#ifdef CONFIG_GRKERNSEC |
918 |
-+ if (gr_task_acl_is_capable_nolog(task, cap) && gr_task_chroot_is_capable_nolog(task, cap)) |
919 |
++ if (gr_task_acl_is_capable(task, cred, cap, false) && gr_task_chroot_is_capable_nolog(task, cap)) |
920 |
+ return 1; |
921 |
+ return 0; |
922 |
+#else |
923 |
@@ -131130,7 +131362,7 @@ index 0000000..94ac4d2 |
924 |
+#define GR_MSRWRITE_MSG "denied write to CPU MSR by " |
925 |
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h |
926 |
new file mode 100644 |
927 |
-index 0000000..4d5dae0 |
928 |
+index 0000000..749b915 |
929 |
--- /dev/null |
930 |
+++ b/include/linux/grsecurity.h |
931 |
@@ -0,0 +1,259 @@ |
932 |
@@ -131180,7 +131412,7 @@ index 0000000..4d5dae0 |
933 |
+int gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs); |
934 |
+int gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs); |
935 |
+ |
936 |
-+int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap); |
937 |
++int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap, bool log); |
938 |
+ |
939 |
+void gr_del_task_from_ip_table(struct task_struct *p); |
940 |
+ |
941 |
@@ -131247,7 +131479,7 @@ index 0000000..4d5dae0 |
942 |
+int gr_is_capable(const int cap); |
943 |
+int gr_is_capable_nolog(const int cap); |
944 |
+int gr_task_is_capable(const struct task_struct *task, const struct cred *cred, const int cap); |
945 |
-+int gr_task_is_capable_nolog(const struct task_struct *task, const int cap); |
946 |
++int gr_task_is_capable_nolog(const struct task_struct *task, const struct cred *cred, const int cap); |
947 |
+ |
948 |
+void gr_copy_label(struct task_struct *tsk); |
949 |
+void gr_handle_crash(struct task_struct *task, const int sig); |
950 |
@@ -131686,6 +131918,18 @@ index c4de623..8f0044f 100644 |
951 |
|
952 |
/* |
953 |
* irq_chip specific flags |
954 |
+diff --git a/include/linux/irqchip/mmp.h b/include/linux/irqchip/mmp.h |
955 |
+index c78a892..124e0b7 100644 |
956 |
+--- a/include/linux/irqchip/mmp.h |
957 |
++++ b/include/linux/irqchip/mmp.h |
958 |
+@@ -1,6 +1,6 @@ |
959 |
+ #ifndef __IRQCHIP_MMP_H |
960 |
+ #define __IRQCHIP_MMP_H |
961 |
+ |
962 |
+-extern struct irq_chip icu_irq_chip; |
963 |
++extern irq_chip_no_const icu_irq_chip; |
964 |
+ |
965 |
+ #endif /* __IRQCHIP_MMP_H */ |
966 |
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h |
967 |
index dcca77c..8503b4f 100644 |
968 |
--- a/include/linux/irqdesc.h |
969 |
@@ -137723,7 +137967,7 @@ index 30f5362..8ed8ac9 100644 |
970 |
void *pmi_pal; |
971 |
u8 *vbe_state_orig; /* |
972 |
diff --git a/init/Kconfig b/init/Kconfig |
973 |
-index 0dfd09d..c18a0e0 100644 |
974 |
+index 0dfd09d..177e567 100644 |
975 |
--- a/init/Kconfig |
976 |
+++ b/init/Kconfig |
977 |
@@ -286,7 +286,8 @@ config FHANDLE |
978 |
@@ -137752,7 +137996,15 @@ index 0dfd09d..c18a0e0 100644 |
979 |
default n |
980 |
help |
981 |
Enables additional kernel features in a sake of checkpoint/restore. |
982 |
-@@ -1699,7 +1702,7 @@ config SLUB_DEBUG |
983 |
+@@ -1423,6 +1426,7 @@ config KALLSYMS_ALL |
984 |
+ |
985 |
+ config KALLSYMS_ABSOLUTE_PERCPU |
986 |
+ bool |
987 |
++ depends on KALLSYMS |
988 |
+ default X86_64 && SMP |
989 |
+ |
990 |
+ config KALLSYMS_BASE_RELATIVE |
991 |
+@@ -1699,7 +1703,7 @@ config SLUB_DEBUG |
992 |
|
993 |
config COMPAT_BRK |
994 |
bool "Disable heap randomization" |
995 |
@@ -138734,7 +138986,7 @@ index cf5e9f7..81ece72 100644 |
996 |
if (!access_ok(VERIFY_READ, uattr, 1)) |
997 |
return -EFAULT; |
998 |
diff --git a/kernel/capability.c b/kernel/capability.c |
999 |
-index 45432b5..988f1e4 100644 |
1000 |
+index 45432b5..7d860f7 100644 |
1001 |
--- a/kernel/capability.c |
1002 |
+++ b/kernel/capability.c |
1003 |
@@ -193,6 +193,9 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) |
1004 |
@@ -138766,7 +139018,7 @@ index 45432b5..988f1e4 100644 |
1005 |
|
1006 |
rcu_read_lock(); |
1007 |
- ret = security_capable_noaudit(__task_cred(t), ns, cap); |
1008 |
-+ ret = security_capable_noaudit(__task_cred(t), ns, cap) == 0 && gr_task_is_capable_nolog(t, cap); |
1009 |
++ ret = security_capable_noaudit(__task_cred(t), ns, cap) == 0 && gr_task_is_capable_nolog(t, __task_cred(t), cap); |
1010 |
rcu_read_unlock(); |
1011 |
|
1012 |
- return (ret == 0); |
1013 |
@@ -143691,7 +143943,7 @@ index a467e6c..7743481 100644 |
1014 |
.thread_should_run = cpu_stop_should_run, |
1015 |
.thread_fn = cpu_stopper_thread, |
1016 |
diff --git a/kernel/sys.c b/kernel/sys.c |
1017 |
-index cf8ba54..314fca6 100644 |
1018 |
+index cf8ba54..196a680 100644 |
1019 |
--- a/kernel/sys.c |
1020 |
+++ b/kernel/sys.c |
1021 |
@@ -160,6 +160,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) |
1022 |
@@ -143722,7 +143974,7 @@ index cf8ba54..314fca6 100644 |
1023 |
+ we may not log a CAP_SETGID check above, e.g. |
1024 |
+ in the case where new rgid = old egid |
1025 |
+ */ |
1026 |
-+ gr_learn_cap(current, new, CAP_SETGID); |
1027 |
++ gr_learn_cap(current, new, CAP_SETGID, true); |
1028 |
+ } |
1029 |
+ |
1030 |
if (rgid != (gid_t) -1 || |
1031 |
@@ -143763,7 +144015,7 @@ index cf8ba54..314fca6 100644 |
1032 |
+ we may not log a CAP_SETUID check above, e.g. |
1033 |
+ in the case where new ruid = old euid |
1034 |
+ */ |
1035 |
-+ gr_learn_cap(current, new, CAP_SETUID); |
1036 |
++ gr_learn_cap(current, new, CAP_SETUID, true); |
1037 |
retval = set_user(new); |
1038 |
if (retval < 0) |
1039 |
goto error; |
1040 |
@@ -156056,6 +156308,19 @@ index e9853df..4b57916 100644 |
1041 |
} |
1042 |
|
1043 |
int udp4_seq_show(struct seq_file *seq, void *v) |
1044 |
+diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c |
1045 |
+index 71acd00..d2c74ee 100644 |
1046 |
+--- a/net/ipv4/xfrm4_mode_beet.c |
1047 |
++++ b/net/ipv4/xfrm4_mode_beet.c |
1048 |
+@@ -36,7 +36,7 @@ static void xfrm4_beet_make_header(struct sk_buff *skb) |
1049 |
+ * |
1050 |
+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt. |
1051 |
+ */ |
1052 |
+-static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
1053 |
++static int __intentional_overflow(0) xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
1054 |
+ { |
1055 |
+ struct ip_beet_phdr *ph; |
1056 |
+ struct iphdr *top_iph; |
1057 |
diff --git a/net/ipv4/xfrm4_mode_transport.c b/net/ipv4/xfrm4_mode_transport.c |
1058 |
index fd840c7..b517627 100644 |
1059 |
--- a/net/ipv4/xfrm4_mode_transport.c |
1060 |
@@ -156970,6 +157235,19 @@ index f96831d9..dae9a77 100644 |
1061 |
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); |
1062 |
|
1063 |
kfree_skb(skb); |
1064 |
+diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c |
1065 |
+index 1e205c3..d71b846 100644 |
1066 |
+--- a/net/ipv6/xfrm6_mode_beet.c |
1067 |
++++ b/net/ipv6/xfrm6_mode_beet.c |
1068 |
+@@ -37,7 +37,7 @@ static void xfrm6_beet_make_header(struct sk_buff *skb) |
1069 |
+ * |
1070 |
+ * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt. |
1071 |
+ */ |
1072 |
+-static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
1073 |
++static int __intentional_overflow(0) xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
1074 |
+ { |
1075 |
+ struct ipv6hdr *top_iph; |
1076 |
+ struct ip_beet_phdr *ph; |
1077 |
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c |
1078 |
index 4e34410..232827a 100644 |
1079 |
--- a/net/ipv6/xfrm6_mode_transport.c |