This is an archive of the discontinued LLVM Phabricator instance.

[StackProtector] attribute __stack_chk_fail as NoReturn
ClosedPublic

Authored by nickdesaulniers on Mar 17 2023, 4:51 PM.

Details

Summary

When GCC added support for stack smashing protections, it was defined
that:

This hook returns a CALL_EXPR that alerts the runtime that the stack
protect guard variable has been modified. This expression should
involve a call to a noreturn function.
The default version of this hook invokes a function called
‘__stack_chk_fail’, taking no arguments.

Do so as well for __stack_smash_handler for OpenBSD.

Every libc implementation I could find has __stack_chk_fail marked
noreturn, or the implementation calls abort, exit, or panic (which
themselves are noreturn).

Glibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=debug/stack_chk_fail.c
Musl: https://git.musl-libc.org/cgit/musl/tree/src/env/__stack_chk_fail.c
Bionic: https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/bionic/__stack_chk_fail.cpp
FreeBSD: https://cgit.freebsd.org/src/tree/lib/libc/secure/stack_protector.c
OpenBSD: https://github.com/openbsd/src/blob/master/lib/libc/sys/stack_protector.c
NetBSD: https://github.com/NetBSD/src/blob/trunk/lib/libc/misc/stack_protector.c
Linux Kernel: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/panic.c
Apple: https://opensource.apple.com/source/Libc/Libc-1439.40.11/sys/OpenBSD/stack_protector.c.auto.html

Link: https://gcc.gnu.org/onlinedocs/gccint/Stack-Smashing-Protection.html#Stack-Smashing-Protection

This will later help us diagnose functions that fall through to other
functions vs end in calls to functions that are noreturn.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptMar 17 2023, 4:51 PM
nickdesaulniers requested review of this revision.Mar 17 2023, 4:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 17 2023, 4:51 PM
  • set SmallVector size to 1
This revision is now accepted and ready to land.Mar 20 2023, 12:04 PM
llvm/lib/CodeGen/StackProtector.cpp
637

@efriedma I wonder if we can avoid this unreachable? (maybe as a follow up commit to this)

I had tried it and a bunch of stack check related tests crashed; I didn't investigate, but suspect maybe some other code expects there to be an instruction after the call.

Or can you think of any reason why an unreachable needs to be added here? Is there something implicit about noreturn functions needing to be followed by unreachable in IR?

(even if the child patches don't land, D146339 alone is still probably worthwhile to land)

efriedma added inline comments.Mar 23 2023, 11:12 AM
llvm/lib/CodeGen/StackProtector.cpp
637

Every basic block must end in a terminator, and call isn't a terminator, so we have to put something after the call. "unreachable" is the terminator we use when we know control can't actually flow anywhere else in the function. Not sure what you'd want to replace it with.

Yes, this patch makes sense even without the other changes.