Commit 115ebd11 authored by Zheng Yejian's avatar Zheng Yejian
Browse files

livepatch/powerpc: Fix issue that miss one layer on stack checking

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BMC9


CVE: NA

--------------------------------

Suppose task 'T' is running in function 'B', and user is doing livepatch
for function 'A', and function 'A' is calling 'B'.

Then task 'T' will be interrupted by stop_machine, and suppose that 'B'
has not saved the link register (which point to address in 'A') into stack
memory, and data in link register position may be invalid, then 'A' would
be missed on stack checking.

To find a solution, we list following cases (suppose calling chain: P ->
A -> B, A runs `bl B`, 'nip' means instruction pointer found in interrupt
frame, 'lr' means link register found in interrupt frame, 'frame->pc'
means link register saved in first stack frame):
 1. 'nip' is in 'A', `bl B` is not executed, then: 'lr' is in 'P',
    'frame->pc' should be ignored;
 2. 'nip' is in some ppc64_stub or ppc32_plt which also not save link
     register, then: 'lr' is in 'A', 'frame->pc' should be ignored;
 3. 'nip' is in 'B', but 'B' has not saved link register, then: 'lr' is
    in 'A', 'frame->pc' should be ignored;
 4. 'nip' is in 'B', 'B' has saved link register, then: 'lr' is in 'A',
    'frame->pc' is also in 'A';
 5. 'nip' is in 'A', 'B' has returned but its stack pointer is not moved,
    then 'lr' is in 'A', 'frame->pc' is also in 'A';
 6. 'nip' is in 'A', 'B' has returned and its stack pointer is moved,
    then 'lr' is in 'A', 'frame->pc' is in 'P'.

As a conclusion, we need to:
  1. check 'nip' or 'lr' or both if they are not in same function;
  2. ignore 'frame->pc' if 'nip' and 'lr' are not in same function.

Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
parent c0386911
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment