> On Sep 11, 2020, at 4:51 PM, Segher Boessenkool <seg...@kernel.crashing.org>
> wrote:
>
> On Fri, Sep 11, 2020 at 04:29:16PM -0500, Qing Zhao wrote:
>>> On Sep 11, 2020, at 4:03 PM, Segher Boessenkool
>>> <seg...@kernel.crashing.org> wrote:
>>>> The parameters that are passed to sys call will be destroyed, therefore,
>>>> the attack will likely failed.
>>>
>>> But you do not need more than one non-zero argument for execv*, and that
>>> is usually the same register as the normal return value register; all
>>> other registers *should* be zero for a simple execv*("/bin/sh", ...)!
>>>
>>> (There is also the system call number register, rax on x86-64, but if
>>> overwriting that would be any effective, you could just do that one
>>> always and everywhere. This is only an effective defence if there are
>>> no gadgets that do the system call an attacker wants, and he has to
>>> construct that sequence himself; but it very effective and cheap then).
>>
>> In the above, do you mean only clearing “rax” on x86-64 should be effective
>> enough?
>
> (rax=0 is "read", you might want to do another value, but that's just
> details.)
>
> "This is only an effective defence if there are
> no gadgets that do the system call an attacker wants, and he has to
> construct that sequence himself; but it very effective and cheap then)."
>
> It is definitely *not* effective if there are gadgets that set rax to
> a value the attacker wants and then do a syscall.
You mean the following gadget:
Gadget 1:
mov rax, value
syscall
ret
Qing
> It of course is quite
> effective in breaking a ROP chain of (set rax) -> (syscall). How
> effective it is in practice, I have no idea.
>
> My point was that your proposed scheme does not protect the other
> syscall parameters very much either.
>
> And, hrm, rax is actually the first return value. On most ABIs the
> same registers are used for arguments and for return values, I got
> confused. Sorry. So this cannot be very effective for x86-64 no
> matter what.
>
>
> Segher