1 Vulnerability: CAN-2003-0127
3 The Linux 2.2 and Linux 2.4 kernels have a flaw in ptrace. This hole allows
4 local users to obtain full privileges. Remote exploitation of this hole is
5 not possible. Linux 2.5 is not believed to be vulnerable.
7 Linux 2.2.25 has been released to correct Linux 2.2. It contains no other
8 changes. The bug fixes that would have been in 2.2.5pre1 will now appear in
9 2.2.26pre1. The patch will apply directly to most older 2.2 releases.
11 A patch for Linux 2.4.20/Linux 2.4.21pre is attached. The patch also
12 subtly changes the PR_SET_DUMPABLE prctl. We believe this is neccessary and
13 that it will not affect any software. The functionality change is specific
14 to unusual debugging situations.
16 We would like to thank Andrzej Szombierski who found the problem, and
17 wrote an initial patch. Seth Arnold cleaned up the 2.2 change. Arjan van
18 de Ven and Ben LaHaise identified additional problems with the original
23 diff -purN linux.orig/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
24 --- linux.orig/arch/alpha/kernel/entry.S Thu Mar 13 12:01:46 2003
25 +++ linux/arch/alpha/kernel/entry.S Thu Mar 13 13:28:49 2003
26 @@ -231,12 +231,12 @@ kernel_clone:
30 - * kernel_thread(fn, arg, clone_flags)
31 + * arch_kernel_thread(fn, arg, clone_flags)
38 ldgp $29,0($27) /* we can be called from a module */
41 diff -purN linux.orig/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
42 --- linux.orig/arch/arm/kernel/process.c Thu Mar 13 12:01:29 2003
43 +++ linux/arch/arm/kernel/process.c Thu Mar 13 13:25:56 2003
44 @@ -366,7 +366,7 @@ void dump_thread(struct pt_regs * regs,
45 * a system call from a "real" process, but the process memory space will
46 * not be free'd until both the parent and the child have exited.
48 -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
49 +pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
53 diff -purN linux.orig/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
54 --- linux.orig/arch/cris/kernel/entry.S Thu Mar 13 12:01:29 2003
55 +++ linux/arch/cris/kernel/entry.S Thu Mar 13 13:30:30 2003
56 @@ -736,12 +736,12 @@ hw_bp_trig_ptr:
57 * the grosser the code, at least with the gcc version in cris-dist-1.13.
60 -/* int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */
61 +/* int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */
65 - .global kernel_thread
67 + .global arch_kernel_thread
70 /* Save ARG for later. */
72 diff -purN linux.orig/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
73 --- linux.orig/arch/i386/kernel/process.c Thu Mar 13 12:01:57 2003
74 +++ linux/arch/i386/kernel/process.c Thu Mar 13 13:26:08 2003
75 @@ -495,7 +495,7 @@ void release_segments(struct mm_struct *
77 * Create a kernel thread
79 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
80 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
84 @@ -518,6 +518,7 @@ int kernel_thread(int (*fn)(void *), voi
86 "b" (flags | CLONE_VM)
92 diff -purN linux.orig/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
93 --- linux.orig/arch/ia64/kernel/process.c Thu Mar 13 12:01:29 2003
94 +++ linux/arch/ia64/kernel/process.c Thu Mar 13 13:26:15 2003
95 @@ -220,7 +220,7 @@ ia64_load_extra (struct task_struct *tas
96 * | | <-- sp (lowest addr)
97 * +---------------------+
99 - * Note: if we get called through kernel_thread() then the memory
100 + * Note: if we get called through arch_kernel_thread() then the memory
101 * above "(highest addr)" is valid kernel stack memory that needs to
104 @@ -469,7 +469,7 @@ ia64_set_personality (struct elf64_hdr *
108 -kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
109 +arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
111 struct task_struct *parent = current;
113 diff -purN linux.orig/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
114 --- linux.orig/arch/m68k/kernel/process.c Thu Mar 13 12:01:29 2003
115 +++ linux/arch/m68k/kernel/process.c Thu Mar 13 13:26:18 2003
116 @@ -124,7 +124,7 @@ void show_regs(struct pt_regs * regs)
118 * Create a kernel thread
120 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
121 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
125 diff -purN linux.orig/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
126 --- linux.orig/arch/mips/kernel/process.c Thu Mar 13 12:01:29 2003
127 +++ linux/arch/mips/kernel/process.c Thu Mar 13 13:26:28 2003
128 @@ -155,7 +155,7 @@ void dump_thread(struct pt_regs *regs, s
130 * Create a kernel thread
132 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
133 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
137 diff -purN linux.orig/arch/mips64/kernel/process.c linux/arch/mips64/kernel/process.c
138 --- linux.orig/arch/mips64/kernel/process.c Thu Mar 13 12:01:29 2003
139 +++ linux/arch/mips64/kernel/process.c Thu Mar 13 13:26:23 2003
140 @@ -152,7 +152,7 @@ void dump_thread(struct pt_regs *regs, s
142 * Create a kernel thread
144 -int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
145 +int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
149 diff -purN linux.orig/arch/parisc/kernel/process.c linux/arch/parisc/kernel/process.c
150 --- linux.orig/arch/parisc/kernel/process.c Fri Feb 9 14:29:44 2001
151 +++ linux/arch/parisc/kernel/process.c Thu Mar 13 13:26:36 2003
152 @@ -118,7 +118,7 @@ void machine_heartbeat(void)
155 extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
156 -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
157 +pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
161 diff -purN linux.orig/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
162 --- linux.orig/arch/ppc/kernel/misc.S Thu Mar 13 12:01:29 2003
163 +++ linux/arch/ppc/kernel/misc.S Thu Mar 13 13:32:21 2003
164 @@ -899,9 +899,9 @@ _GLOBAL(cvt_df)
167 * Create a kernel thread
168 - * kernel_thread(fn, arg, flags)
169 + * arch_kernel_thread(fn, arg, flags)
171 -_GLOBAL(kernel_thread)
172 +_GLOBAL(arch_kernel_thread)
173 mr r6,r3 /* function */
174 ori r3,r5,CLONE_VM /* flags */
176 diff -purN linux.orig/arch/ppc64/kernel/misc.S linux/arch/ppc64/kernel/misc.S
177 --- linux.orig/arch/ppc64/kernel/misc.S Thu Mar 13 12:01:30 2003
178 +++ linux/arch/ppc64/kernel/misc.S Thu Mar 13 13:29:42 2003
179 @@ -493,9 +493,9 @@ _GLOBAL(cvt_df)
182 * Create a kernel thread
183 - * kernel_thread(fn, arg, flags)
184 + * arch_kernel_thread(fn, arg, flags)
186 -_GLOBAL(kernel_thread)
187 +_GLOBAL(arch_kernel_thread)
188 mr r6,r3 /* function */
189 ori r3,r5,CLONE_VM /* flags */
191 diff -purN linux.orig/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
192 --- linux.orig/arch/s390/kernel/process.c Thu Mar 13 12:01:30 2003
193 +++ linux/arch/s390/kernel/process.c Thu Mar 13 13:26:43 2003
194 @@ -105,7 +105,7 @@ void show_regs(struct pt_regs *regs)
195 show_trace((unsigned long *) regs->gprs[15]);
198 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
199 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
201 int clone_arg = flags | CLONE_VM;
203 diff -purN linux.orig/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
204 --- linux.orig/arch/s390x/kernel/process.c Thu Mar 13 12:01:30 2003
205 +++ linux/arch/s390x/kernel/process.c Thu Mar 13 13:26:46 2003
206 @@ -102,7 +102,7 @@ void show_regs(struct pt_regs *regs)
207 show_trace((unsigned long *) regs->gprs[15]);
210 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
211 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
213 int clone_arg = flags | CLONE_VM;
215 diff -purN linux.orig/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
216 --- linux.orig/arch/sh/kernel/process.c Mon Oct 15 16:36:48 2001
217 +++ linux/arch/sh/kernel/process.c Thu Mar 13 13:26:49 2003
218 @@ -118,7 +118,7 @@ void free_task_struct(struct task_struct
219 * This is the mechanism for creating a new kernel thread.
222 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
223 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
224 { /* Don't use this in BL=1(cli). Or else, CPU resets! */
225 register unsigned long __sc0 __asm__ ("r0");
226 register unsigned long __sc3 __asm__ ("r3") = __NR_clone;
227 diff -purN linux.orig/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
228 --- linux.orig/arch/sparc/kernel/process.c Thu Mar 13 12:01:30 2003
229 +++ linux/arch/sparc/kernel/process.c Thu Mar 13 13:26:58 2003
230 @@ -676,7 +676,7 @@ out:
231 * a system call from a "real" process, but the process memory space will
232 * not be free'd until both the parent and the child have exited.
234 -pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
235 +pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
239 diff -purN linux.orig/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
240 --- linux.orig/arch/sparc64/kernel/process.c Thu Mar 13 12:01:30 2003
241 +++ linux/arch/sparc64/kernel/process.c Thu Mar 13 13:26:54 2003
242 @@ -658,7 +658,7 @@ int copy_thread(int nr, unsigned long cl
243 * a system call from a "real" process, but the process memory space will
244 * not be free'd until both the parent and the child have exited.
246 -pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
247 +pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
251 diff -purN linux.orig/arch/um/kernel/process_kern.c linux/arch/um/kernel/process_kern.c
252 --- linux.orig/arch/um/kernel/process_kern.c Thu Mar 13 12:01:48 2003
253 +++ linux/arch/um/kernel/process_kern.c Thu Mar 13 13:27:37 2003
254 @@ -171,14 +171,14 @@ static int new_thread_proc(void *stack)
255 os_usr1_process(os_getpid());
258 -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
259 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
263 current->thread.request.u.thread.proc = fn;
264 current->thread.request.u.thread.arg = arg;
265 pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
266 - if(pid < 0) panic("do_fork failed in kernel_thread");
267 + if(pid < 0) panic("do_fork failed in arch_kernel_thread");
271 diff -purN linux.orig/fs/exec.c linux/fs/exec.c
272 --- linux.orig/fs/exec.c Thu Mar 13 12:01:46 2003
273 +++ linux/fs/exec.c Thu Mar 13 14:19:08 2003
274 @@ -559,8 +559,10 @@ int flush_old_exec(struct linux_binprm *
276 current->sas_ss_sp = current->sas_ss_size = 0;
278 - if (current->euid == current->uid && current->egid == current->gid)
279 + if (current->euid == current->uid && current->egid == current->gid) {
280 current->mm->dumpable = 1;
281 + current->task_dumpable = 1;
283 name = bprm->filename;
284 for (i=0; (ch = *(name++)) != '\0';) {
286 @@ -952,7 +954,7 @@ int do_coredump(long signr, struct pt_re
287 binfmt = current->binfmt;
288 if (!binfmt || !binfmt->core_dump)
290 - if (!current->mm->dumpable)
291 + if (!is_dumpable(current))
293 current->mm->dumpable = 0;
294 if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
295 diff -purN linux.orig/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
296 --- linux.orig/include/asm-alpha/processor.h Fri Oct 5 15:11:05 2001
297 +++ linux/include/asm-alpha/processor.h Thu Mar 13 13:35:18 2003
298 @@ -119,7 +119,7 @@ struct task_struct;
299 extern void release_thread(struct task_struct *);
301 /* Create a kernel thread without removing it from tasklists. */
302 -extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
303 +extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
305 #define copy_segments(tsk, mm) do { } while (0)
306 #define release_segments(mm) do { } while (0)
307 diff -purN linux.orig/include/asm-arm/processor.h linux/include/asm-arm/processor.h
308 --- linux.orig/include/asm-arm/processor.h Thu Mar 13 12:01:35 2003
309 +++ linux/include/asm-arm/processor.h Thu Mar 13 13:35:18 2003
310 @@ -117,7 +117,7 @@ extern void __free_task_struct(struct ta
312 * Create a new kernel thread
314 -extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
315 +extern int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
319 diff -purN linux.orig/include/asm-cris/processor.h linux/include/asm-cris/processor.h
320 --- linux.orig/include/asm-cris/processor.h Thu Mar 13 12:01:35 2003
321 +++ linux/include/asm-cris/processor.h Thu Mar 13 13:35:18 2003
322 @@ -81,7 +81,7 @@ struct thread_struct {
323 #define INIT_THREAD { \
324 0, 0, 0x20 } /* ccr = int enable, nothing else */
326 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
327 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
329 /* give the thread a program location
330 * set user-mode (The 'U' flag (User mode flag) is CCR/DCCR bit 8)
331 diff -purN linux.orig/include/asm-i386/processor.h linux/include/asm-i386/processor.h
332 --- linux.orig/include/asm-i386/processor.h Thu Mar 13 12:01:57 2003
333 +++ linux/include/asm-i386/processor.h Thu Mar 13 13:51:02 2003
334 @@ -433,7 +433,7 @@ extern void release_thread(struct task_s
336 * create a kernel thread without removing it from tasklists
338 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
339 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
341 /* Copy and release all segment info associated with a VM */
342 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
343 diff -purN linux.orig/include/asm-ia64/processor.h linux/include/asm-ia64/processor.h
344 --- linux.orig/include/asm-ia64/processor.h Thu Mar 13 12:01:35 2003
345 +++ linux/include/asm-ia64/processor.h Thu Mar 13 13:35:18 2003
346 @@ -476,7 +476,7 @@ struct task_struct;
347 * do_basic_setup() and the timing is such that free_initmem() has
348 * been called already.
350 -extern int kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
351 +extern int arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
353 /* Copy and release all segment info associated with a VM */
354 #define copy_segments(tsk, mm) do { } while (0)
355 diff -purN linux.orig/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h
356 --- linux.orig/include/asm-m68k/processor.h Fri Oct 5 15:11:05 2001
357 +++ linux/include/asm-m68k/processor.h Thu Mar 13 13:35:18 2003
358 @@ -105,7 +105,7 @@ static inline void release_thread(struct
362 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
363 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
365 #define copy_segments(tsk, mm) do { } while (0)
366 #define release_segments(mm) do { } while (0)
367 diff -purN linux.orig/include/asm-mips/processor.h linux/include/asm-mips/processor.h
368 --- linux.orig/include/asm-mips/processor.h Thu Mar 13 12:01:36 2003
369 +++ linux/include/asm-mips/processor.h Thu Mar 13 13:35:18 2003
370 @@ -186,7 +186,7 @@ struct thread_struct {
371 /* Free all resources held by a thread. */
372 #define release_thread(thread) do { } while(0)
374 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
375 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
377 /* Copy and release all segment info associated with a VM */
378 #define copy_segments(p, mm) do { } while(0)
379 diff -purN linux.orig/include/asm-mips64/processor.h linux/include/asm-mips64/processor.h
380 --- linux.orig/include/asm-mips64/processor.h Thu Mar 13 12:01:36 2003
381 +++ linux/include/asm-mips64/processor.h Thu Mar 13 13:35:18 2003
382 @@ -245,7 +245,7 @@ struct thread_struct {
383 /* Free all resources held by a thread. */
384 #define release_thread(thread) do { } while(0)
386 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
387 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
389 /* Copy and release all segment info associated with a VM */
390 #define copy_segments(p, mm) do { } while(0)
391 diff -purN linux.orig/include/asm-parisc/processor.h linux/include/asm-parisc/processor.h
392 --- linux.orig/include/asm-parisc/processor.h Fri Oct 5 15:11:05 2001
393 +++ linux/include/asm-parisc/processor.h Thu Mar 13 13:35:18 2003
394 @@ -305,7 +305,7 @@ struct task_struct;
396 /* Free all resources held by a thread. */
397 extern void release_thread(struct task_struct *);
398 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
399 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
401 #define copy_segments(tsk, mm) do { } while (0)
402 #define release_segments(mm) do { } while (0)
403 diff -purN linux.orig/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
404 --- linux.orig/include/asm-ppc/processor.h Thu Mar 13 12:01:36 2003
405 +++ linux/include/asm-ppc/processor.h Thu Mar 13 13:35:18 2003
406 @@ -593,7 +593,7 @@ void release_thread(struct task_struct *
408 * Create a new kernel thread.
410 -extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
411 +extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
415 diff -purN linux.orig/include/asm-ppc64/processor.h linux/include/asm-ppc64/processor.h
416 --- linux.orig/include/asm-ppc64/processor.h Thu Mar 13 12:01:36 2003
417 +++ linux/include/asm-ppc64/processor.h Thu Mar 13 13:35:18 2003
418 @@ -609,7 +609,7 @@ void release_thread(struct task_struct *
420 * Create a new kernel thread.
422 -extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
423 +extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
427 diff -purN linux.orig/include/asm-s390/processor.h linux/include/asm-s390/processor.h
428 --- linux.orig/include/asm-s390/processor.h Thu Mar 13 12:01:36 2003
429 +++ linux/include/asm-s390/processor.h Thu Mar 13 13:35:18 2003
430 @@ -113,7 +113,7 @@ struct mm_struct;
432 /* Free all resources held by a thread. */
433 extern void release_thread(struct task_struct *);
434 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
435 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
437 /* Copy and release all segment info associated with a VM */
438 #define copy_segments(nr, mm) do { } while (0)
439 diff -purN linux.orig/include/asm-s390x/processor.h linux/include/asm-s390x/processor.h
440 --- linux.orig/include/asm-s390x/processor.h Thu Mar 13 12:01:36 2003
441 +++ linux/include/asm-s390x/processor.h Thu Mar 13 13:35:18 2003
442 @@ -127,7 +127,7 @@ struct mm_struct;
444 /* Free all resources held by a thread. */
445 extern void release_thread(struct task_struct *);
446 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
447 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
449 /* Copy and release all segment info associated with a VM */
450 #define copy_segments(nr, mm) do { } while (0)
451 diff -purN linux.orig/include/asm-sh/processor.h linux/include/asm-sh/processor.h
452 --- linux.orig/include/asm-sh/processor.h Fri Oct 5 15:11:05 2001
453 +++ linux/include/asm-sh/processor.h Thu Mar 13 13:35:18 2003
454 @@ -137,7 +137,7 @@ extern void release_thread(struct task_s
456 * create a kernel thread without removing it from tasklists
458 -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
459 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
463 diff -purN linux.orig/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
464 --- linux.orig/include/asm-sparc/processor.h Thu Oct 11 02:42:47 2001
465 +++ linux/include/asm-sparc/processor.h Thu Mar 13 13:35:18 2003
466 @@ -146,7 +146,7 @@ extern __inline__ void start_thread(stru
468 /* Free all resources held by a thread. */
469 #define release_thread(tsk) do { } while(0)
470 -extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
471 +extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
474 #define copy_segments(tsk, mm) do { } while (0)
475 diff -purN linux.orig/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h
476 --- linux.orig/include/asm-sparc64/processor.h Thu Mar 13 12:01:36 2003
477 +++ linux/include/asm-sparc64/processor.h Thu Mar 13 13:35:18 2003
478 @@ -270,7 +270,7 @@ do { \
479 /* Free all resources held by a thread. */
480 #define release_thread(tsk) do { } while(0)
482 -extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
483 +extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
485 #define copy_segments(tsk, mm) do { } while (0)
486 #define release_segments(mm) do { } while (0)
487 diff -purN linux.orig/include/linux/sched.h linux/include/linux/sched.h
488 --- linux.orig/include/linux/sched.h Thu Mar 13 12:01:57 2003
489 +++ linux/include/linux/sched.h Thu Mar 13 13:54:05 2003
490 @@ -362,6 +362,7 @@ struct task_struct {
492 unsigned long personality;
493 int did_exec:1, in_page_fault:1;
494 + unsigned task_dumpable:1;
498 @@ -485,6 +486,8 @@ struct task_struct {
499 #define PT_TRACESYSGOOD 0x00000008
500 #define PT_PTRACE_CAP 0x00000010 /* ptracer can follow suid-exec */
502 +#define is_dumpable(tsk) ((tsk)->task_dumpable && (tsk)->mm->dumpable)
505 * Limit the stack by to some sane default: root can always
506 * increase this limit if needed.. 8MB seems reasonable.
507 @@ -848,6 +851,8 @@ extern void FASTCALL(remove_wait_queue(w
509 extern void wait_task_inactive(task_t * p);
510 extern void kick_if_running(task_t * p);
511 +extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
514 #define __wait_event(wq, condition) \
516 diff -purN linux.orig/kernel/fork.c linux/kernel/fork.c
517 --- linux.orig/kernel/fork.c Thu Mar 13 12:01:57 2003
518 +++ linux/kernel/fork.c Thu Mar 13 13:51:24 2003
520 #include <asm/pgalloc.h>
521 #include <asm/uaccess.h>
522 #include <asm/mmu_context.h>
523 +#include <asm/processor.h>
525 /* The idle threads do not count.. */
527 @@ -575,6 +576,31 @@ static inline void copy_flags(unsigned l
528 p->flags = new_flags;
531 +long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
533 + struct task_struct *task = current;
534 + unsigned old_task_dumpable;
537 + /* lock out any potential ptracer */
539 + if (task->ptrace) {
544 + old_task_dumpable = task->task_dumpable;
545 + task->task_dumpable = 0;
548 + ret = arch_kernel_thread(fn, arg, flags);
550 + /* never reached in child process, only in parent */
551 + current->task_dumpable = old_task_dumpable;
557 * Ok, this is the main fork-routine. It copies the system process
558 * information (task[nr]) and sets up the necessary registers. It also
559 diff -purN linux.orig/kernel/ptrace.c linux/kernel/ptrace.c
560 --- linux.orig/kernel/ptrace.c Thu Mar 13 12:01:46 2003
561 +++ linux/kernel/ptrace.c Thu Mar 13 13:47:16 2003
564 int ptrace_check_attach(struct task_struct *child, int kill)
567 + if (!is_dumpable(child))
570 if (!(child->ptrace & PT_PTRACED))
573 @@ -57,7 +61,7 @@ int ptrace_attach(struct task_struct *ta
574 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
577 - if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
578 + if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE))
580 /* the same process cannot be attached many times */
581 if (task->ptrace & PT_PTRACED)
582 @@ -123,6 +127,8 @@ int access_process_vm(struct task_struct
583 /* Worry about races with exit() */
586 + if (!is_dumpable(tsk) || (&init_mm == mm))
589 atomic_inc(&mm->mm_users);
591 diff -purN linux.orig/kernel/sys.c linux/kernel/sys.c
592 --- linux.orig/kernel/sys.c Thu Mar 13 12:01:57 2003
593 +++ linux/kernel/sys.c Thu Mar 13 13:41:25 2003
594 @@ -1286,7 +1286,7 @@ asmlinkage long sys_prctl(int option, un
595 error = put_user(current->pdeath_signal, (int *)arg2);
597 case PR_GET_DUMPABLE:
598 - if (current->mm->dumpable)
599 + if (is_dumpable(current))
602 case PR_SET_DUMPABLE:
603 @@ -1294,7 +1294,8 @@ asmlinkage long sys_prctl(int option, un
607 - current->mm->dumpable = arg2;
608 + if (is_dumpable(current))
609 + current->mm->dumpable = arg2;
612 #ifdef SET_UNALIGN_CTL
614 To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
615 the body of a message to majordomo@vger.kernel.org
616 More majordomo info at http://vger.kernel.org/majordomo-info.html
617 Please read the FAQ at http://www.tux.org/lkml/