lkml.org 
[lkml]   [2024]   [Feb]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH v8 33/38] kselftest/arm64: Add a GCS test program built with the system libc
    Date

    Mark Brown <broonie@kernel.org> writes:

    > There are things like threads which nolibc struggles with which we want
    > to add coverage for, and the ABI allows us to test most of these even if
    > libc itself does not understand GCS so add a test application built
    > using the system libc.
    >
    > Signed-off-by: Mark Brown <broonie@kernel.org>
    > ---
    > tools/testing/selftests/arm64/gcs/.gitignore | 1 +
    > tools/testing/selftests/arm64/gcs/Makefile | 4 +-
    > tools/testing/selftests/arm64/gcs/gcs-util.h | 10 +
    > tools/testing/selftests/arm64/gcs/libc-gcs.c | 736 +++++++++++++++++++++++++++
    > 4 files changed, 750 insertions(+), 1 deletion(-)

    In v7, several tests weren't running in my FVT VM for some reason.
    This time they do:

    $ ./run_kselftest.sh -t arm64:libc-gcs
    TAP version 13
    1..1
    # timeout set to 45
    # selftests: arm64: libc-gcs
    # TAP version 13
    # 1..118
    # # Starting 118 tests from 32 test cases.
    # # RUN global.can_call_function ...
    # # can_call_function: Test terminated unexpectedly by signal 11
    # # FAIL global.can_call_function
    # not ok 1 global.can_call_function
    # # RUN global.gcs_enabled_thread ...
    # # OK global.gcs_enabled_thread
    # ok 2 global.gcs_enabled_thread

    # # RUN invalid_mprotect.exec_bti.do_map_read ...
    # # Allocated stack from 0xffffb3aa9000-0xffffb3aaa000
    # # OK invalid_mprotect.exec_bti.do_map_read
    # ok 118 invalid_mprotect.exec_bti.do_map_read
    # # FAILED: 117 / 118 tests passed.
    # # Totals: pass:117 fail:1 xfail:0 xpass:0 skip:0 error:0
    not ok 1 selftests: arm64: libc-gcs # exit=1

    The only issue as can be seen above is that the can_call_function test
    is failing. The child is getting a GCS Segmentation fault when returning
    from fork().

    I tried debugging it with GDB, but I don't see what's wrong since the
    address in LR matches the first entry in GCSPR. Here is the
    debug session:

    (gdb) break libc-gcs.c:58
    Breakpoint 1 at 0x3894: file libc-gcs.c, line 58.
    (gdb) set follow-fork-mode child
    (gdb) r
    Starting program: /var/tmp/selftests/arm64/libc-gcs
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
    TAP version 13
    1..118
    # Starting 118 tests from 32 test cases.
    # RUN global.can_call_function ...
    [Attaching after Thread 0xfffff7ff7e80 (LWP 9164) fork to child process 9168]
    [New inferior 2 (process 9168)]
    [Detaching after fork from parent process 9164]
    [Inferior 1 (process 9164) detached]
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".

    Thread 2.1 "libc-gcs" received signal SIGSEGV, Segmentation fault
    Guarded Control Stack error.
    [Switching to Thread 0xfffff7ff7e80 (LWP 9168)]
    0x0000fffff7ec6fc0 [GCS error] in __GI__Fork () at ../sysdeps/nptl/_Fork.c:50
    warning: 50 ../sysdeps/nptl/_Fork.c: No such file or directory
    (gdb) bt
    #0 0x0000fffff7ec6fc0 [GCS error] in __GI__Fork () at ../sysdeps/nptl/_Fork.c:50
    #1 0x0000fffff7ec6be0 in __libc_fork () at ./posix/fork.c:73
    #2 0x0000aaaaaaaa49b8 in __run_test (f=f@entry=0xaaaaaaab98c8 <_fixture_global>,
    variant=variant@entry=0xffffffffefb8, t=t@entry=0xaaaaaaab81b0 <_can_call_function_object>)
    at /home/thiago.bauermann/src/linux/tools/testing/selftests/kselftest_harness.h:1128
    #3 0x0000aaaaaaaa2ac4 in test_harness_run (argv=0xfffffffff158, argc=1)
    at /home/thiago.bauermann/src/linux/tools/testing/selftests/kselftest_harness.h:1199
    #4 main (argc=1, argv=0xfffffffff158) at libc-gcs.c:735
    (gdb) p $gcspr
    $1 = (void *) 0xfffff7dfffe0
    (gdb) p/x $lr
    $3 = 0xfffff7ec6be0
    (gdb) p/x *(unsigned long *)$gcspr
    $5 = 0xfffff7ec6be0
    (gdb) disassemble
    Dump of assembler code for function __GI__Fork:
    0x0000fffff7ec6f70 <+0>: mrs x5, tpidr_el0
    0x0000fffff7ec6f74 <+4>: mov x0, #0x11 // #17
    0x0000fffff7ec6f78 <+8>: sub x6, x5, #0x7c0
    0x0000fffff7ec6f7c <+12>: sub x4, x5, #0x6f0
    0x0000fffff7ec6f80 <+16>: movk x0, #0x120, lsl #16
    0x0000fffff7ec6f84 <+20>: mov x1, #0x0 // #0
    0x0000fffff7ec6f88 <+24>: mov x2, #0x0 // #0
    0x0000fffff7ec6f8c <+28>: mov x3, #0x0 // #0
    0x0000fffff7ec6f90 <+32>: mov x8, #0xdc // #220
    0x0000fffff7ec6f94 <+36>: svc #0x0
    0x0000fffff7ec6f98 <+40>: cmn x0, #0x1, lsl #12
    0x0000fffff7ec6f9c <+44>: b.hi 0xfffff7ec6fc4 <__GI__Fork+84> // b.pmore
    0x0000fffff7ec6fa0 <+48>: mov w2, w0
    0x0000fffff7ec6fa4 <+52>: cbnz w0, 0xfffff7ec6fbc <__GI__Fork+76>
    0x0000fffff7ec6fa8 <+56>: sub x0, x5, #0x6e0
    0x0000fffff7ec6fac <+60>: mov x1, #0x18 // #24
    0x0000fffff7ec6fb0 <+64>: mov x8, #0x63 // #99
    0x0000fffff7ec6fb4 <+68>: stp x0, x0, [x6, #216]
    0x0000fffff7ec6fb8 <+72>: svc #0x0
    0x0000fffff7ec6fbc <+76>: mov w0, w2
    => 0x0000fffff7ec6fc0 <+80>: ret
    0x0000fffff7ec6fc4 <+84>: adrp x1, 0xfffff7faa000 <sys_siglist+424>
    0x0000fffff7ec6fc8 <+88>: ldr x1, [x1, #3528]
    0x0000fffff7ec6fcc <+92>: neg w0, w0
    0x0000fffff7ec6fd0 <+96>: mov w2, #0xffffffff // #-1
    0x0000fffff7ec6fd4 <+100>: str w0, [x5, x1]
    0x0000fffff7ec6fd8 <+104>: mov w0, w2
    0x0000fffff7ec6fdc <+108>: ret
    End of assembler dump.
    (gdb) p $w0
    $8 = 0
    (gdb) p $_siginfo.si_signo
    $12 = 11
    (gdb) p $_siginfo.si_code
    $13 = 10
    (gdb) p $_siginfo._sifields._sigfault.si_addr
    $14 = (void *) 0xfffff7ec6fc0 <__GI__Fork+80>

    --
    Thiago

    \
     
     \ /
      Last update: 2024-05-27 15:11    [W:2.454 / U:0.252 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site