[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Tue, 24 Nov 2015 11:03:19 +0100
From: Florian Weimer <fweimer@...hat.com>
To: oss-security@...ts.openwall.com
Subject: Re: Instruction encoding which prevents execution of a
suffix

On 11/24/2015 03:11 AM, Josh Bressers wrote:

> If an attacker has full control (and in this case that should be the
> assumption), there's nothing you can do short of some sort of processor
> magic that doesn't exist today (that I'm aware of).
>
> What if you did the checks inside the kernel operation. Some sort of
> pre-shared secret of sorts to ensure the caller isn't new code.
>
> Of course this would require a kernel patch that I imagine wouldn't be a
> welcome change. Sometimes it's worth talking through problems like this
> with silly ideas though.

Indeed.  The silly idea I came up covers the special case where the
protected block ends in a system call.  It involves a pseudo-system call
defined with seccomp, which returns the cookie using SECCOMP_RET_ERRNO
and verifies it in the system call at the end of the block.  Or, in more
detail:

A partial solution is known for the case where the code sequence that
needs protection ends in a system call:
\begin{itemize}
\item At process startup, execute the following steps:
\begin{enumerate}
\item Find an unused system call number.
\item Using seccomp, install a system call filter for the unused
system call which returns the secret cookie via the
\verb|SECCOMP_RET_ERRNO| filter return value, after validating the
the program counter has the appropriate value (that is, it belongs
to the code sequence below).
\item Install a seccomp filter for the actual target system call (at
the end of the protected block) which checks the secret cookie and
the program counter (the latter has to match the code sequence
below).
\item Wipe the secret cookie and the generated seccomp programs from
memory.
\end{enumerate}
\item The protected block has to perform these steps:
\begin{enumerate}
system call identified at process startup.  Make sure that this
value stays in a register and is not spilled to the stack.
\item Perform the desired pre-condition checks.
\item Perform the original target system call, passing the cookie as
\item Clear the register in which the secret cookie value us start.
\end{enumerate}
\end{itemize}

However, this only works for system calls which have an unused
argument slot available.  The critical \texttt{mmap} system takes six
arguments, so this technique does not work there.  There is also a
potential race condition where the cookie value leaks to signal
handlers which interrupt the execution of the protected block or its
following system call.