[v2.6] kernel: mishandling int80 fork from 64-bit tasks (CVE-2015-2830)
On unpatched x86_64 Linux with 32-bit emulation enabled, calling
fork(2) or close(2) using int $0x80 in a 64-bit task could return back
to user space in the new task using ret_from_sys_call. That’s
inappropriate for an int80 entry, and, if nothing else forced a
slow-path syscall return, the kernel would execute SYSRETL.
That would likely break the calling process, since it would incorrectly return in long mode (i.e. CS would have the wrong value). This particular failure has no security implications.
There’s another problem, though: setup_thread_stack would propagate TS_COMPAT (i.e. the indication that the task is in a 32-bit syscall) to the child, and nothing would clear that bit. This violates a general invariant that tasks executing in user mode never have TS_COMPAT set.
The user task could then do a normal 64-bit syscall, and
is_compat_task() would incorrectly return true. I don’t see any direct
way to escalate privileges as a result, but Ingo Molnar pointed
out that this affects syscall_get_arch. As a result, both seccomp and
audit could misinterpret the offending syscall, with possibly dangerous
results depending on configuration.
I suspect that this could be used to break out of certain seccomp sandboxes on kernels older than 3.16.
Reported by Andrew Lutomirski <luto () kernel org>
References:
http://seclists.org/oss-sec/2015/q2/19
CONFIRM: https://security-tracker.debian.org/tracker/CVE-2015-2830
CONFIRM:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=956421fbb74c3a6261903f3836c0740187cf038b
(from redmine: issue id 4050, created on 2015-04-07, closed on 2017-09-05)
- Relations:
- parent #4049