i386 WP bit problems

Colin Plumb (colin@nyx.net)
Tue, 29 Jul 97 17:13:36 MDT

Linus was speaking on the subject of the 1386's broken WP bit handling:
> The issue with kernel threads is that they share the same address space,
> which means that one thread can change the mapping of another thread in
> the middle of some operation.

> In particular, one thread can change the mapping of another thread in
> between that other thread testing the i386 WP bit by hand and actually
> writing to the page. It's a small window, and probably _very_ hard to
> actually take advantage of, but it's there.

As I recall, which may be imperfect, the i386 doesn't enforce the WP
(write protect) bit on the kernel, so if a system call passes a buffer
to the kernel to be filled in, the kernel has to check (in software)
that the user-level code is allowed to write to that location before
doing so.

There is a time window between the check being made and the write being
performed during which another thread in the same address space could
play some evil tricks and get the kernel to write over something it
shouldn't. You have to *try* to get this to happen; as Linus says,
normal software doesn't do things that cause this problem.

The problem is very strongly analagous to the security holes with setuid
root programs that write to files on behalf of a user, so check if the
user owns the destination file before writing to it. If you replace the
file with (say) a symlink to /etc/passwd in the moment between the check
and the write, you can overwrite /etc/passwd.

But now, a question:

It seems to me that this can't be a problem because there is no "time"
for another thread to do anything between the check and the write.
There are not multiprocessor 386's, and once in the kernel, there
is no preemption except on explicit calls to schedule() (or
sleep_on() or whatever eventually calls schedule()). And I think
most places in the kernel don't do that between the check and the write.

So where is the problem?