l2tp: Privilege escalation in ppp over l2tp sockets
The l2tp call-down to udp_prot.[gs]etsockopt() is entirely broken, as
reported by Sasha, since the socket in question isn't an ip socket, so
when the IP code does either
The 'sysret' fastpath does not correctly restore even all regular
registers, much less any segment registers or reflags values. That is
very much part of why it's faster than 'iret'.
Normally that isn't a problem, because the normal ptrace() interface
catches the process using the signal handler infrastructure, which
always returns with an iret.
However, some paths can get caught using ptrace_event() instead of the
signal path, and for those we need to make sure that we aren't going to
return to user space using 'sysret'. Otherwise the modifications that
may have been done to the register set by the tracer wouldn't
necessarily take effect.
Fix it by forcing IRET path by setting TIF_NOTIFY_RESUME from
arch_ptrace_stop_needed() which is invoked from ptrace_stop().
Don't allow ptrace to set RIP to a value that couldn't happen by
ordinary control flow. There are CPU bugs^Wfeatures that can have
interesting effects if RIP is non-canonical.
I didn't make the corresponding x86_32 change, since x86_32 has no
concept of canonical addresses.
putreg32 doesn't need this fix: value is only 32 bits, so it can't
be non-canonical.
Fixes CVE-2014-4699. There are arguably still bugs here, but this
fixes the major issue.
Signed-off-by: Andy Lutomirski <email address hidden>
CVE-2014-4699
BugLink: http://bugs.launchpad.net/bugs/1337339
Acked-by: Andy Whitcroft <email address hidden>
Signed-off-by: John Johansen <email address hidden>
Signed-off-by: Luis Henriques <email address hidden>