--- linux-2.6.18.2/arch/alpha/kernel/asm-offsets.c 2006-02-15 13:54:10 +0100 +++ linux-2.6.18.2-vs2.1.1/arch/alpha/kernel/asm-offsets.c 2006-09-25 15:40:02 +0200 @@ -36,6 +36,7 @@ void foo(void) DEFINE(PT_PTRACED, PT_PTRACED); DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); + DEFINE(CLONE_KTHREAD, CLONE_KTHREAD); DEFINE(SIGCHLD, SIGCHLD); BLANK(); --- linux-2.6.18.2/arch/alpha/kernel/entry.S 2006-09-20 16:57:57 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/alpha/kernel/entry.S 2006-09-25 15:40:02 +0200 @@ -644,7 +644,7 @@ kernel_thread: stq $2, 152($sp) /* HAE */ /* Shuffle FLAGS to the front; add CLONE_VM. */ - ldi $1, CLONE_VM|CLONE_UNTRACED + ldi $1, CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD; or $18, $1, $16 bsr $26, sys_clone --- linux-2.6.18.2/arch/arm/kernel/process.c 2006-09-20 16:57:57 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/arm/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -459,7 +460,8 @@ pid_t kernel_thread(int (*fn)(void *), v regs.ARM_pc = (unsigned long)kernel_thread_helper; regs.ARM_cpsr = SVC_MODE; - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); --- linux-2.6.18.2/arch/arm26/kernel/process.c 2006-09-20 16:57:57 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/arm26/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -365,7 +365,8 @@ pid_t kernel_thread(int (*fn)(void *), v regs.ARM_r3 = (unsigned long)do_exit; regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26; - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); --- linux-2.6.18.2/arch/cris/arch-v10/kernel/process.c 2006-09-20 16:57:57 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/cris/arch-v10/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -103,7 +103,8 @@ int kernel_thread(int (*fn)(void *), voi regs.dccr = 1 << I_DCCR_BITNR; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } /* setup the child's kernel stack with a pt_regs and switch_stack on it. --- linux-2.6.18.2/arch/cris/arch-v32/kernel/process.c 2006-09-20 16:57:57 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/cris/arch-v32/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -120,7 +120,8 @@ kernel_thread(int (*fn)(void *), void * regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT); /* Create the new process. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } /* --- linux-2.6.18.2/arch/frv/kernel/kernel_thread.S 2005-03-02 12:38:20 +0100 +++ linux-2.6.18.2-vs2.1.1/arch/frv/kernel/kernel_thread.S 2006-09-25 15:40:02 +0200 @@ -13,6 +13,8 @@ #include #define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_KTHREAD 0x10000000 /* kernel thread */ +#define CLONE_KT (CLONE_VM | CLONE_KTHREAD) /* kernel thread flags */ #define KERN_ERR "<3>" .section .rodata --- linux-2.6.18.2/arch/frv/kernel/kernel_thread.S 2005-03-02 12:38:20 +0100 +++ linux-2.6.18.2-vs2.1.1/arch/frv/kernel/kernel_thread.S 2006-09-25 15:40:02 +0200 @@ -37,7 +39,7 @@ kernel_thread: # start by forking the current process, but with shared VM setlos.p #__NR_clone,gr7 ; syscall number - ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags] + ori gr10,#CLONE_KT,gr8 ; first syscall arg [clone_flags] sethi.p #0xe4e4,gr9 ; second syscall arg [newsp] setlo #0xe4e4,gr9 setlos.p #0,gr10 ; third syscall arg [parent_tidptr] --- linux-2.6.18.2/arch/h8300/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/h8300/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -134,7 +134,7 @@ int kernel_thread(int (*fn)(void *), voi fs = get_fs(); set_fs (KERNEL_DS); - clone_arg = flags | CLONE_VM; + clone_arg = flags | CLONE_VM | CLONE_KTHREAD; __asm__("mov.l sp,er3\n\t" "sub.l er2,er2\n\t" "mov.l %2,er1\n\t" --- linux-2.6.18.2/arch/i386/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/i386/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -350,7 +352,8 @@ int kernel_thread(int (*fn)(void *), voi regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); --- linux-2.6.18.2/arch/ia64/kernel/asm-offsets.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/ia64/kernel/asm-offsets.c 2006-09-25 15:40:02 +0200 @@ -191,6 +191,7 @@ void foo(void) /* for assembly files which can't include sched.h: */ DEFINE(IA64_CLONE_VFORK, CLONE_VFORK); DEFINE(IA64_CLONE_VM, CLONE_VM); + DEFINE(IA64_CLONE_KTHREAD, CLONE_KTHREAD); BLANK(); DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, --- linux-2.6.18.2/arch/ia64/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/ia64/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -690,7 +691,8 @@ kernel_thread (int (*fn)(void *), void * regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET; regs.sw.pr = (1 << PRED_KERNEL_STACK); - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s.pt, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); --- linux-2.6.18.2/arch/m32r/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/m32r/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -211,8 +211,8 @@ int kernel_thread(int (*fn)(void *), voi regs.psw = M32R_PSW_BIE; /* Ok, create the new process. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, - NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } /* --- linux-2.6.18.2/arch/m68k/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/m68k/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -159,7 +159,8 @@ int kernel_thread(int (*fn)(void *), voi { register long retval __asm__ ("d0"); - register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED; + register long clone_arg __asm__ ("d1") = + flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD; retval = __NR_clone; __asm__ __volatile__ --- linux-2.6.18.2/arch/m68knommu/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/m68knommu/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -122,7 +122,7 @@ void show_regs(struct pt_regs * regs) int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { int retval; - long clone_arg = flags | CLONE_VM; + long clone_arg = flags | CLONE_VM | CLONE_KTHREAD; mm_segment_t fs; fs = get_fs(); --- linux-2.6.18.2/arch/mips/kernel/process.c 2006-09-20 16:57:58 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/mips/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -270,7 +270,8 @@ long kernel_thread(int (*fn)(void *), vo #endif /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } static struct mips_frame_info { --- linux-2.6.18.2/arch/parisc/kernel/entry.S 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/parisc/kernel/entry.S 2006-09-25 15:40:02 +0200 @@ -764,6 +764,7 @@ fault_vector_11: #define CLONE_VM 0x100 /* Must agree with */ #define CLONE_UNTRACED 0x00800000 +#define CLONE_KTHREAD 0x10000000 .export __kernel_thread, code .import do_fork --- linux-2.6.18.2/arch/parisc/kernel/process.c 2006-06-18 04:52:15 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/parisc/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -173,7 +173,7 @@ pid_t kernel_thread(int (*fn)(void *), v * kernel_thread can become a #define. */ - return __kernel_thread(fn, arg, flags); + return __kernel_thread(fn, arg, flags | CLONE_KTHREAD); } EXPORT_SYMBOL(kernel_thread); --- linux-2.6.18.2/arch/powerpc/kernel/asm-offsets.c 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/powerpc/kernel/asm-offsets.c 2006-09-25 15:40:02 +0200 @@ -229,6 +229,7 @@ int main(void) DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); + DEFINE(CLONE_KTHREAD, CLONE_KTHREAD); #ifndef CONFIG_PPC64 DEFINE(MM_PGD, offsetof(struct mm_struct, pgd)); --- linux-2.6.18.2/arch/powerpc/kernel/misc_32.S 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/powerpc/kernel/misc_32.S 2006-09-25 15:40:02 +0200 @@ -823,7 +823,7 @@ _GLOBAL(kernel_thread) mr r30,r3 /* function */ mr r31,r4 /* argument */ ori r3,r5,CLONE_VM /* flags */ - oris r3,r3,CLONE_UNTRACED>>16 + oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16 li r4,0 /* new sp (unused) */ li r0,__NR_clone sc --- linux-2.6.18.2/arch/powerpc/kernel/misc_64.S 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/powerpc/kernel/misc_64.S 2006-09-25 15:40:02 +0200 @@ -472,7 +472,7 @@ _GLOBAL(kernel_thread) mr r29,r3 mr r30,r4 ori r3,r5,CLONE_VM /* flags */ - oris r3,r3,(CLONE_UNTRACED>>16) + oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16 li r4,0 /* new sp (unused) */ li r0,__NR_clone sc --- linux-2.6.18.2/arch/ppc/kernel/asm-offsets.c 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/ppc/kernel/asm-offsets.c 2006-09-25 15:40:02 +0200 @@ -121,6 +121,7 @@ main(void) DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); + DEFINE(CLONE_KTHREAD, CLONE_KTHREAD); DEFINE(MM_PGD, offsetof(struct mm_struct, pgd)); /* About the CPU features table */ --- linux-2.6.18.2/arch/ppc/kernel/misc.S 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/ppc/kernel/misc.S 2006-09-25 15:40:02 +0200 @@ -1010,7 +1010,7 @@ _GLOBAL(kernel_thread) mr r30,r3 /* function */ mr r31,r4 /* argument */ ori r3,r5,CLONE_VM /* flags */ - oris r3,r3,CLONE_UNTRACED>>16 + oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16 li r4,0 /* new sp (unused) */ li r0,__NR_clone sc --- linux-2.6.18.2/arch/s390/kernel/process.c 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/s390/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -197,7 +197,7 @@ int kernel_thread(int (*fn)(void *), voi regs.orig_gpr2 = -1; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, 0, ®s, 0, NULL, NULL); } --- linux-2.6.18.2/arch/sh/kernel/process.c 2006-11-04 19:43:22 +0100 +++ linux-2.6.18.2-vs2.1.1/arch/sh/kernel/process.c 2006-10-18 01:14:30 +0200 @@ -181,7 +182,8 @@ int kernel_thread(int (*fn)(void *), voi regs.sr = (1 << 30); /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, + 0, ®s, 0, NULL, NULL); } /* --- linux-2.6.18.2/arch/sh64/kernel/process.c 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/sh64/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -639,7 +639,7 @@ int kernel_thread(int (*fn)(void *), voi static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp) static __inline__ _syscall1(int,exit,int,ret) - reply = clone(flags | CLONE_VM, 0); + reply = clone(flags | CLONE_VM | CLONE_KTHREAD, 0); if (!reply) { /* Child */ reply = exit(fn(arg)); --- linux-2.6.18.2/arch/sparc/kernel/process.c 2006-09-20 16:58:01 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/sparc/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -705,7 +705,8 @@ pid_t kernel_thread(int (*fn)(void *), v /* Notreached by child. */ "1: mov %%o0, %0\n\t" : "=r" (retval) : - "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED), + "i" (__NR_clone), "r" (flags | + CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD), "i" (__NR_exit), "r" (fn), "r" (arg) : "g1", "g2", "g3", "o0", "o1", "memory", "cc"); return retval; --- linux-2.6.18.2/arch/sparc64/kernel/process.c 2006-09-20 16:58:06 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/sparc64/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -696,7 +696,8 @@ pid_t kernel_thread(int (*fn)(void *), v /* Notreached by child. */ "1:" : "=r" (retval) : - "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED), + "i" (__NR_clone), "r" (flags | + CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD), "i" (__NR_exit), "r" (fn), "r" (arg) : "g1", "g2", "g3", "o0", "o1", "memory", "cc"); return retval; --- linux-2.6.18.2/arch/um/kernel/process_kern.c 2006-06-18 04:52:38 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/um/kernel/process_kern.c 2006-11-03 00:38:37 +0100 @@ -95,7 +95,7 @@ int kernel_thread(int (*fn)(void *), voi current->thread.request.u.thread.proc = fn; current->thread.request.u.thread.arg = arg; - pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, + pid = do_fork(CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD | flags, 0, ¤t->thread.regs, 0, NULL, NULL); if(pid < 0) panic("do_fork failed in kernel_thread, errno = %d", pid); --- linux-2.6.18.2/arch/v850/kernel/process.c 2006-09-20 16:58:06 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/v850/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -83,7 +83,7 @@ int kernel_thread (int (*fn)(void *), vo /* Clone this thread. Note that we don't pass the clone syscall's second argument -- it's ignored for calls from kernel mode (the child's SP is always set to the top of the kernel stack). */ - arg0 = flags | CLONE_VM; + arg0 = flags | CLONE_VM | CLONE_KTHREAD; syscall = __NR_clone; asm volatile ("trap " SYSCALL_SHORT_TRAP : "=r" (ret), "=r" (syscall) --- linux-2.6.18.2/arch/x86_64/kernel/process.c 2006-09-20 16:58:06 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/x86_64/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -54,7 +54,8 @@ asmlinkage extern void ret_from_fork(void); -unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; +unsigned long kernel_thread_flags = + CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD; unsigned long boot_option_idle_override = 0; EXPORT_SYMBOL(boot_option_idle_override); --- linux-2.6.18.2/arch/xtensa/kernel/process.c 2006-09-20 16:58:06 +0200 +++ linux-2.6.18.2-vs2.1.1/arch/xtensa/kernel/process.c 2006-09-25 15:40:02 +0200 @@ -206,7 +206,7 @@ int kernel_thread(int (*fn)(void *), voi :"=r" (retval) :"i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), - "r" (flags | CLONE_VM) + "r" (flags | CLONE_VM | CLONE_KTHREAD) : "a2", "a3", "a4", "a5", "a6" ); return retval; } --- linux-2.6.18.2/include/linux/sched.h 2006-09-20 16:58:44 +0200 +++ linux-2.6.18.2-vs2.1.1/include/linux/sched.h 2006-10-06 23:09:03 +0200 @@ -24,6 +24,7 @@ #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ +#define CLONE_KTHREAD 0x10000000 /* clone a kernel thread */ /* * Scheduling policies --- linux-2.6.18.2/include/linux/sched.h 2006-09-20 16:58:44 +0200 +++ linux-2.6.18.2-vs2.1.1/include/linux/sched.h 2006-10-06 23:09:03 +0200 @@ -90,7 +92,7 @@ struct futex_pi_state; * List of flags we want to share for kernel threads, * if only because they are not used by them anyway. */ -#define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND) +#define CLONE_KERNEL (CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_KTHREAD) /* * These are the constant used to fake the fixed-point load-average --- linux-2.6.18.2/kernel/fork.c 2006-09-20 16:58:44 +0200 +++ linux-2.6.18.2-vs2.1.1/kernel/fork.c 2006-09-25 15:40:02 +0200 @@ -1349,6 +1396,15 @@ long do_fork(unsigned long clone_flags, if (!pid) return -EAGAIN; + + /* kernel threads are host only */ + if ((clone_flags & CLONE_KTHREAD) && !vx_check(0, VX_ADMIN)) { + vxwprintk(1, "xid=%d tried to spawn a kernel thread.", + vx_current_xid()); + free_pid(pid); + return -EPERM; + } + nr = pid->nr; if (unlikely(current->ptrace)) { trace = fork_traceflag (clone_flags);