oss-sec mailing list archives

CVE Request: Linux mishandles int80 fork from 64-bit tasks


From: Andrew Lutomirski <luto () kernel org>
Date: Wed, 1 Apr 2015 14:51:29 -0700

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.

The upstream fix is here:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=956421fbb74c3a6261903f3836c0740187cf038b

--Andy


Current thread: