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:Zheng Yejian <zhengyejian1@huawei.com>
Loading
Please sign in to comment