Page MenuHomeFreeBSD

arm64: Disable per-thread stack-smashing protection in data_abort()

Authored by markj on Nov 3 2022, 7:00 PM.
Referenced Files
Unknown Object (File)
Sun, Mar 5, 6:03 PM
Unknown Object (File)
Feb 18 2023, 7:08 AM
Unknown Object (File)
Jan 9 2023, 12:35 AM
Unknown Object (File)
Jan 8 2023, 5:04 PM
Unknown Object (File)
Dec 30 2022, 9:58 AM
Unknown Object (File)
Dec 14 2022, 2:53 AM



With PERTHREAD_SSP configured, SSP uses a per-thread canary value
instead of a global value. The value is stored in td->td_md.md_canary;
the sp_el0 register always contains a pointer to that value, and certain
functions selected by the compiler will store the canary value on the
stack as a part of the function prologue (and will verify the copy as
part of the epilogue). In particular, the thread structure may be

This happens to occur in data_abort(), which leads to the same problem
addressed by commit 2c10be9e06d4 ("arm64: Handle translation faults for
thread structures"). This patch fixes that directly, by disabling SSP
in data_abort() and a couple of related functions by using a function
attribute. It also moves the update of sp_el0 out of C code in case
the compiler decides to start checking the canary in pmap_switch()

A different solution might be to move the canary value to the PCB, which
currently lives on the kernel stack and isn't subject to the same
problem as thread structures. However, there isn't any particular
reason the PCB has to live on the stack today; on amd64 it is embedded
in struct thread, reintroducing the same problem. Keeping the reference
canary value at the top of the stack also seems a bit dubious since it
could be clobbered by a sufficiently large stack overflow.

A third solution could be to go back to the approach of commit
5aa5420ff2e8, and modify UMA to use the direct map for thread structures
even if KASAN is enabled. But transient promotions and demotions in the
direct map are possible too.

Since all of these options have shortcomings, I went with the most
straightforward one.

Diff Detail

rG FreeBSD src repository
Lint Not Applicable
Tests Not Applicable

Event Timeline

markj requested review of this revision.Nov 3 2022, 7:00 PM

Why does this need _KERNEL protection?

markj marked an inline comment as done.Nov 4 2022, 4:12 PM
markj added inline comments.

No real reason.

Note, gcc <= 10 does not have this attribute.

markj marked an inline comment as done.

Define __nostackprotector for !_KERNEL.


This is missing the #else case.


It looks like the gcc <= 10 spelling is __attribute__ ((__optimize__ ("-fno-stack-protector")))

Define NO_PERTHREAD_SSP in all cases.

Provide a fallback definition for __nostackprotect which works with older gcc.

This revision is now accepted and ready to land.Nov 4 2022, 5:22 PM