https://bugs.kde.org/show_bug.cgi?id=518370

            Bug ID: 518370
           Summary: Syscall attempting to access a madvise() guard page
                    protected pointer crashes valgrind
    Classification: Developer tools
           Product: valgrind
      Version First 3.27 GIT
       Reported In:
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: memcheck
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Created attachment 191163
  --> https://bugs.kde.org/attachment.cgi?id=191163&action=edit
reproducer program

Bug 514297 adds support for madvise() based guard pages to Valgrind.  With that
patch applied, syscalls accessing guarded pointers will crash valgrind.

The issue may be reproduced using the attache program.  It allocates memory
using mmap(), then installs a guard page on top of it, and finally it attempts
to access a pointer to the guarded region with openat().  Here's what happens:


> $ ./vg-in-place ./a.out 
> ==2736525== Memcheck, a memory error detector
> ==2736525== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
> ==2736525== Using Valgrind-3.27.0.GIT and LibVEX; rerun with -h for copyright 
> info
> ==2736525== Command: ./a.out
> ==2736525== 
> page size: 4096
> page aligned
> 0
> 
> page 0, guard region: 0, page present: 1
> page 1, guard region: 0, page present: 0
> page 2, guard region: 0, page present: 0
> 
> Installing guard page
> 
> page 0, guard region: 1, page present: 0
> page 1, guard region: 0, page present: 0
> page 2, guard region: 0, page present: 0
> 
> YYY addr: 485c000
> YYY  pid: 2736525
> --2736525-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) 
> - exiting
> --2736525-- si_code=1;  Faulting address: 0x485C000;  sp: 0x1002ee4c90
> 
> valgrind: the 'impossible' happened:
>    Killed by fatal signal
> 
> host stacktrace:
> ==2736525==    at 0x5800FFDD: mc_is_defined_asciiz (mc_main.c:4424)
> ==2736525==    by 0x5800FFDD: check_mem_is_defined_asciiz (mc_main.c:4502)
> ==2736525==    by 0x5811FD55: vgSysWrap_linux_sys_openat_before 
> (syswrap-linux.c:6356)
> ==2736525==    by 0x5809DF0A: vgPlain_client_syscall (syswrap-main.c:2400)
> ==2736525==    by 0x58099DDA: handle_syscall (scheduler.c:1214)
> ==2736525==    by 0x5809BC56: vgPlain_scheduler (scheduler.c:1588)
> ==2736525==    by 0x5810669A: thread_wrapper (syswrap-linux.c:102)
> ==2736525==    by 0x5810669A: run_a_thread_NORETURN (syswrap-linux.c:154)
> 
> sched status:
>   running_tid=1
> 
> Thread 1: status = VgTs_Runnable syscall 257 (lwpid 2736525)
> ==2736525==    at 0x495BFB6: open (open64.c:41)
> ==2736525==    by 0x400782: main (gp.c:83)
> client stack range: [0x1FFEFFD000 0x1FFF000FFF] client SP: 0x1FFEFFF2B0
> valgrind stack range: [0x1002DE7000 0x1002EE6FFF] top usage: 21184 of 1048576
> 
> 
> Note: see also the FAQ in the source distribution.
> It contains workarounds to several common problems.
> In particular, if Valgrind aborted or crashed after
> identifying problems in your program, there's a good chance
> that fixing those problems will prevent Valgrind aborting or
> crashing, especially if it happened in m_mallocfree.c.
> 
> If that doesn't help, please report this bug to: www.valgrind.org
> 
> In the bug report, send all the above text, the valgrind
> version, and what OS and version you are using.  Thanks.
> 
> $ 

The problem is that PRE_MEM_RASCIIZ( "openat(pathname)", ARG2 ); fails when the
guarded pointer access is attempted.  To work it around, one can call
PRE_MEM_RASCIIZ() after the argument passed ML_(safe_to_deref)() check.  That
gives the following workaround:

> $ git diff
> diff --git a/coregrind/m_syswrap/syswrap-linux.c 
> b/coregrind/m_syswrap/syswrap-linux.c
> index 6853e5e94..dfe1b528f 100644
> --- a/coregrind/m_syswrap/syswrap-linux.c
> +++ b/coregrind/m_syswrap/syswrap-linux.c
> @@ -6352,7 +6352,8 @@ PRE(sys_openat)
>                      int, dirfd, const char *, pathname, int, flags);
>     }
>  
> -   PRE_MEM_RASCIIZ( "openat(pathname)", ARG2 );
> +   if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ))
> +      PRE_MEM_RASCIIZ( "openat(pathname)", ARG2 );
>  
>     // check that we are not trying to open the client exe for writing
>     if ((ARG3 & VKI_O_WRONLY) ||
> $ 

The behavior is not specific to openta().  Any syscall will behave like this
with the current codebase.  This bug is about finding a solution to this
problem.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to