Page MenuHomeFreeBSD

rtld-elf: Fix UB for direct exec with no extra rtld arguments
ClosedPublic

Authored by jrtc27 on Mon, May 5, 11:19 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, May 18, 6:36 AM
Unknown Object (File)
Sat, May 17, 4:12 PM
Unknown Object (File)
Tue, May 13, 7:06 AM
Unknown Object (File)
Mon, May 12, 5:27 PM
Unknown Object (File)
Sat, May 10, 7:46 AM
Unknown Object (File)
Thu, May 8, 5:41 AM
Unknown Object (File)
Wed, May 7, 5:09 PM
Unknown Object (File)
Wed, May 7, 3:22 AM
Subscribers

Details

Summary

If no extra rtld arguments are provided, rtld_argc will be 1 (for
argv[0] and so we are shifting the entire memory range down by a single
pointer. However, unlike argv and envp, auxp's entries are two pointers
in size, not one, and so in this case the source and destination
overlap, meaning simple assignment is UB (C99 6.5.16.1p3). On many
architectures this ends up being harmless as the compiler will emit
double machine word loads and stores, or if it splits them it may still
schedule them such that it works in this case, but our RISC-V baseline
does not include such instructions and LLVM ends up picking a schedule
that copies the second word before the first word, thereby replacing the
first word with a copy of the second word. This results in direct exec
mode segfaulting on RISC-V when given no arguments.

Fix this by using a temporary in the source and let the compiler safely
elide its use.

Fixes: 0fc65b0ab82c ("Make ld-elf.so.1 directly executable.")
MFC after: 1 week

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib added inline comments.
libexec/rtld-elf/rtld.c
676–681

I think the comment is too cryptic, why not say 'Use temporary since *auxpf and *auxp overlap if rtld_arch is 1'?

This revision is now accepted and ready to land.Tue, May 6, 9:45 PM
libexec/rtld-elf/rtld.c
676–681

I was terse to keep it single-line, but at this indentation level that was probably a bad idea. Will expand on committing.