Bug 396887 - arch_prctl should return EINVAL on unknown option
Summary: arch_prctl should return EINVAL on unknown option
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL: https://bugzilla.redhat.com/show_bug....
Keywords:
: 397286 397393 397521 431829 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-07-26 17:23 UTC by Mark Wielaard
Modified: 2021-01-19 22:22 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2018-07-26 17:23:24 UTC
Currently arch_prctl calls VG_(core_panic) when it sees an unknown arch_prctl which kills the process. glibc uses arch_prctl with a (as yet) unknown option to see if the kernel supports CET. This breaks any application with:

valgrind: the 'impossible' happened:
   Unsupported arch_prctl option

host stacktrace:
==19934==    at 0x5803B102: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x5803B214: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x5803B459: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x5803B480: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x580CFD08: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x58096FFA: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x58093A72: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x58095206: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==19934==    by 0x580A4ACA: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 19934)
==19934==    at 0x121A15: get_cet_status (cpu-features.c:28)
==19934==    by 0x121A15: init_cpu_features (cpu-features.c:474)
==19934==    by 0x121A15: dl_platform_init (dl-machine.h:228)
==19934==    by 0x121A15: _dl_sysdep_start (dl-sysdep.c:231)
==19934==    by 0x10A1D7: _dl_start_final (rtld.c:413)
==19934==    by 0x10A1D7: _dl_start (rtld.c:520)
==19934==    by 0x109117: ??? (in /builddir/build/BUILD/glibc-2.27.9000-645-gcfba5dbb10/build-x86_64-redhat-linux/elf/ld.so)
==19934==    by 0x3: ???
==19934==    by 0x1FFF0009E6: ???
==19934==    by 0x1FFF0009F0: ???
==19934==    by 0x1FFF0009FF: ???
==19934==    by 0x1FFF000A10: ???

We already handle all known options. It would be better to do as the kernel does and just return failure with EINVAL instead.

Proposed patch:

diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
index 0f2ad8c51..407af7f76 100644
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
@@ -249,6 +249,7 @@ PRE(sys_rt_sigreturn)
 PRE(sys_arch_prctl)
 {
    ThreadState* tst;
+   Bool known_option = True;
    PRINT( "arch_prctl ( %ld, %lx )", SARG1, ARG2 );
 
    vg_assert(VG_(is_valid_tid)(tid));
@@ -283,13 +284,16 @@ PRE(sys_arch_prctl)
       POST_MEM_WRITE(ARG2, sizeof(unsigned long));
    }
    else {
-      VG_(core_panic)("Unsupported arch_prctl option");
+      known_option = False;
    }
 
    /* Note; the Status writeback to guest state that happens after
       this wrapper returns does not change guest_FS_CONST or guest_GS_CONST;
       hence that direct assignment to the guest state is safe here. */
-   SET_STATUS_Success( 0 );
+   if (known_option)
+      SET_STATUS_Success( 0 );
+   else
+      SET_STATUS_Failure( VKI_EINVAL );
 }
 
 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
Comment 1 Mark Wielaard 2018-07-30 10:25:54 UTC
commit 21a01b13e259b9a43f10f0046b2b3f409c11ea75
Author: Mark Wielaard <mark@klomp.org>
Date:   Mon Jul 30 12:20:16 2018 +0200

    Bug 396887 - arch_prctl should return EINVAL on unknown option.
    
    Currently arch_prctl calls VG_(core_panic) when it sees an unknown
    arch_prctl option which kills the process. glibc uses arch_prctl with
    an (as yet) unknown option to see if the kernel supports CET. This
    breaks any application running under valgrind on x86_64 with:
    
    valgrind: the 'impossible' happened:
       Unsupported arch_prctl option
    
    Thread 1: status = VgTs_Runnable (lwpid 19934)
    ==19934==    at 0x121A15: get_cet_status (cpu-features.c:28)
    ==19934==    by 0x121A15: init_cpu_features (cpu-features.c:474)
    ==19934==    by 0x121A15: dl_platform_init (dl-machine.h:228)
    ==19934==    by 0x121A15: _dl_sysdep_start (dl-sysdep.c:231)
    ==19934==    by 0x10A1D7: _dl_start_final (rtld.c:413)
    ==19934==    by 0x10A1D7: _dl_start (rtld.c:520)
    
    We already handle all known options. It would be better to do as the
    kernel does and just return failure with EINVAL instead.
Comment 2 Mark Wielaard 2018-08-08 19:46:12 UTC
*** Bug 397286 has been marked as a duplicate of this bug. ***
Comment 3 Tom Hughes 2018-08-16 13:44:06 UTC
*** Bug 397521 has been marked as a duplicate of this bug. ***
Comment 4 Tom Hughes 2018-08-16 13:44:39 UTC
*** Bug 397393 has been marked as a duplicate of this bug. ***
Comment 5 Tom Hughes 2021-01-19 22:22:08 UTC
*** Bug 431829 has been marked as a duplicate of this bug. ***