1 |
commit: 137d5284fb9ae3dfe988065ede8881bbf11876f7 |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Jul 2 13:22:47 2013 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Jul 2 13:22:47 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=137d5284 |
7 |
|
8 |
Grsec/PaX: 2.9.1-{2.6.32.61,3.2.47,3.9.8}-201306302052 |
9 |
|
10 |
--- |
11 |
2.6.32/0000_README | 2 +- |
12 |
..._grsecurity-2.9.1-2.6.32.61-201306302051.patch} | 125 +++++++-- |
13 |
3.2.47/0000_README | 2 +- |
14 |
...420_grsecurity-2.9.1-3.2.48-201306302051.patch} | 292 +++++++++++---------- |
15 |
3.9.8/0000_README | 2 +- |
16 |
...4420_grsecurity-2.9.1-3.9.8-201306302052.patch} | 115 +++++++- |
17 |
6 files changed, 367 insertions(+), 171 deletions(-) |
18 |
|
19 |
diff --git a/2.6.32/0000_README b/2.6.32/0000_README |
20 |
index 133e8f6..7480e7a 100644 |
21 |
--- a/2.6.32/0000_README |
22 |
+++ b/2.6.32/0000_README |
23 |
@@ -38,7 +38,7 @@ Patch: 1060_linux-2.6.32.61.patch |
24 |
From: http://www.kernel.org |
25 |
Desc: Linux 2.6.32.61 |
26 |
|
27 |
-Patch: 4420_grsecurity-2.9.1-2.6.32.61-201306272055.patch |
28 |
+Patch: 4420_grsecurity-2.9.1-2.6.32.61-201306302051.patch |
29 |
From: http://www.grsecurity.net |
30 |
Desc: hardened-sources base patch from upstream grsecurity |
31 |
|
32 |
|
33 |
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201306272055.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201306302051.patch |
34 |
similarity index 99% |
35 |
rename from 2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201306272055.patch |
36 |
rename to 2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201306302051.patch |
37 |
index c67f417..d3ad7ec 100644 |
38 |
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201306272055.patch |
39 |
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201306302051.patch |
40 |
@@ -78102,7 +78102,7 @@ index 83fbd64..8353dce 100644 |
41 |
|
42 |
out_free_fd: |
43 |
diff --git a/fs/exec.c b/fs/exec.c |
44 |
-index feb2435..4f60348 100644 |
45 |
+index feb2435..04123c5 100644 |
46 |
--- a/fs/exec.c |
47 |
+++ b/fs/exec.c |
48 |
@@ -56,12 +56,34 @@ |
49 |
@@ -78411,7 +78411,21 @@ index feb2435..4f60348 100644 |
50 |
|
51 |
/* Set the new mm task size. We have to do that late because it may |
52 |
* depend on TIF_32BIT which is only updated in flush_thread() on |
53 |
-@@ -1090,14 +1165,14 @@ EXPORT_SYMBOL(setup_new_exec); |
54 |
+@@ -1065,13 +1140,6 @@ void setup_new_exec(struct linux_binprm * bprm) |
55 |
+ set_dumpable(current->mm, suid_dumpable); |
56 |
+ } |
57 |
+ |
58 |
+- /* |
59 |
+- * Flush performance counters when crossing a |
60 |
+- * security domain: |
61 |
+- */ |
62 |
+- if (!get_dumpable(current->mm)) |
63 |
+- perf_event_exit_task(current); |
64 |
+- |
65 |
+ /* An exec changes our domain. We are no longer part of the thread |
66 |
+ group */ |
67 |
+ |
68 |
+@@ -1090,14 +1158,14 @@ EXPORT_SYMBOL(setup_new_exec); |
69 |
*/ |
70 |
int prepare_bprm_creds(struct linux_binprm *bprm) |
71 |
{ |
72 |
@@ -78428,7 +78442,7 @@ index feb2435..4f60348 100644 |
73 |
return -ENOMEM; |
74 |
} |
75 |
|
76 |
-@@ -1105,7 +1180,7 @@ void free_bprm(struct linux_binprm *bprm) |
77 |
+@@ -1105,7 +1173,7 @@ void free_bprm(struct linux_binprm *bprm) |
78 |
{ |
79 |
free_arg_pages(bprm); |
80 |
if (bprm->cred) { |
81 |
@@ -78437,7 +78451,22 @@ index feb2435..4f60348 100644 |
82 |
abort_creds(bprm->cred); |
83 |
} |
84 |
/* If a binfmt changed the interp, free it. */ |
85 |
-@@ -1141,13 +1216,13 @@ void install_exec_creds(struct linux_binprm *bprm) |
86 |
+@@ -1135,19 +1203,28 @@ void install_exec_creds(struct linux_binprm *bprm) |
87 |
+ |
88 |
+ commit_creds(bprm->cred); |
89 |
+ bprm->cred = NULL; |
90 |
++ |
91 |
++ /* |
92 |
++ * Disable monitoring for regular users |
93 |
++ * when executing setuid binaries. Must |
94 |
++ * wait until new credentials are committed |
95 |
++ * by commit_creds() above |
96 |
++ */ |
97 |
++ if (get_dumpable(current->mm) != SUID_DUMP_USER) |
98 |
++ perf_event_exit_task(current); |
99 |
+ /* |
100 |
+ * cred_guard_mutex must be held at least to this point to prevent |
101 |
+ * ptrace_attach() from altering our determination of the task's |
102 |
* credentials; any time after this it may be unlocked. |
103 |
*/ |
104 |
security_bprm_committed_creds(bprm); |
105 |
@@ -78453,7 +78482,7 @@ index feb2435..4f60348 100644 |
106 |
* PTRACE_ATTACH |
107 |
*/ |
108 |
int check_unsafe_exec(struct linux_binprm *bprm) |
109 |
-@@ -1167,7 +1242,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
110 |
+@@ -1167,7 +1244,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
111 |
} |
112 |
rcu_read_unlock(); |
113 |
|
114 |
@@ -78462,7 +78491,7 @@ index feb2435..4f60348 100644 |
115 |
bprm->unsafe |= LSM_UNSAFE_SHARE; |
116 |
} else { |
117 |
res = -EAGAIN; |
118 |
-@@ -1354,6 +1429,21 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) |
119 |
+@@ -1354,6 +1431,21 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) |
120 |
|
121 |
EXPORT_SYMBOL(search_binary_handler); |
122 |
|
123 |
@@ -78484,7 +78513,7 @@ index feb2435..4f60348 100644 |
124 |
/* |
125 |
* sys_execve() executes a new program. |
126 |
*/ |
127 |
-@@ -1362,11 +1452,35 @@ int do_execve(char * filename, |
128 |
+@@ -1362,11 +1454,35 @@ int do_execve(char * filename, |
129 |
char __user *__user *envp, |
130 |
struct pt_regs * regs) |
131 |
{ |
132 |
@@ -78520,7 +78549,7 @@ index feb2435..4f60348 100644 |
133 |
|
134 |
retval = unshare_files(&displaced); |
135 |
if (retval) |
136 |
-@@ -1392,12 +1506,27 @@ int do_execve(char * filename, |
137 |
+@@ -1392,12 +1508,27 @@ int do_execve(char * filename, |
138 |
if (IS_ERR(file)) |
139 |
goto out_unmark; |
140 |
|
141 |
@@ -78548,7 +78577,7 @@ index feb2435..4f60348 100644 |
142 |
retval = bprm_mm_init(bprm); |
143 |
if (retval) |
144 |
goto out_file; |
145 |
-@@ -1414,25 +1543,66 @@ int do_execve(char * filename, |
146 |
+@@ -1414,25 +1545,66 @@ int do_execve(char * filename, |
147 |
if (retval < 0) |
148 |
goto out; |
149 |
|
150 |
@@ -78619,7 +78648,7 @@ index feb2435..4f60348 100644 |
151 |
current->fs->in_exec = 0; |
152 |
current->in_execve = 0; |
153 |
acct_update_integrals(current); |
154 |
-@@ -1441,6 +1611,14 @@ int do_execve(char * filename, |
155 |
+@@ -1441,6 +1613,14 @@ int do_execve(char * filename, |
156 |
put_files_struct(displaced); |
157 |
return retval; |
158 |
|
159 |
@@ -78634,7 +78663,7 @@ index feb2435..4f60348 100644 |
160 |
out: |
161 |
if (bprm->mm) { |
162 |
acct_arg_size(bprm, 0); |
163 |
-@@ -1606,6 +1784,251 @@ out: |
164 |
+@@ -1606,6 +1786,251 @@ out: |
165 |
return ispipe; |
166 |
} |
167 |
|
168 |
@@ -78886,7 +78915,7 @@ index feb2435..4f60348 100644 |
169 |
static int zap_process(struct task_struct *start) |
170 |
{ |
171 |
struct task_struct *t; |
172 |
-@@ -1808,17 +2231,17 @@ static void wait_for_dump_helpers(struct file *file) |
173 |
+@@ -1808,17 +2233,17 @@ static void wait_for_dump_helpers(struct file *file) |
174 |
pipe = file->f_path.dentry->d_inode->i_pipe; |
175 |
|
176 |
pipe_lock(pipe); |
177 |
@@ -78909,7 +78938,7 @@ index feb2435..4f60348 100644 |
178 |
pipe_unlock(pipe); |
179 |
|
180 |
} |
181 |
-@@ -1841,10 +2264,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
182 |
+@@ -1841,10 +2266,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
183 |
char **helper_argv = NULL; |
184 |
int helper_argc = 0; |
185 |
int dump_count = 0; |
186 |
@@ -78924,7 +78953,7 @@ index feb2435..4f60348 100644 |
187 |
binfmt = mm->binfmt; |
188 |
if (!binfmt || !binfmt->core_dump) |
189 |
goto fail; |
190 |
-@@ -1889,6 +2315,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
191 |
+@@ -1889,6 +2317,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
192 |
*/ |
193 |
clear_thread_flag(TIF_SIGPENDING); |
194 |
|
195 |
@@ -78933,7 +78962,7 @@ index feb2435..4f60348 100644 |
196 |
/* |
197 |
* lock_kernel() because format_corename() is controlled by sysctl, which |
198 |
* uses lock_kernel() |
199 |
-@@ -1923,7 +2351,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
200 |
+@@ -1923,7 +2353,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
201 |
goto fail_unlock; |
202 |
} |
203 |
|
204 |
@@ -78942,7 +78971,7 @@ index feb2435..4f60348 100644 |
205 |
if (core_pipe_limit && (core_pipe_limit < dump_count)) { |
206 |
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", |
207 |
task_tgid_vnr(current), current->comm); |
208 |
-@@ -1987,7 +2415,7 @@ close_fail: |
209 |
+@@ -1987,7 +2417,7 @@ close_fail: |
210 |
filp_close(file, NULL); |
211 |
fail_dropcount: |
212 |
if (dump_count) |
213 |
@@ -85081,6 +85110,70 @@ index c5081ad..342ea86 100644 |
214 |
if (!IS_ERR(page)) |
215 |
free_page((unsigned long)page); |
216 |
} |
217 |
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c |
218 |
+index 552fb01..2cff69a 100644 |
219 |
+--- a/fs/ubifs/dir.c |
220 |
++++ b/fs/ubifs/dir.c |
221 |
+@@ -377,6 +377,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
222 |
+ */ |
223 |
+ return 0; |
224 |
+ |
225 |
++ if (file->f_version == 0) { |
226 |
++ /* |
227 |
++ * The file was seek'ed, which means that @file->private_data |
228 |
++ * is now invalid. This may also be just the first |
229 |
++ * 'ubifs_readdir()' invocation, in which case |
230 |
++ * @file->private_data is NULL, and the below code is |
231 |
++ * basically a no-op. |
232 |
++ */ |
233 |
++ kfree(file->private_data); |
234 |
++ file->private_data = NULL; |
235 |
++ } |
236 |
++ |
237 |
++ /* |
238 |
++ * 'generic_file_llseek()' unconditionally sets @file->f_version to |
239 |
++ * zero, and we use this for detecting whether the file was seek'ed. |
240 |
++ */ |
241 |
++ file->f_version = 1; |
242 |
++ |
243 |
+ /* File positions 0 and 1 correspond to "." and ".." */ |
244 |
+ if (file->f_pos == 0) { |
245 |
+ ubifs_assert(!file->private_data); |
246 |
+@@ -451,6 +469,14 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
247 |
+ file->f_pos = key_hash_flash(c, &dent->key); |
248 |
+ file->private_data = dent; |
249 |
+ cond_resched(); |
250 |
++ |
251 |
++ if (file->f_version == 0) |
252 |
++ /* |
253 |
++ * The file was seek'ed meanwhile, lets return and start |
254 |
++ * reading direntries from the new position on the next |
255 |
++ * invocation. |
256 |
++ */ |
257 |
++ return 0; |
258 |
+ } |
259 |
+ |
260 |
+ out: |
261 |
+@@ -461,16 +487,14 @@ out: |
262 |
+ |
263 |
+ kfree(file->private_data); |
264 |
+ file->private_data = NULL; |
265 |
++ /* 2 is a special value indicating that there are no more direntries */ |
266 |
+ file->f_pos = 2; |
267 |
+ return 0; |
268 |
+ } |
269 |
+ |
270 |
+-/* If a directory is seeked, we have to free saved readdir() state */ |
271 |
+-static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin) |
272 |
++static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) |
273 |
+ { |
274 |
+- kfree(file->private_data); |
275 |
+- file->private_data = NULL; |
276 |
+- return generic_file_llseek(file, offset, origin); |
277 |
++ return generic_file_llseek(file, offset, whence); |
278 |
+ } |
279 |
+ |
280 |
+ /* Free saved readdir() state when the directory is closed */ |
281 |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c |
282 |
index 1e06853..b06d325 100644 |
283 |
--- a/fs/udf/balloc.c |
284 |
|
285 |
diff --git a/3.2.47/0000_README b/3.2.47/0000_README |
286 |
index 0779b50..94e84cf 100644 |
287 |
--- a/3.2.47/0000_README |
288 |
+++ b/3.2.47/0000_README |
289 |
@@ -106,7 +106,7 @@ Patch: 1046_linux-3.2.47.patch |
290 |
From: http://www.kernel.org |
291 |
Desc: Linux 3.2.47 |
292 |
|
293 |
-Patch: 4420_grsecurity-2.9.1-3.2.47-201306272056.patch |
294 |
+Patch: 4420_grsecurity-2.9.1-3.2.48-201306302051.patch |
295 |
From: http://www.grsecurity.net |
296 |
Desc: hardened-sources base patch from upstream grsecurity |
297 |
|
298 |
|
299 |
diff --git a/3.2.47/4420_grsecurity-2.9.1-3.2.47-201306272056.patch b/3.2.47/4420_grsecurity-2.9.1-3.2.48-201306302051.patch |
300 |
similarity index 99% |
301 |
rename from 3.2.47/4420_grsecurity-2.9.1-3.2.47-201306272056.patch |
302 |
rename to 3.2.47/4420_grsecurity-2.9.1-3.2.48-201306302051.patch |
303 |
index 81b695e..6eccde6 100644 |
304 |
--- a/3.2.47/4420_grsecurity-2.9.1-3.2.47-201306272056.patch |
305 |
+++ b/3.2.47/4420_grsecurity-2.9.1-3.2.48-201306302051.patch |
306 |
@@ -266,7 +266,7 @@ index 88fd7f5..b318a78 100644 |
307 |
============================================================== |
308 |
|
309 |
diff --git a/Makefile b/Makefile |
310 |
-index 40e2a11..8c31286 100644 |
311 |
+index 299e2eb..cb3e698 100644 |
312 |
--- a/Makefile |
313 |
+++ b/Makefile |
314 |
@@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ |
315 |
@@ -1448,7 +1448,7 @@ index 75fe66b..2255c86 100644 |
316 |
/* |
317 |
* Memory returned by kmalloc() may be used for DMA, so we must make |
318 |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h |
319 |
-index 1252a26..9dc17b5 100644 |
320 |
+index 1397408..c4f6969 100644 |
321 |
--- a/arch/arm/include/asm/cacheflush.h |
322 |
+++ b/arch/arm/include/asm/cacheflush.h |
323 |
@@ -108,7 +108,7 @@ struct cpu_cache_fns { |
324 |
@@ -8673,7 +8673,7 @@ index ad8f795..2c7eec6 100644 |
325 |
/* |
326 |
* Memory returned by kmalloc() may be used for DMA, so we must make |
327 |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
328 |
-index 9a42703..79a673e 100644 |
329 |
+index fb2e69d..9cd4eea 100644 |
330 |
--- a/arch/x86/Kconfig |
331 |
+++ b/arch/x86/Kconfig |
332 |
@@ -235,7 +235,7 @@ config X86_HT |
333 |
@@ -22535,10 +22535,10 @@ index aac5ea7..266eda9 100644 |
334 |
|
335 |
vmx->exit_reason = vmcs_read32(VM_EXIT_REASON); |
336 |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c |
337 |
-index e82a53a..6b38ed8 100644 |
338 |
+index 57867e4..1d5ff81 100644 |
339 |
--- a/arch/x86/kvm/x86.c |
340 |
+++ b/arch/x86/kvm/x86.c |
341 |
-@@ -1342,8 +1342,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) |
342 |
+@@ -1341,8 +1341,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) |
343 |
{ |
344 |
struct kvm *kvm = vcpu->kvm; |
345 |
int lm = is_long_mode(vcpu); |
346 |
@@ -22549,7 +22549,7 @@ index e82a53a..6b38ed8 100644 |
347 |
u8 blob_size = lm ? kvm->arch.xen_hvm_config.blob_size_64 |
348 |
: kvm->arch.xen_hvm_config.blob_size_32; |
349 |
u32 page_num = data & ~PAGE_MASK; |
350 |
-@@ -2160,6 +2160,8 @@ long kvm_arch_dev_ioctl(struct file *filp, |
351 |
+@@ -2159,6 +2159,8 @@ long kvm_arch_dev_ioctl(struct file *filp, |
352 |
if (n < msr_list.nmsrs) |
353 |
goto out; |
354 |
r = -EFAULT; |
355 |
@@ -22558,7 +22558,7 @@ index e82a53a..6b38ed8 100644 |
356 |
if (copy_to_user(user_msr_list->indices, &msrs_to_save, |
357 |
num_msrs_to_save * sizeof(u32))) |
358 |
goto out; |
359 |
-@@ -2335,15 +2337,20 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, |
360 |
+@@ -2334,15 +2336,20 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, |
361 |
struct kvm_cpuid2 *cpuid, |
362 |
struct kvm_cpuid_entry2 __user *entries) |
363 |
{ |
364 |
@@ -22582,7 +22582,7 @@ index e82a53a..6b38ed8 100644 |
365 |
vcpu->arch.cpuid_nent = cpuid->nent; |
366 |
kvm_apic_set_version(vcpu); |
367 |
kvm_x86_ops->cpuid_update(vcpu); |
368 |
-@@ -2358,15 +2365,19 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, |
369 |
+@@ -2357,15 +2364,19 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, |
370 |
struct kvm_cpuid2 *cpuid, |
371 |
struct kvm_cpuid_entry2 __user *entries) |
372 |
{ |
373 |
@@ -22605,7 +22605,7 @@ index e82a53a..6b38ed8 100644 |
374 |
return 0; |
375 |
|
376 |
out: |
377 |
-@@ -2741,7 +2752,7 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, |
378 |
+@@ -2740,7 +2751,7 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, |
379 |
static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, |
380 |
struct kvm_interrupt *irq) |
381 |
{ |
382 |
@@ -22614,7 +22614,7 @@ index e82a53a..6b38ed8 100644 |
383 |
return -EINVAL; |
384 |
if (irqchip_in_kernel(vcpu->kvm)) |
385 |
return -ENXIO; |
386 |
-@@ -5183,7 +5194,7 @@ static void kvm_set_mmio_spte_mask(void) |
387 |
+@@ -5182,7 +5193,7 @@ static void kvm_set_mmio_spte_mask(void) |
388 |
kvm_mmu_set_mmio_spte_mask(mask); |
389 |
} |
390 |
|
391 |
@@ -39831,7 +39831,7 @@ index 49b549f..13d648c 100644 |
392 |
|
393 |
mac->phydev = phydev; |
394 |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c |
395 |
-index f698183..d08df42 100644 |
396 |
+index ed7a5a6..606fc45 100644 |
397 |
--- a/drivers/net/ethernet/realtek/r8169.c |
398 |
+++ b/drivers/net/ethernet/realtek/r8169.c |
399 |
@@ -704,17 +704,17 @@ struct rtl8169_private { |
400 |
@@ -50146,7 +50146,7 @@ index 451b9b8..12e5a03 100644 |
401 |
|
402 |
out_free_fd: |
403 |
diff --git a/fs/exec.c b/fs/exec.c |
404 |
-index 312e297..699f362 100644 |
405 |
+index 312e297..6367442 100644 |
406 |
--- a/fs/exec.c |
407 |
+++ b/fs/exec.c |
408 |
@@ -55,12 +55,35 @@ |
409 |
@@ -50526,7 +50526,37 @@ index 312e297..699f362 100644 |
410 |
|
411 |
/* Set the new mm task size. We have to do that late because it may |
412 |
* depend on TIF_32BIT which is only updated in flush_thread() on |
413 |
-@@ -1266,7 +1342,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
414 |
+@@ -1159,13 +1235,6 @@ void setup_new_exec(struct linux_binprm * bprm) |
415 |
+ set_dumpable(current->mm, suid_dumpable); |
416 |
+ } |
417 |
+ |
418 |
+- /* |
419 |
+- * Flush performance counters when crossing a |
420 |
+- * security domain: |
421 |
+- */ |
422 |
+- if (!get_dumpable(current->mm)) |
423 |
+- perf_event_exit_task(current); |
424 |
+- |
425 |
+ /* An exec changes our domain. We are no longer part of the thread |
426 |
+ group */ |
427 |
+ |
428 |
+@@ -1229,6 +1298,15 @@ void install_exec_creds(struct linux_binprm *bprm) |
429 |
+ |
430 |
+ commit_creds(bprm->cred); |
431 |
+ bprm->cred = NULL; |
432 |
++ |
433 |
++ /* |
434 |
++ * Disable monitoring for regular users |
435 |
++ * when executing setuid binaries. Must |
436 |
++ * wait until new credentials are committed |
437 |
++ * by commit_creds() above |
438 |
++ */ |
439 |
++ if (get_dumpable(current->mm) != SUID_DUMP_USER) |
440 |
++ perf_event_exit_task(current); |
441 |
+ /* |
442 |
+ * cred_guard_mutex must be held at least to this point to prevent |
443 |
+ * ptrace_attach() from altering our determination of the task's |
444 |
+@@ -1266,7 +1344,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
445 |
} |
446 |
rcu_read_unlock(); |
447 |
|
448 |
@@ -50535,7 +50565,7 @@ index 312e297..699f362 100644 |
449 |
bprm->unsafe |= LSM_UNSAFE_SHARE; |
450 |
} else { |
451 |
res = -EAGAIN; |
452 |
-@@ -1461,6 +1537,31 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) |
453 |
+@@ -1461,6 +1539,31 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) |
454 |
|
455 |
EXPORT_SYMBOL(search_binary_handler); |
456 |
|
457 |
@@ -50567,7 +50597,7 @@ index 312e297..699f362 100644 |
458 |
/* |
459 |
* sys_execve() executes a new program. |
460 |
*/ |
461 |
-@@ -1469,6 +1570,11 @@ static int do_execve_common(const char *filename, |
462 |
+@@ -1469,6 +1572,11 @@ static int do_execve_common(const char *filename, |
463 |
struct user_arg_ptr envp, |
464 |
struct pt_regs *regs) |
465 |
{ |
466 |
@@ -50579,7 +50609,7 @@ index 312e297..699f362 100644 |
467 |
struct linux_binprm *bprm; |
468 |
struct file *file; |
469 |
struct files_struct *displaced; |
470 |
-@@ -1476,6 +1582,8 @@ static int do_execve_common(const char *filename, |
471 |
+@@ -1476,6 +1584,8 @@ static int do_execve_common(const char *filename, |
472 |
int retval; |
473 |
const struct cred *cred = current_cred(); |
474 |
|
475 |
@@ -50588,7 +50618,7 @@ index 312e297..699f362 100644 |
476 |
/* |
477 |
* We move the actual failure in case of RLIMIT_NPROC excess from |
478 |
* set*uid() to execve() because too many poorly written programs |
479 |
-@@ -1516,12 +1624,27 @@ static int do_execve_common(const char *filename, |
480 |
+@@ -1516,12 +1626,27 @@ static int do_execve_common(const char *filename, |
481 |
if (IS_ERR(file)) |
482 |
goto out_unmark; |
483 |
|
484 |
@@ -50616,7 +50646,7 @@ index 312e297..699f362 100644 |
485 |
retval = bprm_mm_init(bprm); |
486 |
if (retval) |
487 |
goto out_file; |
488 |
-@@ -1538,24 +1661,65 @@ static int do_execve_common(const char *filename, |
489 |
+@@ -1538,24 +1663,65 @@ static int do_execve_common(const char *filename, |
490 |
if (retval < 0) |
491 |
goto out; |
492 |
|
493 |
@@ -50686,7 +50716,7 @@ index 312e297..699f362 100644 |
494 |
current->fs->in_exec = 0; |
495 |
current->in_execve = 0; |
496 |
acct_update_integrals(current); |
497 |
-@@ -1564,6 +1728,14 @@ static int do_execve_common(const char *filename, |
498 |
+@@ -1564,6 +1730,14 @@ static int do_execve_common(const char *filename, |
499 |
put_files_struct(displaced); |
500 |
return retval; |
501 |
|
502 |
@@ -50701,7 +50731,7 @@ index 312e297..699f362 100644 |
503 |
out: |
504 |
if (bprm->mm) { |
505 |
acct_arg_size(bprm, 0); |
506 |
-@@ -1637,7 +1809,7 @@ static int expand_corename(struct core_name *cn) |
507 |
+@@ -1637,7 +1811,7 @@ static int expand_corename(struct core_name *cn) |
508 |
{ |
509 |
char *old_corename = cn->corename; |
510 |
|
511 |
@@ -50710,7 +50740,7 @@ index 312e297..699f362 100644 |
512 |
cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL); |
513 |
|
514 |
if (!cn->corename) { |
515 |
-@@ -1734,7 +1906,7 @@ static int format_corename(struct core_name *cn, long signr) |
516 |
+@@ -1734,7 +1908,7 @@ static int format_corename(struct core_name *cn, long signr) |
517 |
int pid_in_pattern = 0; |
518 |
int err = 0; |
519 |
|
520 |
@@ -50719,7 +50749,7 @@ index 312e297..699f362 100644 |
521 |
cn->corename = kmalloc(cn->size, GFP_KERNEL); |
522 |
cn->used = 0; |
523 |
|
524 |
-@@ -1831,6 +2003,280 @@ out: |
525 |
+@@ -1831,6 +2005,280 @@ out: |
526 |
return ispipe; |
527 |
} |
528 |
|
529 |
@@ -51000,7 +51030,7 @@ index 312e297..699f362 100644 |
530 |
static int zap_process(struct task_struct *start, int exit_code) |
531 |
{ |
532 |
struct task_struct *t; |
533 |
-@@ -2004,17 +2450,17 @@ static void coredump_finish(struct mm_struct *mm) |
534 |
+@@ -2004,17 +2452,17 @@ static void coredump_finish(struct mm_struct *mm) |
535 |
void set_dumpable(struct mm_struct *mm, int value) |
536 |
{ |
537 |
switch (value) { |
538 |
@@ -51021,7 +51051,7 @@ index 312e297..699f362 100644 |
539 |
set_bit(MMF_DUMP_SECURELY, &mm->flags); |
540 |
smp_wmb(); |
541 |
set_bit(MMF_DUMPABLE, &mm->flags); |
542 |
-@@ -2027,7 +2473,7 @@ static int __get_dumpable(unsigned long mm_flags) |
543 |
+@@ -2027,7 +2475,7 @@ static int __get_dumpable(unsigned long mm_flags) |
544 |
int ret; |
545 |
|
546 |
ret = mm_flags & MMF_DUMPABLE_MASK; |
547 |
@@ -51030,7 +51060,7 @@ index 312e297..699f362 100644 |
548 |
} |
549 |
|
550 |
int get_dumpable(struct mm_struct *mm) |
551 |
-@@ -2042,17 +2488,17 @@ static void wait_for_dump_helpers(struct file *file) |
552 |
+@@ -2042,17 +2490,17 @@ static void wait_for_dump_helpers(struct file *file) |
553 |
pipe = file->f_path.dentry->d_inode->i_pipe; |
554 |
|
555 |
pipe_lock(pipe); |
556 |
@@ -51053,7 +51083,7 @@ index 312e297..699f362 100644 |
557 |
pipe_unlock(pipe); |
558 |
|
559 |
} |
560 |
-@@ -2113,7 +2559,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
561 |
+@@ -2113,7 +2561,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
562 |
int retval = 0; |
563 |
int flag = 0; |
564 |
int ispipe; |
565 |
@@ -51063,7 +51093,7 @@ index 312e297..699f362 100644 |
566 |
struct coredump_params cprm = { |
567 |
.signr = signr, |
568 |
.regs = regs, |
569 |
-@@ -2128,6 +2575,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
570 |
+@@ -2128,6 +2577,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
571 |
|
572 |
audit_core_dumps(signr); |
573 |
|
574 |
@@ -51073,7 +51103,7 @@ index 312e297..699f362 100644 |
575 |
binfmt = mm->binfmt; |
576 |
if (!binfmt || !binfmt->core_dump) |
577 |
goto fail; |
578 |
-@@ -2138,14 +2588,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
579 |
+@@ -2138,14 +2590,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
580 |
if (!cred) |
581 |
goto fail; |
582 |
/* |
583 |
@@ -51094,7 +51124,7 @@ index 312e297..699f362 100644 |
584 |
} |
585 |
|
586 |
retval = coredump_wait(exit_code, &core_state); |
587 |
-@@ -2195,7 +2647,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
588 |
+@@ -2195,7 +2649,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
589 |
} |
590 |
cprm.limit = RLIM_INFINITY; |
591 |
|
592 |
@@ -51103,7 +51133,7 @@ index 312e297..699f362 100644 |
593 |
if (core_pipe_limit && (core_pipe_limit < dump_count)) { |
594 |
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", |
595 |
task_tgid_vnr(current), current->comm); |
596 |
-@@ -2222,9 +2674,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
597 |
+@@ -2222,9 +2676,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
598 |
} else { |
599 |
struct inode *inode; |
600 |
|
601 |
@@ -51123,7 +51153,7 @@ index 312e297..699f362 100644 |
602 |
cprm.file = filp_open(cn.corename, |
603 |
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
604 |
0600); |
605 |
-@@ -2265,7 +2727,7 @@ close_fail: |
606 |
+@@ -2265,7 +2729,7 @@ close_fail: |
607 |
filp_close(cprm.file, NULL); |
608 |
fail_dropcount: |
609 |
if (ispipe) |
610 |
@@ -51132,7 +51162,7 @@ index 312e297..699f362 100644 |
611 |
fail_unlock: |
612 |
kfree(cn.corename); |
613 |
fail_corename: |
614 |
-@@ -2284,7 +2746,7 @@ fail: |
615 |
+@@ -2284,7 +2748,7 @@ fail: |
616 |
*/ |
617 |
int dump_write(struct file *file, const void *addr, int nr) |
618 |
{ |
619 |
@@ -57248,6 +57278,70 @@ index bb55cdb..e9ebb8a 100644 |
620 |
{ |
621 |
if (sbi->s_bytesex == BYTESEX_PDP) |
622 |
return PDP_swab((__force __u32)n); |
623 |
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c |
624 |
+index 6834920..6b0cc3e 100644 |
625 |
+--- a/fs/ubifs/dir.c |
626 |
++++ b/fs/ubifs/dir.c |
627 |
+@@ -372,6 +372,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
628 |
+ */ |
629 |
+ return 0; |
630 |
+ |
631 |
++ if (file->f_version == 0) { |
632 |
++ /* |
633 |
++ * The file was seek'ed, which means that @file->private_data |
634 |
++ * is now invalid. This may also be just the first |
635 |
++ * 'ubifs_readdir()' invocation, in which case |
636 |
++ * @file->private_data is NULL, and the below code is |
637 |
++ * basically a no-op. |
638 |
++ */ |
639 |
++ kfree(file->private_data); |
640 |
++ file->private_data = NULL; |
641 |
++ } |
642 |
++ |
643 |
++ /* |
644 |
++ * 'generic_file_llseek()' unconditionally sets @file->f_version to |
645 |
++ * zero, and we use this for detecting whether the file was seek'ed. |
646 |
++ */ |
647 |
++ file->f_version = 1; |
648 |
++ |
649 |
+ /* File positions 0 and 1 correspond to "." and ".." */ |
650 |
+ if (file->f_pos == 0) { |
651 |
+ ubifs_assert(!file->private_data); |
652 |
+@@ -446,6 +464,14 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
653 |
+ file->f_pos = key_hash_flash(c, &dent->key); |
654 |
+ file->private_data = dent; |
655 |
+ cond_resched(); |
656 |
++ |
657 |
++ if (file->f_version == 0) |
658 |
++ /* |
659 |
++ * The file was seek'ed meanwhile, lets return and start |
660 |
++ * reading direntries from the new position on the next |
661 |
++ * invocation. |
662 |
++ */ |
663 |
++ return 0; |
664 |
+ } |
665 |
+ |
666 |
+ out: |
667 |
+@@ -456,16 +482,14 @@ out: |
668 |
+ |
669 |
+ kfree(file->private_data); |
670 |
+ file->private_data = NULL; |
671 |
++ /* 2 is a special value indicating that there are no more direntries */ |
672 |
+ file->f_pos = 2; |
673 |
+ return 0; |
674 |
+ } |
675 |
+ |
676 |
+-/* If a directory is seeked, we have to free saved readdir() state */ |
677 |
+-static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin) |
678 |
++static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) |
679 |
+ { |
680 |
+- kfree(file->private_data); |
681 |
+- file->private_data = NULL; |
682 |
+- return generic_file_llseek(file, offset, origin); |
683 |
++ return generic_file_llseek(file, offset, whence); |
684 |
+ } |
685 |
+ |
686 |
+ /* Free saved readdir() state when the directory is closed */ |
687 |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c |
688 |
index 9228950..bbad895 100644 |
689 |
--- a/fs/ubifs/io.c |
690 |
@@ -87232,7 +87326,7 @@ index f78f898..d7aa843 100644 |
691 |
|
692 |
if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs, NULL)) { |
693 |
diff --git a/net/compat.c b/net/compat.c |
694 |
-index 6def90e..ffd9b82 100644 |
695 |
+index 8c979cc..5800e81 100644 |
696 |
--- a/net/compat.c |
697 |
+++ b/net/compat.c |
698 |
@@ -71,9 +71,9 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) |
699 |
@@ -87362,7 +87456,7 @@ index 6def90e..ffd9b82 100644 |
700 |
struct group_filter __user *kgf; |
701 |
int __user *koptlen; |
702 |
u32 interface, fmode, numsrc; |
703 |
-@@ -790,7 +790,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) |
704 |
+@@ -799,7 +799,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) |
705 |
|
706 |
if (call < SYS_SOCKET || call > SYS_SENDMMSG) |
707 |
return -EINVAL; |
708 |
@@ -88377,7 +88471,7 @@ index 8f441b2..a56d38e 100644 |
709 |
return -ENOMEM; |
710 |
} |
711 |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c |
712 |
-index d55110e..7e0739d 100644 |
713 |
+index 5f28fab..ebd7a97 100644 |
714 |
--- a/net/ipv4/ip_gre.c |
715 |
+++ b/net/ipv4/ip_gre.c |
716 |
@@ -118,7 +118,7 @@ |
717 |
@@ -88898,24 +88992,6 @@ index 5485077..7e37374 100644 |
718 |
|
719 |
hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table); |
720 |
if (hdr == NULL) |
721 |
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
722 |
-index fe381c2..ec8b4b7e 100644 |
723 |
---- a/net/ipv4/tcp.c |
724 |
-+++ b/net/ipv4/tcp.c |
725 |
-@@ -3037,8 +3037,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, |
726 |
- |
727 |
- for (i = 0; i < shi->nr_frags; ++i) { |
728 |
- const struct skb_frag_struct *f = &shi->frags[i]; |
729 |
-- struct page *page = skb_frag_page(f); |
730 |
-- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); |
731 |
-+ unsigned int offset = f->page_offset; |
732 |
-+ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); |
733 |
-+ |
734 |
-+ sg_set_page(&sg, page, skb_frag_size(f), |
735 |
-+ offset_in_page(offset)); |
736 |
- if (crypto_hash_update(desc, &sg, skb_frag_size(f))) |
737 |
- return 1; |
738 |
- } |
739 |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
740 |
index 872b41d..54a02f1 100644 |
741 |
--- a/net/ipv4/tcp_input.c |
742 |
@@ -89293,7 +89369,7 @@ index 5a65eea..bd913a1 100644 |
743 |
|
744 |
int udp4_seq_show(struct seq_file *seq, void *v) |
745 |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
746 |
-index d84033b..a15645a 100644 |
747 |
+index d603caa..dca1994 100644 |
748 |
--- a/net/ipv6/addrconf.c |
749 |
+++ b/net/ipv6/addrconf.c |
750 |
@@ -2151,7 +2151,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) |
751 |
@@ -89366,7 +89442,7 @@ index 1567fb1..29af910 100644 |
752 |
dst = NULL; |
753 |
} |
754 |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
755 |
-index 3ccd9b2..7a0f168 100644 |
756 |
+index 6aadaa8..7a0f168 100644 |
757 |
--- a/net/ipv6/ip6_output.c |
758 |
+++ b/net/ipv6/ip6_output.c |
759 |
@@ -909,11 +909,17 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, |
760 |
@@ -89388,15 +89464,6 @@ index 3ccd9b2..7a0f168 100644 |
761 |
/* Yes, checking route validity in not connected |
762 |
* case is not very simple. Take into account, |
763 |
* that we do not support routing by source, TOS, |
764 |
-@@ -1233,7 +1239,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
765 |
- if (WARN_ON(np->cork.opt)) |
766 |
- return -EINVAL; |
767 |
- |
768 |
-- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); |
769 |
-+ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); |
770 |
- if (unlikely(np->cork.opt == NULL)) |
771 |
- return -ENOBUFS; |
772 |
- |
773 |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c |
774 |
index b204df8..8f274f4 100644 |
775 |
--- a/net/ipv6/ipv6_sockglue.c |
776 |
@@ -90056,33 +90123,6 @@ index 93a41a0..d4b4edb 100644 |
777 |
|
778 |
NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); |
779 |
NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id); |
780 |
-diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c |
781 |
-index 6f60175..74410e6 100644 |
782 |
---- a/net/l2tp/l2tp_ppp.c |
783 |
-+++ b/net/l2tp/l2tp_ppp.c |
784 |
-@@ -350,19 +350,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh |
785 |
- skb_put(skb, 2); |
786 |
- |
787 |
- /* Copy user data into skb */ |
788 |
-- error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); |
789 |
-+ error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, |
790 |
-+ total_len); |
791 |
- if (error < 0) { |
792 |
- kfree_skb(skb); |
793 |
- goto error_put_sess_tun; |
794 |
- } |
795 |
-- skb_put(skb, total_len); |
796 |
- |
797 |
- l2tp_xmit_skb(session, skb, session->hdr_len); |
798 |
- |
799 |
- sock_put(ps->tunnel_sock); |
800 |
- sock_put(sk); |
801 |
- |
802 |
-- return error; |
803 |
-+ return total_len; |
804 |
- |
805 |
- error_put_sess_tun: |
806 |
- sock_put(ps->tunnel_sock); |
807 |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h |
808 |
index 73495f1..ad51356 100644 |
809 |
--- a/net/mac80211/ieee80211_i.h |
810 |
@@ -90873,7 +90913,7 @@ index 3df7c5a..8f324b0 100644 |
811 |
*uaddr_len = sizeof(struct sockaddr_ax25); |
812 |
} |
813 |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
814 |
-index 5a70215..070be35 100644 |
815 |
+index a2ac2c3..070be35 100644 |
816 |
--- a/net/packet/af_packet.c |
817 |
+++ b/net/packet/af_packet.c |
818 |
@@ -1670,7 +1670,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, |
819 |
@@ -90913,22 +90953,7 @@ index 5a70215..070be35 100644 |
820 |
|
821 |
msg->msg_flags |= MSG_ERRQUEUE; |
822 |
err = copied; |
823 |
-@@ -2820,12 +2822,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, |
824 |
- return -EOPNOTSUPP; |
825 |
- |
826 |
- uaddr->sa_family = AF_PACKET; |
827 |
-+ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); |
828 |
- rcu_read_lock(); |
829 |
- dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); |
830 |
- if (dev) |
831 |
-- strncpy(uaddr->sa_data, dev->name, 14); |
832 |
-- else |
833 |
-- memset(uaddr->sa_data, 0, 14); |
834 |
-+ strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); |
835 |
- rcu_read_unlock(); |
836 |
- *uaddr_len = sizeof(*uaddr); |
837 |
- |
838 |
-@@ -3262,7 +3263,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, |
839 |
+@@ -3261,7 +3263,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, |
840 |
case PACKET_HDRLEN: |
841 |
if (len > sizeof(int)) |
842 |
len = sizeof(int); |
843 |
@@ -90937,7 +90962,7 @@ index 5a70215..070be35 100644 |
844 |
return -EFAULT; |
845 |
switch (val) { |
846 |
case TPACKET_V1: |
847 |
-@@ -3312,7 +3313,11 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, |
848 |
+@@ -3311,7 +3313,11 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, |
849 |
|
850 |
if (put_user(len, optlen)) |
851 |
return -EFAULT; |
852 |
@@ -91617,7 +91642,7 @@ index 9032d50..49eb875 100644 |
853 |
sctp_generate_t1_cookie_event, |
854 |
sctp_generate_t1_init_event, |
855 |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c |
856 |
-index 5e0d86e..f09fd13 100644 |
857 |
+index ba0108f..f09fd13 100644 |
858 |
--- a/net/sctp/socket.c |
859 |
+++ b/net/sctp/socket.c |
860 |
@@ -2157,11 +2157,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, |
861 |
@@ -91635,20 +91660,7 @@ index 5e0d86e..f09fd13 100644 |
862 |
|
863 |
/* |
864 |
* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, |
865 |
-@@ -3929,6 +3931,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) |
866 |
- |
867 |
- /* Release our hold on the endpoint. */ |
868 |
- sp = sctp_sk(sk); |
869 |
-+ /* This could happen during socket init, thus we bail out |
870 |
-+ * early, since the rest of the below is not setup either. |
871 |
-+ */ |
872 |
-+ if (sp->ep == NULL) |
873 |
-+ return; |
874 |
-+ |
875 |
- if (sp->do_auto_asconf) { |
876 |
- sp->do_auto_asconf = 0; |
877 |
- list_del(&sp->auto_asconf_list); |
878 |
-@@ -4141,13 +4149,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, |
879 |
+@@ -4147,13 +4149,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, |
880 |
static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, |
881 |
int __user *optlen) |
882 |
{ |
883 |
@@ -91666,7 +91678,7 @@ index 5e0d86e..f09fd13 100644 |
884 |
return -EFAULT; |
885 |
return 0; |
886 |
} |
887 |
-@@ -4165,6 +4176,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, |
888 |
+@@ -4171,6 +4176,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, |
889 |
*/ |
890 |
static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optval, int __user *optlen) |
891 |
{ |
892 |
@@ -91675,7 +91687,7 @@ index 5e0d86e..f09fd13 100644 |
893 |
/* Applicable to UDP-style socket only */ |
894 |
if (sctp_style(sk, TCP)) |
895 |
return -EOPNOTSUPP; |
896 |
-@@ -4173,7 +4186,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv |
897 |
+@@ -4179,7 +4186,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv |
898 |
len = sizeof(int); |
899 |
if (put_user(len, optlen)) |
900 |
return -EFAULT; |
901 |
@@ -91685,7 +91697,7 @@ index 5e0d86e..f09fd13 100644 |
902 |
return -EFAULT; |
903 |
return 0; |
904 |
} |
905 |
-@@ -4537,12 +4551,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, |
906 |
+@@ -4543,12 +4551,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, |
907 |
*/ |
908 |
static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) |
909 |
{ |
910 |
@@ -91702,7 +91714,7 @@ index 5e0d86e..f09fd13 100644 |
911 |
return -EFAULT; |
912 |
return 0; |
913 |
} |
914 |
-@@ -4583,6 +4600,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, |
915 |
+@@ -4589,6 +4600,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, |
916 |
addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
917 |
if (space_left < addrlen) |
918 |
return -ENOMEM; |
919 |
@@ -91765,7 +91777,7 @@ index 8da4481..d02565e 100644 |
920 |
+ (rtt >> sctp_rto_alpha); |
921 |
} else { |
922 |
diff --git a/net/socket.c b/net/socket.c |
923 |
-index 68879db..a5288e9 100644 |
924 |
+index cf546a3..f7c6c75 100644 |
925 |
--- a/net/socket.c |
926 |
+++ b/net/socket.c |
927 |
@@ -88,6 +88,7 @@ |
928 |
@@ -91936,7 +91948,7 @@ index 68879db..a5288e9 100644 |
929 |
int err, err2; |
930 |
int fput_needed; |
931 |
|
932 |
-@@ -1950,7 +2012,7 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
933 |
+@@ -1950,7 +2012,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
934 |
* checking falls down on this. |
935 |
*/ |
936 |
if (copy_from_user(ctl_buf, |
937 |
@@ -91945,7 +91957,7 @@ index 68879db..a5288e9 100644 |
938 |
ctl_len)) |
939 |
goto out_freectl; |
940 |
msg_sys->msg_control = ctl_buf; |
941 |
-@@ -2090,7 +2152,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
942 |
+@@ -2101,7 +2163,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
943 |
int err, iov_size, total_len, len; |
944 |
|
945 |
/* kernel mode address */ |
946 |
@@ -91954,7 +91966,7 @@ index 68879db..a5288e9 100644 |
947 |
|
948 |
/* user mode address pointers */ |
949 |
struct sockaddr __user *uaddr; |
950 |
-@@ -2120,7 +2182,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
951 |
+@@ -2131,7 +2193,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
952 |
* kernel msghdr to use the kernel address space) |
953 |
*/ |
954 |
|
955 |
@@ -91963,7 +91975,7 @@ index 68879db..a5288e9 100644 |
956 |
uaddr_len = COMPAT_NAMELEN(msg); |
957 |
if (MSG_CMSG_COMPAT & flags) { |
958 |
err = verify_compat_iovec(msg_sys, iov, |
959 |
-@@ -2749,7 +2811,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
960 |
+@@ -2772,7 +2834,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
961 |
} |
962 |
|
963 |
ifr = compat_alloc_user_space(buf_size); |
964 |
@@ -91972,7 +91984,7 @@ index 68879db..a5288e9 100644 |
965 |
|
966 |
if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) |
967 |
return -EFAULT; |
968 |
-@@ -2773,12 +2835,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
969 |
+@@ -2796,12 +2858,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
970 |
offsetof(struct ethtool_rxnfc, fs.ring_cookie)); |
971 |
|
972 |
if (copy_in_user(rxnfc, compat_rxnfc, |
973 |
@@ -91989,7 +92001,7 @@ index 68879db..a5288e9 100644 |
974 |
copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt, |
975 |
sizeof(rxnfc->rule_cnt))) |
976 |
return -EFAULT; |
977 |
-@@ -2790,12 +2852,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
978 |
+@@ -2813,12 +2875,12 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
979 |
|
980 |
if (convert_out) { |
981 |
if (copy_in_user(compat_rxnfc, rxnfc, |
982 |
@@ -92006,7 +92018,7 @@ index 68879db..a5288e9 100644 |
983 |
copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt, |
984 |
sizeof(rxnfc->rule_cnt))) |
985 |
return -EFAULT; |
986 |
-@@ -2865,7 +2927,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd, |
987 |
+@@ -2888,7 +2950,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd, |
988 |
old_fs = get_fs(); |
989 |
set_fs(KERNEL_DS); |
990 |
err = dev_ioctl(net, cmd, |
991 |
@@ -92015,7 +92027,7 @@ index 68879db..a5288e9 100644 |
992 |
set_fs(old_fs); |
993 |
|
994 |
return err; |
995 |
-@@ -2974,7 +3036,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd, |
996 |
+@@ -2997,7 +3059,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd, |
997 |
|
998 |
old_fs = get_fs(); |
999 |
set_fs(KERNEL_DS); |
1000 |
@@ -92024,7 +92036,7 @@ index 68879db..a5288e9 100644 |
1001 |
set_fs(old_fs); |
1002 |
|
1003 |
if (cmd == SIOCGIFMAP && !err) { |
1004 |
-@@ -3079,7 +3141,7 @@ static int routing_ioctl(struct net *net, struct socket *sock, |
1005 |
+@@ -3102,7 +3164,7 @@ static int routing_ioctl(struct net *net, struct socket *sock, |
1006 |
ret |= __get_user(rtdev, &(ur4->rt_dev)); |
1007 |
if (rtdev) { |
1008 |
ret |= copy_from_user(devname, compat_ptr(rtdev), 15); |
1009 |
@@ -92033,7 +92045,7 @@ index 68879db..a5288e9 100644 |
1010 |
devname[15] = 0; |
1011 |
} else |
1012 |
r4.rt_dev = NULL; |
1013 |
-@@ -3319,8 +3381,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, |
1014 |
+@@ -3342,8 +3404,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, |
1015 |
int __user *uoptlen; |
1016 |
int err; |
1017 |
|
1018 |
@@ -92044,7 +92056,7 @@ index 68879db..a5288e9 100644 |
1019 |
|
1020 |
set_fs(KERNEL_DS); |
1021 |
if (level == SOL_SOCKET) |
1022 |
-@@ -3340,7 +3402,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, |
1023 |
+@@ -3363,7 +3425,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, |
1024 |
char __user *uoptval; |
1025 |
int err; |
1026 |
|
1027 |
|
1028 |
diff --git a/3.9.8/0000_README b/3.9.8/0000_README |
1029 |
index 8c126eb..1e4e620 100644 |
1030 |
--- a/3.9.8/0000_README |
1031 |
+++ b/3.9.8/0000_README |
1032 |
@@ -2,7 +2,7 @@ README |
1033 |
----------------------------------------------------------------------------- |
1034 |
Individual Patch Descriptions: |
1035 |
----------------------------------------------------------------------------- |
1036 |
-Patch: 4420_grsecurity-2.9.1-3.9.8-201306272057.patch |
1037 |
+Patch: 4420_grsecurity-2.9.1-3.9.8-201306302052.patch |
1038 |
From: http://www.grsecurity.net |
1039 |
Desc: hardened-sources base patch from upstream grsecurity |
1040 |
|
1041 |
|
1042 |
diff --git a/3.9.8/4420_grsecurity-2.9.1-3.9.8-201306272057.patch b/3.9.8/4420_grsecurity-2.9.1-3.9.8-201306302052.patch |
1043 |
similarity index 99% |
1044 |
rename from 3.9.8/4420_grsecurity-2.9.1-3.9.8-201306272057.patch |
1045 |
rename to 3.9.8/4420_grsecurity-2.9.1-3.9.8-201306302052.patch |
1046 |
index 3efd0e4..9c80933 100644 |
1047 |
--- a/3.9.8/4420_grsecurity-2.9.1-3.9.8-201306272057.patch |
1048 |
+++ b/3.9.8/4420_grsecurity-2.9.1-3.9.8-201306302052.patch |
1049 |
@@ -2312,7 +2312,7 @@ index 60d3b73..d27ee09 100644 |
1050 |
EXPORT_SYMBOL(__get_user_1); |
1051 |
EXPORT_SYMBOL(__get_user_2); |
1052 |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S |
1053 |
-index 0f82098..3dbd3ee 100644 |
1054 |
+index 0f82098..fb3d3d5 100644 |
1055 |
--- a/arch/arm/kernel/entry-armv.S |
1056 |
+++ b/arch/arm/kernel/entry-armv.S |
1057 |
@@ -47,6 +47,87 @@ |
1058 |
@@ -2484,7 +2484,7 @@ index 0f82098..3dbd3ee 100644 |
1059 |
THUMB( str sp, [ip], #4 ) |
1060 |
THUMB( str lr, [ip], #4 ) |
1061 |
-#ifdef CONFIG_CPU_USE_DOMAINS |
1062 |
-+#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) |
1063 |
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) |
1064 |
ldr r6, [r2, #TI_CPU_DOMAIN] |
1065 |
#endif |
1066 |
set_tls r3, r4, r5 |
1067 |
@@ -2493,7 +2493,7 @@ index 0f82098..3dbd3ee 100644 |
1068 |
ldr r7, [r7, #TSK_STACK_CANARY] |
1069 |
#endif |
1070 |
-#ifdef CONFIG_CPU_USE_DOMAINS |
1071 |
-+#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) |
1072 |
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) |
1073 |
mcr p15, 0, r6, c3, c0, 0 @ Set domain register |
1074 |
#endif |
1075 |
mov r5, r0 |
1076 |
@@ -50560,7 +50560,7 @@ index 6a16053..2155147 100644 |
1077 |
return rc; |
1078 |
} |
1079 |
diff --git a/fs/exec.c b/fs/exec.c |
1080 |
-index 6d56ff2..3bc6638 100644 |
1081 |
+index 6d56ff2..f65b4ca 100644 |
1082 |
--- a/fs/exec.c |
1083 |
+++ b/fs/exec.c |
1084 |
@@ -55,8 +55,20 @@ |
1085 |
@@ -50862,7 +50862,37 @@ index 6d56ff2..3bc6638 100644 |
1086 |
set_fs(old_fs); |
1087 |
return result; |
1088 |
} |
1089 |
-@@ -1250,7 +1325,7 @@ static int check_unsafe_exec(struct linux_binprm *bprm) |
1090 |
+@@ -1136,13 +1211,6 @@ void setup_new_exec(struct linux_binprm * bprm) |
1091 |
+ set_dumpable(current->mm, suid_dumpable); |
1092 |
+ } |
1093 |
+ |
1094 |
+- /* |
1095 |
+- * Flush performance counters when crossing a |
1096 |
+- * security domain: |
1097 |
+- */ |
1098 |
+- if (!get_dumpable(current->mm)) |
1099 |
+- perf_event_exit_task(current); |
1100 |
+- |
1101 |
+ /* An exec changes our domain. We are no longer part of the thread |
1102 |
+ group */ |
1103 |
+ |
1104 |
+@@ -1206,6 +1274,15 @@ void install_exec_creds(struct linux_binprm *bprm) |
1105 |
+ |
1106 |
+ commit_creds(bprm->cred); |
1107 |
+ bprm->cred = NULL; |
1108 |
++ |
1109 |
++ /* |
1110 |
++ * Disable monitoring for regular users |
1111 |
++ * when executing setuid binaries. Must |
1112 |
++ * wait until new credentials are committed |
1113 |
++ * by commit_creds() above |
1114 |
++ */ |
1115 |
++ if (get_dumpable(current->mm) != SUID_DUMP_USER) |
1116 |
++ perf_event_exit_task(current); |
1117 |
+ /* |
1118 |
+ * cred_guard_mutex must be held at least to this point to prevent |
1119 |
+ * ptrace_attach() from altering our determination of the task's |
1120 |
+@@ -1250,7 +1327,7 @@ static int check_unsafe_exec(struct linux_binprm *bprm) |
1121 |
} |
1122 |
rcu_read_unlock(); |
1123 |
|
1124 |
@@ -50871,7 +50901,7 @@ index 6d56ff2..3bc6638 100644 |
1125 |
bprm->unsafe |= LSM_UNSAFE_SHARE; |
1126 |
} else { |
1127 |
res = -EAGAIN; |
1128 |
-@@ -1450,6 +1525,31 @@ int search_binary_handler(struct linux_binprm *bprm) |
1129 |
+@@ -1450,6 +1527,31 @@ int search_binary_handler(struct linux_binprm *bprm) |
1130 |
|
1131 |
EXPORT_SYMBOL(search_binary_handler); |
1132 |
|
1133 |
@@ -50903,7 +50933,7 @@ index 6d56ff2..3bc6638 100644 |
1134 |
/* |
1135 |
* sys_execve() executes a new program. |
1136 |
*/ |
1137 |
-@@ -1457,6 +1557,11 @@ static int do_execve_common(const char *filename, |
1138 |
+@@ -1457,6 +1559,11 @@ static int do_execve_common(const char *filename, |
1139 |
struct user_arg_ptr argv, |
1140 |
struct user_arg_ptr envp) |
1141 |
{ |
1142 |
@@ -50915,7 +50945,7 @@ index 6d56ff2..3bc6638 100644 |
1143 |
struct linux_binprm *bprm; |
1144 |
struct file *file; |
1145 |
struct files_struct *displaced; |
1146 |
-@@ -1464,6 +1569,8 @@ static int do_execve_common(const char *filename, |
1147 |
+@@ -1464,6 +1571,8 @@ static int do_execve_common(const char *filename, |
1148 |
int retval; |
1149 |
const struct cred *cred = current_cred(); |
1150 |
|
1151 |
@@ -50924,7 +50954,7 @@ index 6d56ff2..3bc6638 100644 |
1152 |
/* |
1153 |
* We move the actual failure in case of RLIMIT_NPROC excess from |
1154 |
* set*uid() to execve() because too many poorly written programs |
1155 |
-@@ -1504,12 +1611,27 @@ static int do_execve_common(const char *filename, |
1156 |
+@@ -1504,12 +1613,27 @@ static int do_execve_common(const char *filename, |
1157 |
if (IS_ERR(file)) |
1158 |
goto out_unmark; |
1159 |
|
1160 |
@@ -50952,7 +50982,7 @@ index 6d56ff2..3bc6638 100644 |
1161 |
retval = bprm_mm_init(bprm); |
1162 |
if (retval) |
1163 |
goto out_file; |
1164 |
-@@ -1526,24 +1648,65 @@ static int do_execve_common(const char *filename, |
1165 |
+@@ -1526,24 +1650,65 @@ static int do_execve_common(const char *filename, |
1166 |
if (retval < 0) |
1167 |
goto out; |
1168 |
|
1169 |
@@ -51022,7 +51052,7 @@ index 6d56ff2..3bc6638 100644 |
1170 |
current->fs->in_exec = 0; |
1171 |
current->in_execve = 0; |
1172 |
acct_update_integrals(current); |
1173 |
-@@ -1552,6 +1715,14 @@ static int do_execve_common(const char *filename, |
1174 |
+@@ -1552,6 +1717,14 @@ static int do_execve_common(const char *filename, |
1175 |
put_files_struct(displaced); |
1176 |
return retval; |
1177 |
|
1178 |
@@ -51037,7 +51067,7 @@ index 6d56ff2..3bc6638 100644 |
1179 |
out: |
1180 |
if (bprm->mm) { |
1181 |
acct_arg_size(bprm, 0); |
1182 |
-@@ -1700,3 +1871,283 @@ asmlinkage long compat_sys_execve(const char __user * filename, |
1183 |
+@@ -1700,3 +1873,283 @@ asmlinkage long compat_sys_execve(const char __user * filename, |
1184 |
return error; |
1185 |
} |
1186 |
#endif |
1187 |
@@ -56758,6 +56788,67 @@ index 69d4889..a810bd4 100644 |
1188 |
{ |
1189 |
if (sbi->s_bytesex == BYTESEX_PDP) |
1190 |
return PDP_swab((__force __u32)n); |
1191 |
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c |
1192 |
+index de08c92f..732cd63 100644 |
1193 |
+--- a/fs/ubifs/dir.c |
1194 |
++++ b/fs/ubifs/dir.c |
1195 |
+@@ -364,6 +364,24 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
1196 |
+ */ |
1197 |
+ return 0; |
1198 |
+ |
1199 |
++ if (file->f_version == 0) { |
1200 |
++ /* |
1201 |
++ * The file was seek'ed, which means that @file->private_data |
1202 |
++ * is now invalid. This may also be just the first |
1203 |
++ * 'ubifs_readdir()' invocation, in which case |
1204 |
++ * @file->private_data is NULL, and the below code is |
1205 |
++ * basically a no-op. |
1206 |
++ */ |
1207 |
++ kfree(file->private_data); |
1208 |
++ file->private_data = NULL; |
1209 |
++ } |
1210 |
++ |
1211 |
++ /* |
1212 |
++ * 'generic_file_llseek()' unconditionally sets @file->f_version to |
1213 |
++ * zero, and we use this for detecting whether the file was seek'ed. |
1214 |
++ */ |
1215 |
++ file->f_version = 1; |
1216 |
++ |
1217 |
+ /* File positions 0 and 1 correspond to "." and ".." */ |
1218 |
+ if (file->f_pos == 0) { |
1219 |
+ ubifs_assert(!file->private_data); |
1220 |
+@@ -438,6 +456,14 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) |
1221 |
+ file->f_pos = key_hash_flash(c, &dent->key); |
1222 |
+ file->private_data = dent; |
1223 |
+ cond_resched(); |
1224 |
++ |
1225 |
++ if (file->f_version == 0) |
1226 |
++ /* |
1227 |
++ * The file was seek'ed meanwhile, lets return and start |
1228 |
++ * reading direntries from the new position on the next |
1229 |
++ * invocation. |
1230 |
++ */ |
1231 |
++ return 0; |
1232 |
+ } |
1233 |
+ |
1234 |
+ out: |
1235 |
+@@ -448,15 +474,13 @@ out: |
1236 |
+ |
1237 |
+ kfree(file->private_data); |
1238 |
+ file->private_data = NULL; |
1239 |
++ /* 2 is a special value indicating that there are no more direntries */ |
1240 |
+ file->f_pos = 2; |
1241 |
+ return 0; |
1242 |
+ } |
1243 |
+ |
1244 |
+-/* If a directory is seeked, we have to free saved readdir() state */ |
1245 |
+ static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int whence) |
1246 |
+ { |
1247 |
+- kfree(file->private_data); |
1248 |
+- file->private_data = NULL; |
1249 |
+ return generic_file_llseek(file, offset, whence); |
1250 |
+ } |
1251 |
+ |
1252 |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c |
1253 |
index e18b988..f1d4ad0f 100644 |
1254 |
--- a/fs/ubifs/io.c |