On 2024/3/5 17:32, Kees Cook wrote: > On Tue, Mar 05, 2024 at 11:31:06AM +0800, Jiangfeng Xiao wrote: >> >> >> On 2024/3/5 1:40, Kees Cook wrote: >>> On Mon, Mar 04, 2024 at 04:15:07PM +0100, Jann Horn wrote: >>>> On Mon, Mar 4, 2024 at 3:02 AM Jiangfeng Xiao <xiaojiangfeng@xxxxxxxxxx> wrote: >>>>> When the last instruction of a noreturn function is a call >>>>> to another function, the return address falls outside >>>>> of the function boundary. This seems to cause kernel >>>>> to interrupt the backtrace. >>> >>> FWIW, all email from huawei.com continues to get eaten by anti-spam >>> checking. I've reported this a few times -- it'd be really nice if the >>> domain configuration could get fixed. >>> >>>> [...] >>>>> Delete __noreturn from usercopy_abort, >>>> >>>> This sounds like the actual bug is in the backtracing logic? I don't >>>> think removing __noreturn annotations from an individual function is a >>>> good fix, since the same thing can happen with other __noreturn >>>> functions depending on what choices the compiler makes. >>> >>> Yeah, NAK. usercopy_abort() doesn't return. It ends with BUG(). >>> >> When the user directly or indirectly calls usercopy_abort, >> the final call stack is incorrect, and the >> code where the problem occurs cannot be located. >> In this case, the user will be frustrated. > > Can you please give an example of this? The main configurations of my kernel are as follows: CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is enabled. (This config uses the compilation parameter -O2.) CONFIG_RELOCATABLE is disabled. (This config uses the compilation option -fpic.) You can use the following kernel module testcase to reproduce this problem on the ARM32 platform. ``` #include <linux/module.h> #include <linux/sched.h> static volatile size_t unconst = 0; /* check_object_size __check_object_size check_kernel_text_object usercopy_abort("kernel text", ...) */ void test_usercopy_kernel(void) { check_object_size(schedule, unconst + PAGE_SIZE, 1); } static int __init test_usercopy_init(void) { test_usercopy_kernel(); return 0; } static void __exit test_usercopy_exit(void) { } module_init(test_usercopy_init); module_exit(test_usercopy_exit); MODULE_LICENSE("GPL"); ``` > >> For the usercopy_abort function, whether '__noreturn' is added >> does not affect the internal behavior of the usercopy_abort function. >> Therefore, it is recommended that '__noreturn' be deleted >> so that backtrace can work properly. > > This isn't acceptable. Removing __noreturn this will break > objtool's processing of execution flow for livepatching, IBT, and > KCFI instrumentation. These all depend on an accurate control flow > descriptions, and usercopy_abort is correctly marked __noreturn. > Thank you for providing this information. I'll go back to further understand how __noreturn is used in features such as KCFI and livepatching.