The x86 denial of service bug
[Posted November 19, 2002 by corbet]
The current 2.5 and 2.4.20-rc releases both contain a patch for a
newly-discovered vulnerability in the Linux kernel. Simply put, anybody
who can run an arbitrary program on a Linux system can bring it down in flames.
Your editor, who is not an expert on x86 assembly (but who can still
describe the difference between CDC 6xxx A, B, and X registers), has made
an effort to figure out just what is going on here, for those who are
curious.
The x86 processor contains many flags which affect its operation. Two of
these flags are abused in this exploit:
- The trap flag (TF) causes a processor trap to happen after
execution of every instruction. It is used primarily for debugging
purposes.
- The nested task (NT) flag indicates that the current task is
executing via an interrupt (or other task-switching operation) that
causes another task to be suspended. It is part of the hardware task
switching mechanism, which Linux makes only limited use of. When the
NT flag is set, the iret instruction performs a hardware task
switch via the "backlink" field in the task state segment (TSS).
Without NT, iret looks much like a normal return.
The DOS attack works, essentially, by setting both flags (TF and NT), then
jumping into the kernel with an lcall instruction. The kernel
code did not clear those flags when entered via that path. Thus, the
setting of TF would cause an immediate processor trap within the kernel
code. That, by itself, is relatively harmless, except that the trap
handler returns via iret. That instruction, seeing that the NT
flag is set, attempts to perform a task switch via the TSS - an operation
the kernel was not expecting, and which had not been prepared for. So the
kernel switches into a nonexistent task, and everything comes to a stop.
It is at this point that one begins to appreciate the virtues of journaling
filesystems.
The solution, as coded up by
Linus, is simply to clear those flags when the kernel is entered via a call
gate. End of problem - once you get the patch installed.
The call entry code has not changed in a long time, so even very old
kernels are affected. The current 2.4.20 release candidate includes a fix,
and the distributors are beginning (slowly) to release updates which fix
the problem. 2.2 kernels are also vulnerable; if you have a 2.2-based
system running with untrusted users, you may want to rebuild the kernel
with this patch from Matthew Grant applied.
(
Log in to post comments)