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

--- Comment #7 from Mark Wielaard <[email protected]> ---
(In reply to mcermak from comment #5)
> Created attachment 189206 [details]
> first experiment
> 
> Here is my first experiment that does not explode ;)  For me locally on
> kernel-6.17.1-300.fc43.x86_64 it catches the guard page then
> ML_(safe_to_deref)( (void*)(Addr)ARG1, 1)) returns false as expected.

Some (alightly random) notes:

- Not all kernels support proc pagemap and you might need permission to read
it.
  See https://www.man7.org/linux/man-pages/man5/proc_pid_pagemap.5.html
  What to do if it isn't available/accessible?
- Instead of using the pid we could probably just use "/proc/self/pagemap"
- We could keep the pagemap file open, or cache the results.
- For checking the guard page we can ignore the 'prot' argument, any access
r/w/e is not valid.
- Hardcodes page size to 4096 atm. How do we determine pagesize in other cases?
- What if len > page size?
- How to combine with nsegments?
  - Should a guard page be "inserted" into the segments with zero permissions
(possibly splitting the segment)?
  - Or should this pagemap check run when a nsegment is "/* ok */"? Aka,
segment is OK, but also part of a guard page?
  - So at least put this into its own function so that it can be invoked only
when necessary (is_in_guard_page (Addr a) maybe?)

- A different way to approach this would be to try to treat the guard pages as
if they were just segments.
  What happens if we do the following (untested) in POST(sys_madvise):

     if (ARG3 == VKI_MADV_GUARD_INSTALL) { // XXX Figure out MADV_GUARD_REMOVE
        Addr a    = ARG1;
        SizeT len = ARG2;
        Int  prot = VKI_PROT_NONE;
        ML_(notify_core_and_tool_of_mprotect)(a, len, prot);
     } 

>  My program (also attached) calls open(p, O_RDONLY), which my 
> glibc-2.42-5.fc43
> apparently turns into something like
> 
> lseek(3, 274505416616, SEEK_SET)        = 274505416616
> 
> where the second arg is an address that in this specific case is a start of
> a guard page.  But the patched is_valid_for() needs to work with arbitrary
> addresses, so before checking the magic guard page bit 58, it first finds
> the corresponding page for given address, and only after that it checks the
> guard page status.

I am not sure why the lseek is happening.
But yes getting the (aligned) page address first is the right thing to do.

Other tests to consider:
- Look at the memcheck/tests/descr_belowsp
- Create one for running under vgdb? As in the original bug #511717

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

Reply via email to