linux/tools
Tiezhu Yang da5b2ad1c2 objtool: Handle frame pointer related instructions
After commit a0f7085f6a ("LoongArch: Add RANDOMIZE_KSTACK_OFFSET
support"), there are three new instructions "addi.d $fp, $sp, 32",
"sub.d $sp, $sp, $t0" and "addi.d $sp, $fp, -32" for the secondary
stack in do_syscall(), then there is a objtool warning "return with
modified stack frame" and no handle_syscall() which is the previous
frame of do_syscall() in the call trace when executing the command
"echo l > /proc/sysrq-trigger".

objdump shows something like this:

0000000000000000 <do_syscall>:
   0:   02ff8063        addi.d          $sp, $sp, -32
   4:   29c04076        st.d            $fp, $sp, 16
   8:   29c02077        st.d            $s0, $sp, 8
   c:   29c06061        st.d            $ra, $sp, 24
  10:   02c08076        addi.d          $fp, $sp, 32
  ...
  74:   0011b063        sub.d           $sp, $sp, $t0
  ...
  a8:   4c000181        jirl            $ra, $t0, 0
  ...
  dc:   02ff82c3        addi.d          $sp, $fp, -32
  e0:   28c06061        ld.d            $ra, $sp, 24
  e4:   28c04076        ld.d            $fp, $sp, 16
  e8:   28c02077        ld.d            $s0, $sp, 8
  ec:   02c08063        addi.d          $sp, $sp, 32
  f0:   4c000020        jirl            $zero, $ra, 0

The instruction "sub.d $sp, $sp, $t0" changes the stack bottom and the
new stack size is a random value, in order to find the return address of
do_syscall() which is stored in the original stack frame after executing
"jirl $ra, $t0, 0", it should use fp which points to the original stack
top.

At the beginning, the thought is tended to decode the secondary stack
instruction "sub.d $sp, $sp, $t0" and set it as a label, then check this
label for the two frame pointer instructions to change the cfa base and
cfa offset during the period of secondary stack in update_cfi_state().
This is valid for GCC but invalid for Clang due to there are different
secondary stack instructions for ClangBuiltLinux on LoongArch, something
like this:

0000000000000000 <do_syscall>:
  ...
  88:   00119064        sub.d           $a0, $sp, $a0
  8c:   00150083        or              $sp, $a0, $zero
  ...

Actually, it equals to a single instruction "sub.d $sp, $sp, $a0", but
there is no proper condition to check it as a label like GCC, and so the
beginning thought is not a good way.

Essentially, there are two special frame pointer instructions which are
"addi.d $fp, $sp, imm" and "addi.d $sp, $fp, imm", the first one points
fp to the original stack top and the second one restores the original
stack bottom from fp.

Based on the above analysis, in order to avoid adding an arch-specific
update_cfi_state(), we just add a member "frame_pointer" in the "struct
symbol" as a label to avoid affecting the current normal case, then set
it as true only if there is "addi.d $sp, $fp, imm". The last is to check
this label for the two frame pointer instructions to change the cfa base
and cfa offset in update_cfi_state().

Tested with the following two configs:
(1) CONFIG_RANDOMIZE_KSTACK_OFFSET=y &&
    CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=n
(2) CONFIG_RANDOMIZE_KSTACK_OFFSET=y &&
    CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y

By the way, there is no effect for x86 with this patch, tested on the
x86 machine with Fedora 40 system.

Cc: stable@vger.kernel.org # 6.9+
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-09-17 22:23:09 +08:00
..
accounting
arch tools/include: Sync arm64 headers with the kernel sources 2024-08-07 10:59:07 -07:00
bootconfig
bpf tools/resolve_btfids: Fix comparison of distinct pointer types warning in resolve_btfids 2024-07-22 16:35:30 +02:00
build Another perf tools fixes for v6.11 2024-07-30 19:22:41 -07:00
certs
cgroup
counter
crypto
debugging
firewire
firmware
gpio gpio: add sloppy logic analyzer using polling 2024-07-01 10:54:11 +02:00
hv tools: hv: rm .*.cmd when make clean 2024-09-05 07:23:08 +00:00
iio
include tools/include: Sync filesystem headers with the kernel sources 2024-08-07 10:59:07 -07:00
kvm/kvm_stat
laptop
leds
lib bitmap-6.11-rc1 2024-07-26 09:50:36 -07:00
memory-model kcsan: Add __data_racy documentation and module description 2024-07-15 15:44:40 -07:00
mm tools/mm: introduce a tool to assess swap entry allocation for thp_swapout 2024-07-10 12:14:51 -07:00
net/ynl tools/net/ynl: fix cli.py --subscribe feature 2024-09-05 14:56:45 -07:00
objtool objtool: Handle frame pointer related instructions 2024-09-17 22:23:09 +08:00
pci
pcmcia
perf perf daemon: Fix the build on more 32-bit architectures 2024-09-02 11:59:24 -07:00
power turbostat release 2024.07.26 2024-07-28 10:52:15 -07:00
rcu tools/rcu: Add rcu-updaters.sh script 2024-06-06 11:44:42 -07:00
scripts
sound
spi
testing There is a recently notified BT regression with no fix yet. I 2024-09-12 12:45:24 -07:00
thermal
time
tracing rtla/osnoise: Prevent NULL dereference in error handling 2024-08-09 13:03:15 -04:00
usb
verification tools/verification: Use pkg-config in lib_setup of Makefile.config 2024-07-17 13:14:51 -07:00
virtio tools/virtio: creating pipe assertion in vringh_test 2024-07-04 11:00:31 -04:00
wmi
workqueue
writeback
Makefile