public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arjan van de Ven <arjanv@redhat.com>
To: Alan Cox <alan@redhat.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Ptrace hole / Linux 2.2.25
Date: 17 Mar 2003 18:57:21 +0100	[thread overview]
Message-ID: <1047923841.1600.3.camel@laptop.fenrus.com> (raw)
In-Reply-To: <200303171604.h2HG4Zc30291@devserv.devel.redhat.com>


[-- Attachment #1.1: Type: text/plain, Size: 849 bytes --]

On Mon, 2003-03-17 at 17:04, Alan Cox wrote:
> Vulnerability: CAN-2003-0127
> 
> The Linux 2.2 and Linux 2.4 kernels have a flaw in ptrace. This hole allows
> local users to obtain full privileges. Remote exploitation of this hole is
> not possible. Linux 2.5 is not believed to be vulnerable.
> 
> Linux 2.2.25 has been released to correct Linux 2.2. It contains no other
> changes. The bug fixes that would have been in 2.2.5pre1 will now appear in
> 2.2.26pre1. The patch will apply directly to most older 2.2 releases.
> 
> A patch for Linux 2.4.20/Linux 2.4.21pre is attached. The patch also
> subtly changes the PR_SET_DUMPABLE prctl. We believe this is neccessary and 
> that it will not affect any software. The functionality change is specific 
> to unusual debugging situations.

I've attached a patch against 2.4.21pre5 

[-- Attachment #1.2: ptrace.patch --]
[-- Type: text/x-patch, Size: 25066 bytes --]

diff -urN linux-2.4.21-pre5/arch/alpha/kernel/entry.S linux-2.4.21-pre5.ptrace/arch/alpha/kernel/entry.S
--- linux-2.4.21-pre5/arch/alpha/kernel/entry.S	2002-08-03 02:39:42.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/arch/alpha/kernel/entry.S	2003-03-17 18:52:52.000000000 +0100
@@ -231,12 +231,12 @@
 .end	kernel_clone
 
 /*
- * kernel_thread(fn, arg, clone_flags)
+ * arch_kernel_thread(fn, arg, clone_flags)
  */
 .align 3
 .globl	kernel_thread
 .ent	kernel_thread
-kernel_thread:
+arch_kernel_thread:
 	ldgp	$29,0($27)	/* we can be called from a module */
 	.frame $30, 4*8, $26
 	subq	$30,4*8,$30
diff -urN linux-2.4.21-pre5/arch/arm/kernel/process.c linux-2.4.21-pre5.ptrace/arch/arm/kernel/process.c
--- linux-2.4.21-pre5/arch/arm/kernel/process.c	2002-08-03 02:39:42.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/arch/arm/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -366,7 +366,7 @@
  * a system call from a "real" process, but the process memory space will
  * not be free'd until both the parent and the child have exited.
  */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
 	pid_t __ret;
 
diff -urN linux-2.4.21-pre5/arch/cris/kernel/entry.S linux-2.4.21-pre5.ptrace/arch/cris/kernel/entry.S
--- linux-2.4.21-pre5/arch/cris/kernel/entry.S	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/cris/kernel/entry.S	2003-03-17 18:52:52.000000000 +0100
@@ -739,12 +739,12 @@
  * the grosser the code, at least with the gcc version in cris-dist-1.13.
  */
 
-/* int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */
+/* int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */
 /*                   r10                r11         r12  */
 
 	.text
-	.global kernel_thread
-kernel_thread:
+	.global arch_kernel_thread
+arch_kernel_thread:
 
 	/* Save ARG for later.  */
 	move.d $r11, $r13
diff -urN linux-2.4.21-pre5/arch/i386/kernel/process.c linux-2.4.21-pre5.ptrace/arch/i386/kernel/process.c
--- linux-2.4.21-pre5/arch/i386/kernel/process.c	2002-08-03 02:39:42.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/arch/i386/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -485,7 +485,7 @@
 /*
  * Create a kernel thread
  */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	long retval, d0;
 
diff -urN linux-2.4.21-pre5/arch/ia64/kernel/process.c linux-2.4.21-pre5.ptrace/arch/ia64/kernel/process.c
--- linux-2.4.21-pre5/arch/ia64/kernel/process.c	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/ia64/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -230,7 +230,7 @@
  *	|                     | <-- sp (lowest addr)
  *	+---------------------+
  *
- * Note: if we get called through kernel_thread() then the memory
+ * Note: if we get called through arch_kernel_thread() then the memory
  * above "(highest addr)" is valid kernel stack memory that needs to
  * be copied as well.
  *
@@ -485,7 +485,7 @@
 }
 
 pid_t
-kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
+arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
 {
 	struct task_struct *parent = current;
 	int result, tid;
diff -urN linux-2.4.21-pre5/arch/m68k/kernel/process.c linux-2.4.21-pre5.ptrace/arch/m68k/kernel/process.c
--- linux-2.4.21-pre5/arch/m68k/kernel/process.c	2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/arch/m68k/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -124,7 +124,7 @@
 /*
  * Create a kernel thread
  */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	int pid;
 	mm_segment_t fs;
diff -urN linux-2.4.21-pre5/arch/mips/kernel/process.c linux-2.4.21-pre5.ptrace/arch/mips/kernel/process.c
--- linux-2.4.21-pre5/arch/mips/kernel/process.c	2002-11-29 00:53:10.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/mips/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -152,7 +152,7 @@
 /*
  * Create a kernel thread
  */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	long retval;
 
diff -urN linux-2.4.21-pre5/arch/mips64/kernel/process.c linux-2.4.21-pre5.ptrace/arch/mips64/kernel/process.c
--- linux-2.4.21-pre5/arch/mips64/kernel/process.c	2002-11-29 00:53:10.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/mips64/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -151,7 +151,7 @@
 /*
  * Create a kernel thread
  */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
 	int retval;
 
diff -urN linux-2.4.21-pre5/arch/parisc/kernel/process.c linux-2.4.21-pre5.ptrace/arch/parisc/kernel/process.c
--- linux-2.4.21-pre5/arch/parisc/kernel/process.c	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/parisc/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -169,7 +169,7 @@
  */
 
 extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
 
 	/*
diff -urN linux-2.4.21-pre5/arch/ppc/kernel/misc.S linux-2.4.21-pre5.ptrace/arch/ppc/kernel/misc.S
--- linux-2.4.21-pre5/arch/ppc/kernel/misc.S	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/ppc/kernel/misc.S	2003-03-17 18:52:52.000000000 +0100
@@ -899,9 +899,9 @@
 
 /*
  * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
+ *   arch_kernel_thread(fn, arg, flags)
  */
-_GLOBAL(kernel_thread)
+_GLOBAL(arch_kernel_thread)
 	mr	r6,r3		/* function */
 	ori	r3,r5,CLONE_VM	/* flags */
 	li	r0,__NR_clone
diff -urN linux-2.4.21-pre5/arch/ppc64/kernel/misc.S linux-2.4.21-pre5.ptrace/arch/ppc64/kernel/misc.S
--- linux-2.4.21-pre5/arch/ppc64/kernel/misc.S	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/ppc64/kernel/misc.S	2003-03-17 18:52:52.000000000 +0100
@@ -481,9 +481,9 @@
 
 /*
  * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
+ *   arch_kernel_thread(fn, arg, flags)
  */
-_GLOBAL(kernel_thread)
+_GLOBAL(arch_kernel_thread)
 	mr	r6,r3		/* function */
 	ori	r3,r5,CLONE_VM	/* flags */
 	li	r0,__NR_clone
diff -urN linux-2.4.21-pre5/arch/s390/kernel/process.c linux-2.4.21-pre5.ptrace/arch/s390/kernel/process.c
--- linux-2.4.21-pre5/arch/s390/kernel/process.c	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/s390/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -105,7 +105,7 @@
 		show_trace((unsigned long *) regs->gprs[15]);
 }
 
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
         int clone_arg = flags | CLONE_VM;
         int retval;
diff -urN linux-2.4.21-pre5/arch/s390x/kernel/process.c linux-2.4.21-pre5.ptrace/arch/s390x/kernel/process.c
--- linux-2.4.21-pre5/arch/s390x/kernel/process.c	2003-03-17 18:51:45.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/s390x/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -102,7 +102,7 @@
 		show_trace((unsigned long *) regs->gprs[15]);
 }
 
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
         int clone_arg = flags | CLONE_VM;
         int retval;
diff -urN linux-2.4.21-pre5/arch/sh/kernel/process.c linux-2.4.21-pre5.ptrace/arch/sh/kernel/process.c
--- linux-2.4.21-pre5/arch/sh/kernel/process.c	2001-10-15 22:36:48.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/arch/sh/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -118,7 +118,7 @@
  * This is the mechanism for creating a new kernel thread.
  *
  */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {	/* Don't use this in BL=1(cli).  Or else, CPU resets! */
 	register unsigned long __sc0 __asm__ ("r0");
 	register unsigned long __sc3 __asm__ ("r3") = __NR_clone;
diff -urN linux-2.4.21-pre5/arch/sparc/kernel/process.c linux-2.4.21-pre5.ptrace/arch/sparc/kernel/process.c
--- linux-2.4.21-pre5/arch/sparc/kernel/process.c	2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/arch/sparc/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -676,7 +676,7 @@
  * a system call from a "real" process, but the process memory space will
  * not be free'd until both the parent and the child have exited.
  */
-pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	long retval;
 
diff -urN linux-2.4.21-pre5/arch/sparc64/kernel/process.c linux-2.4.21-pre5.ptrace/arch/sparc64/kernel/process.c
--- linux-2.4.21-pre5/arch/sparc64/kernel/process.c	2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/arch/sparc64/kernel/process.c	2003-03-17 18:52:52.000000000 +0100
@@ -673,7 +673,7 @@
  * a system call from a "real" process, but the process memory space will
  * not be free'd until both the parent and the child have exited.
  */
-pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	long retval;
 
diff -urN linux-2.4.21-pre5/fs/exec.c linux-2.4.21-pre5.ptrace/fs/exec.c
--- linux-2.4.21-pre5/fs/exec.c	2003-03-17 18:52:03.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/fs/exec.c	2003-03-17 18:52:54.000000000 +0100
@@ -576,8 +576,10 @@
 
 	current->sas_ss_sp = current->sas_ss_size = 0;
 
-	if (current->euid == current->uid && current->egid == current->gid)
+	if (current->euid == current->uid && current->egid == current->gid) {
 		current->mm->dumpable = 1;
+		current->task_dumpable = 1;
+	}
 	name = bprm->filename;
 	for (i=0; (ch = *(name++)) != '\0';) {
 		if (ch == '/')
@@ -1085,7 +1087,7 @@
 	binfmt = current->binfmt;
 	if (!binfmt || !binfmt->core_dump)
 		goto fail;
-	if (!current->mm->dumpable)
+	if (!is_dumpable(current))
 		goto fail;
 	current->mm->dumpable = 0;
 	if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
diff -urN linux-2.4.21-pre5/include/asm-alpha/processor.h linux-2.4.21-pre5.ptrace/include/asm-alpha/processor.h
--- linux-2.4.21-pre5/include/asm-alpha/processor.h	2001-10-05 21:11:05.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-alpha/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -119,7 +119,7 @@
 extern void release_thread(struct task_struct *);
 
 /* Create a kernel thread without removing it from tasklists.  */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 #define copy_segments(tsk, mm)		do { } while (0)
 #define release_segments(mm)		do { } while (0)
diff -urN linux-2.4.21-pre5/include/asm-arm/processor.h linux-2.4.21-pre5.ptrace/include/asm-arm/processor.h
--- linux-2.4.21-pre5/include/asm-arm/processor.h	2002-08-03 02:39:45.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-arm/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -117,7 +117,7 @@
 /*
  * Create a new kernel thread
  */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 #endif
 
diff -urN linux-2.4.21-pre5/include/asm-cris/processor.h linux-2.4.21-pre5.ptrace/include/asm-cris/processor.h
--- linux-2.4.21-pre5/include/asm-cris/processor.h	2003-03-17 18:52:04.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-cris/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -81,7 +81,7 @@
 #define INIT_THREAD  { \
    0, 0, 0x20 }  /* ccr = int enable, nothing else */
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* give the thread a program location
  * set user-mode (The 'U' flag (User mode flag) is CCR/DCCR bit 8) 
diff -urN linux-2.4.21-pre5/include/asm-i386/processor.h linux-2.4.21-pre5.ptrace/include/asm-i386/processor.h
--- linux-2.4.21-pre5/include/asm-i386/processor.h	2002-08-03 02:39:45.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-i386/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -433,7 +433,7 @@
 /*
  * create a kernel thread without removing it from tasklists
  */
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
diff -urN linux-2.4.21-pre5/include/asm-ia64/processor.h linux-2.4.21-pre5.ptrace/include/asm-ia64/processor.h
--- linux-2.4.21-pre5/include/asm-ia64/processor.h	2003-03-17 18:52:05.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-ia64/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -372,7 +372,7 @@
  * do_basic_setup() and the timing is such that free_initmem() has
  * been called already.
  */
-extern int kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
+extern int arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(tsk, mm)			do { } while (0)
diff -urN linux-2.4.21-pre5/include/asm-m68k/processor.h linux-2.4.21-pre5.ptrace/include/asm-m68k/processor.h
--- linux-2.4.21-pre5/include/asm-m68k/processor.h	2001-10-05 21:11:05.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-m68k/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -105,7 +105,7 @@
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 #define copy_segments(tsk, mm)		do { } while (0)
 #define release_segments(mm)		do { } while (0)
diff -urN linux-2.4.21-pre5/include/asm-mips/processor.h linux-2.4.21-pre5.ptrace/include/asm-mips/processor.h
--- linux-2.4.21-pre5/include/asm-mips/processor.h	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-mips/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -188,7 +188,7 @@
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while(0)
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(p, mm) do { } while(0)
diff -urN linux-2.4.21-pre5/include/asm-mips64/processor.h linux-2.4.21-pre5.ptrace/include/asm-mips64/processor.h
--- linux-2.4.21-pre5/include/asm-mips64/processor.h	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-mips64/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -231,7 +231,7 @@
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while(0)
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(p, mm) do { } while(0)
diff -urN linux-2.4.21-pre5/include/asm-parisc/processor.h linux-2.4.21-pre5.ptrace/include/asm-parisc/processor.h
--- linux-2.4.21-pre5/include/asm-parisc/processor.h	2003-03-17 18:52:05.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-parisc/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -292,7 +292,7 @@
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm);
 
diff -urN linux-2.4.21-pre5/include/asm-ppc/processor.h linux-2.4.21-pre5.ptrace/include/asm-ppc/processor.h
--- linux-2.4.21-pre5/include/asm-ppc/processor.h	2003-03-17 18:52:05.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-ppc/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -622,7 +622,7 @@
 /*
  * Create a new kernel thread.
  */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 /*
  * Bus types
diff -urN linux-2.4.21-pre5/include/asm-ppc64/processor.h linux-2.4.21-pre5.ptrace/include/asm-ppc64/processor.h
--- linux-2.4.21-pre5/include/asm-ppc64/processor.h	2003-03-17 18:52:06.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-ppc64/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -602,7 +602,7 @@
 /*
  * Create a new kernel thread.
  */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 /*
  * Bus types
diff -urN linux-2.4.21-pre5/include/asm-s390/processor.h linux-2.4.21-pre5.ptrace/include/asm-s390/processor.h
--- linux-2.4.21-pre5/include/asm-s390/processor.h	2002-08-03 02:39:45.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-s390/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -113,7 +113,7 @@
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(nr, mm)           do { } while (0)
diff -urN linux-2.4.21-pre5/include/asm-s390x/processor.h linux-2.4.21-pre5.ptrace/include/asm-s390x/processor.h
--- linux-2.4.21-pre5/include/asm-s390x/processor.h	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/asm-s390x/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -128,7 +128,7 @@
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /* Copy and release all segment info associated with a VM */
 #define copy_segments(nr, mm)           do { } while (0)
diff -urN linux-2.4.21-pre5/include/asm-sh/processor.h linux-2.4.21-pre5.ptrace/include/asm-sh/processor.h
--- linux-2.4.21-pre5/include/asm-sh/processor.h	2001-10-05 21:11:05.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-sh/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -137,7 +137,7 @@
 /*
  * create a kernel thread without removing it from tasklists
  */
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /*
  * Bus types
diff -urN linux-2.4.21-pre5/include/asm-sparc/processor.h linux-2.4.21-pre5.ptrace/include/asm-sparc/processor.h
--- linux-2.4.21-pre5/include/asm-sparc/processor.h	2001-10-11 08:42:47.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-sparc/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -146,7 +146,7 @@
 
 /* Free all resources held by a thread. */
 #define release_thread(tsk)		do { } while(0)
-extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 
 #define copy_segments(tsk, mm)		do { } while (0)
diff -urN linux-2.4.21-pre5/include/asm-sparc64/processor.h linux-2.4.21-pre5.ptrace/include/asm-sparc64/processor.h
--- linux-2.4.21-pre5/include/asm-sparc64/processor.h	2002-08-03 02:39:45.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/include/asm-sparc64/processor.h	2003-03-17 18:52:58.000000000 +0100
@@ -270,7 +270,7 @@
 /* Free all resources held by a thread. */
 #define release_thread(tsk)		do { } while(0)
 
-extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 #define copy_segments(tsk, mm)		do { } while (0)
 #define release_segments(mm)		do { } while (0)
diff -urN linux-2.4.21-pre5/include/linux/sched.h linux-2.4.21-pre5.ptrace/include/linux/sched.h
--- linux-2.4.21-pre5/include/linux/sched.h	2003-03-17 18:52:08.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/include/linux/sched.h	2003-03-17 18:53:26.000000000 +0100
@@ -162,6 +162,7 @@
 extern void flush_scheduled_tasks(void);
 extern int start_context_thread(void);
 extern int current_is_keventd(void);
+extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 #if CONFIG_SMP
 extern void set_cpus_allowed(struct task_struct *p, unsigned long new_mask);
@@ -345,6 +346,7 @@
 	/* ??? */
 	unsigned long personality;
 	int did_exec:1;
+	unsigned task_dumpable:1;
 	pid_t pid;
 	pid_t pgrp;
 	pid_t tty_old_pgrp;
@@ -454,6 +456,8 @@
 #define PT_TRACESYSGOOD	0x00000008
 #define PT_PTRACE_CAP	0x00000010	/* ptracer can follow suid-exec */
 
+#define is_dumpable(tsk)	((tsk)->task_dumpable && (tsk)->mm->dumpable)
+
 /*
  * Limit the stack by to some sane default: root can always
  * increase this limit if needed..  8MB seems reasonable.
diff -urN linux-2.4.21-pre5/kernel/fork.c linux-2.4.21-pre5.ptrace/kernel/fork.c
--- linux-2.4.21-pre5/kernel/fork.c	2002-11-29 00:53:15.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/kernel/fork.c	2003-03-17 18:52:58.000000000 +0100
@@ -27,6 +27,7 @@
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+#include <asm/processor.h>
 
 /* The idle threads do not count.. */
 int nr_threads;
@@ -565,6 +566,31 @@
 	p->flags = new_flags;
 }
 
+long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	struct task_struct *task = current;
+	unsigned old_task_dumpable;
+	long ret;
+
+	/* lock out any potential ptracer */
+	task_lock(task);
+	if (task->ptrace) {
+		task_unlock(task);
+		return -EPERM;
+	}
+
+	old_task_dumpable = task->task_dumpable;
+	task->task_dumpable = 0;
+	task_unlock(task);
+
+	ret = arch_kernel_thread(fn, arg, flags);
+
+	/* never reached in child process, only in parent */
+	current->task_dumpable = old_task_dumpable;
+
+	return ret;
+}
+
 /*
  *  Ok, this is the main fork-routine. It copies the system process
  * information (task[nr]) and sets up the necessary registers. It also
diff -urN linux-2.4.21-pre5/kernel/ptrace.c linux-2.4.21-pre5.ptrace/kernel/ptrace.c
--- linux-2.4.21-pre5/kernel/ptrace.c	2002-08-03 02:39:46.000000000 +0200
+++ linux-2.4.21-pre5.ptrace/kernel/ptrace.c	2003-03-17 18:52:58.000000000 +0100
@@ -21,6 +21,10 @@
  */
 int ptrace_check_attach(struct task_struct *child, int kill)
 {
+	mb();
+	if (!is_dumpable(child))
+		return -EPERM;
+
 	if (!(child->ptrace & PT_PTRACED))
 		return -ESRCH;
 
@@ -70,7 +74,7 @@
  	    (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
 		goto bad;
 	rmb();
-	if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
+	if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE))
 		goto bad;
 	/* the same process cannot be attached many times */
 	if (task->ptrace & PT_PTRACED)
@@ -136,6 +140,8 @@
 	/* Worry about races with exit() */
 	task_lock(tsk);
 	mm = tsk->mm;
+	if (!is_dumpable(tsk) || (&init_mm == mm))
+		mm = NULL;
 	if (mm)
 		atomic_inc(&mm->mm_users);
 	task_unlock(tsk);
diff -urN linux-2.4.21-pre5/kernel/sys.c linux-2.4.21-pre5.ptrace/kernel/sys.c
--- linux-2.4.21-pre5/kernel/sys.c	2003-03-17 18:52:08.000000000 +0100
+++ linux-2.4.21-pre5.ptrace/kernel/sys.c	2003-03-17 18:52:58.000000000 +0100
@@ -1238,7 +1238,7 @@
 			error = put_user(current->pdeath_signal, (int *)arg2);
 			break;
 		case PR_GET_DUMPABLE:
-			if (current->mm->dumpable)
+			if (is_dumpable(current))
 				error = 1;
 			break;
 		case PR_SET_DUMPABLE:
@@ -1246,7 +1246,8 @@
 				error = -EINVAL;
 				break;
 			}
-			current->mm->dumpable = arg2;
+			if (is_dumpable(current))
+				current->mm->dumpable = arg2;
 			break;
 
 	        case PR_SET_UNALIGN:

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

  reply	other threads:[~2003-03-17 17:46 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-17 16:04 Ptrace hole / Linux 2.2.25 Alan Cox
2003-03-17 17:57 ` Arjan van de Ven [this message]
2003-03-17 18:20   ` Tomas Szepe
2003-03-17 18:23     ` James Bourne
2003-03-17 18:27     ` Jeff Garzik
2003-03-21 21:17       ` Pavel Machek
2003-03-23 10:00         ` Stephan von Krawczynski
2003-03-23 13:41           ` Jeff Garzik
2003-03-23 15:58             ` Petr Baudis
2003-03-23 19:25             ` Martin Mares
2003-03-23 19:30               ` Alan Cox
2003-03-23 19:34                 ` Martin Mares
2003-03-23 19:38                   ` Alan Cox
2003-03-23 19:44                     ` Martin Mares
2003-03-23 19:47                       ` Robert Love
2003-03-23 19:55                         ` Henrik Persson
2003-03-23 20:13                           ` Robert Love
2003-03-23 20:46                           ` Henrik Persson
2003-03-23 19:56                         ` Martin Mares
2003-03-23 20:08                           ` Russell King
2003-03-23 22:26                             ` Alan Cox
2003-03-23 20:10                           ` Robert Love
2003-03-23 20:30                             ` Martin J. Bligh
2003-03-23 20:36                               ` Pavel Machek
2003-03-23 21:20                                 ` Martin Hermanowski
2003-03-23 21:35                                 ` James Bourne
2003-03-23 21:53                                   ` Martin J. Bligh
2003-03-23 22:21                                     ` Jeff Garzik
2003-03-23 22:29                                       ` James Bourne
2003-03-23 22:57                                         ` Martin J. Bligh
2003-03-24  0:15                                           ` James Bourne
2003-03-23 22:43                                       ` Felipe Alfaro Solana
2003-03-23 22:54                                       ` Martin J. Bligh
2003-03-23 23:19                                         ` Alan Cox
2003-03-23 23:34                                           ` Martin J. Bligh
2003-03-24  3:35                                           ` Andrea Arcangeli
2003-03-24  3:54                                             ` Andrea Arcangeli
2003-03-24  6:56                                             ` Christoph Hellwig
2003-03-24 12:17                                             ` Alan Cox
2003-03-23 23:34                                         ` Jeff Garzik
2003-03-23 23:45                                           ` Martin J. Bligh
2003-03-24  0:07                                             ` J.A. Magallon
2003-03-24  6:52                                               ` Christoph Hellwig
2003-03-24  0:09                                             ` Christian Axelsson
2003-03-24 20:05                                         ` aradorlinux
2003-03-23 20:38                               ` Arjan van de Ven
2003-03-23 20:51                                 ` Martin J. Bligh
2003-03-24  0:51                                   ` Juan Quintela
2003-03-24  1:29                                     ` Brian Tinsley
2003-03-23 20:54                               ` Robert Love
2003-03-23 22:13                                 ` Martin J. Bligh
2003-03-23 21:51                               ` Jeff Garzik
2003-03-23 21:59                                 ` Martin J. Bligh
2003-03-23 22:14                                   ` Jeff Garzik
2003-03-23 22:46                                     ` Martin J. Bligh
2003-03-25 11:35                               ` Henning P. Schmiedehausen
2003-03-25 11:36                               ` Henning P. Schmiedehausen
2003-03-23 20:09                         ` Tomas Szepe
2003-03-23 20:21                           ` Robert Love
2003-03-23 20:49                           ` Jeff Garzik
2003-03-23 22:22                             ` Alan Cox
2003-03-23 21:56                       ` Jeff Garzik
2003-03-23 21:59                         ` Arjan van de Ven
2003-03-24 15:33                       ` jlnance
2003-03-23 19:53                     ` Jörn Engel
2003-03-24  0:08                       ` Sven Schuster
2003-03-24  0:20                         ` James Bourne
2003-03-24  0:37                           ` Sven Schuster
2003-03-24  0:50                             ` James Bourne
2003-03-24  0:39                           ` Jörn Engel
2003-03-24  2:54                             ` H. Peter Anvin
2003-03-24  2:57                               ` James Bourne
2003-03-24  2:59                                 ` H. Peter Anvin
2003-03-24 14:42                               ` Dave Jones
2003-03-27  7:47                                 ` Pavel Machek
2003-03-26 20:30                                   ` Dave Jones
2003-03-26 20:41                                     ` H. Peter Anvin
2003-03-26 21:02                                       ` Jörn Engel
2003-03-27  5:20                                       ` James Bourne
2003-03-23 19:41                   ` Tomas Szepe
2003-03-17 19:34     ` Alan Cox
2003-03-17 18:27       ` Tomas Szepe
2003-03-17 19:23         ` Neale Banks
2003-03-18 18:44           ` James Bourne
     [not found] <20030317161020$42ed@gated-at.bofh.it>
2003-03-17 18:39 ` Ben Pfaff
2003-03-18  1:46   ` Alan Cox
  -- strict thread matches above, loose matches on Subject: below --
2003-03-19 11:28 mlafon
2003-03-19 20:09 Matthew Grant
2003-03-19 21:34 ` Matthew Grant
     [not found] <20030323194012$6886@gated-at.bofh.it>
     [not found] ` <20030323194014$66c3@gated-at.bofh.it>
     [not found]   ` <20030323195010$5026@gated-at.bofh.it>
     [not found]     ` <20030323195012$6f30@gated-at.bofh.it>
     [not found]       ` <20030323200029$737b@gated-at.bofh.it>
     [not found]         ` <20030323202005$2a74@gated-at.bofh.it>
2003-03-23 20:33           ` Florian Weimer
2003-03-23 22:24             ` Alan Cox
2003-03-23 21:46               ` Florian Weimer
2003-03-23 23:05                 ` Alan Cox
     [not found]       ` <20030323200023$1a65@gated-at.bofh.it>
     [not found]         ` <20030323202014$096a@gated-at.bofh.it>
2003-03-23 20:35           ` Florian Weimer
2003-03-23 20:59             ` Robert Love
2003-03-23 22:38 Martin J. Bligh
2003-03-23 22:53 ` Jeff Garzik
2003-03-23 23:06   ` Martin J. Bligh
2003-03-24 10:30     ` Stephan von Krawczynski
2003-03-24 10:43       ` Christoph Hellwig
2003-03-24 15:40       ` Martin J. Bligh
2003-03-24 16:55         ` Stephan von Krawczynski
2003-03-27 14:47 Dr. Greg Wettstein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1047923841.1600.3.camel@laptop.fenrus.com \
    --to=arjanv@redhat.com \
    --cc=alan@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox