Re: [RFC] Potential bug in kernel_thread() on i386.

Linus Torvalds (torvalds@transmeta.com)
7 Oct 1998 18:54:14 GMT


In article <Pine.SUN.3.93.981006172055.1280A-100000@pascal.math.psu.edu>,
Alexander Viro <viro@math.psu.edu> wrote:
> Folks, there's something strange with kernel_thread() on i386.
>After reading old bug reports I've got a strong feeling that there is
>a race somewhere around fput() and while I was (still am) hunting for it
>I've stumbled across the request_module() and kernel_thread().
> First of all, I was under the impression that kernel_thread() is
>kosher only for pure kernel processes. Is that right? request_module() can
>be called from a system call (e.g. mount()), so...

It's kosher for anything that has no user space part, ie normally just
kernel threads. But even then it's actually ok to do an "execve()", as
that execve() will create the proper user context. This is what the
module thing does.

> Now, kernel_thread(fn,arg,flags) expands to the following
>(assuming that both flags and fn are constants):
>movl %edx,fn
>movl %eax,__NR_clone
>movl %ebx,flags | CLONE_VM
>movl %esp,%esi
>int $0x80
>cmpl %esp,%esi
>je 1f
>pushl arg
>call *%edx
>movl __NR_exit,%eax
>int $0x80
>1:
> But... WTF? clone has _two_ arguments, not one. I've looked
>through the sys_clone() and figured out that it takes the new stack
>pointer from %ecx.

It takes the new USER stack pointer from the second argument (ie %ecx,
as you correctly deduced).

Which means that for a kernel thread, %ecx is never used, because a
kernel thread does not have any user level stack.

(The kernel stack is always created as a separate stack, because all
threads need to have separate stacks in kernel space for very obvious
reasons).

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/