[PATCH] powerpc64le: ROP changes for clone/clone3

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Fri Oct 11 11:49:41 GMT 2024



On 10/10/24 18:01, Peter Bergner wrote:
> On 10/9/24 2:37 PM, Adhemerval Zanella Netto wrote:
>> Do we really need ROP-mitigation on clone/clone3? The initial stack
>> frame is only created so the child can save its TOC (so the initial
>> thread function seems as a normal execution flow), and the LR won't
>> be used to return after the thread function returns (pthread_create
>> will issue exit).
> 
> I think you mean so the child can save its LR, since the LR is saved
> in the caller's stack frame.  If the child needs to save its TOC,
> then that is stored in the child's own frame.  But understood about
> why there is a parent frame.

Not really, I think my comment was confusing because I reference the
initial stack and code changes the svc issuing.  

What I really meant that the only reason we save/restore LR for svc is 
because it is volatile by the kernel ABI, so the ROP change is to
protect an eventual corruption by the *kernel*.  IMHO, if you think
kernel will possible corrupt the userland stack you have a bigger
problem, so I am not sure if this hardening is really helpful here.

> 
> Looking at the disassembly of __clone, I do see some bltlr+ and
> bnslr+ instructions following the restore the the LR, so it does
> seem to be used.  Maybe an error path?  So I don't think we can
> just remove the save/store of the LR altogether.  But you know this
> code better than I do though.
> 
> That said, in your commit c579f48edb "Remove cached PID/TID in clone",
> you removed the only use of r29, but you failed to remove the saving
> and restoring of r29 or the copy of r5 into r29.  That is serendipitous,
> as that leaves the non-volatile r29 free to use to save the LR across
> the scv instruction as Florian suggested, so ROP wouldn't be required
> at all.
> 
> clone3.S isn't as easy, since there is no saved/restored non-volatile
> reg already available, but we could add saving/restoring of r31 similar
> to clone.S and then use that to save/restore the LR.
> 
> Does the following untested patch to clone.S look correct to you?
> 
> I assume we don't care whether the kernel needs to use the same
> non-volatile register so it may save our LR value via the non-volatile
> reg on the kernel's stack frame, since that frame isn't accessible
> to user code to corrupt?
> 
> Peter
> 
> 
> 
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
> index 164311d2bd..e57cb6e82e 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
> @@ -56,7 +56,6 @@ ENTRY (__clone)
>  
>         /* Save fn, args, stack across syscall.  */
>         mr      r30,r3                  /* Function in r30.  */
> -       mr      r29,r5                  /* Flags in r29.  */
>         mr      r31,r6                  /* Argument in r31.  */
>  
>         /* 'flags' argument is first parameter to clone syscall.
> @@ -77,14 +76,12 @@ ENTRY (__clone)
>         CHECK_SCV_SUPPORT r28 0f
>         /* This is equivalent to DO_CALL_SCV, but we cannot use the macro here
>         because it uses CFI directives and we just called cfi_endproc.  */
> -       mflr    r9
> -       std     r9,FRAME_LR_SAVE(r1)
> +       mflr    r29
>         .machine "push"
>         .machine "power9"
>         scv     0
>         .machine "pop"
> -       ld      r9,FRAME_LR_SAVE(r1)
> -       mtlr    r9
> +       mtlr    r29
>  
>         /* Check for child process.  */
>         /* When using scv, error is indicated by negative r3.  */
> 
> 
> 
> 
> 



More information about the Libc-alpha mailing list