Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: d6a6f29475b0e9a8ff0d85b0b73b1c18b6c922ff
      
https://github.com/WebKit/WebKit/commit/d6a6f29475b0e9a8ff0d85b0b73b1c18b6c922ff
  Author: Dan Hecht <[email protected]>
  Date:   2025-06-09 (Mon, 09 Jun 2025)

  Changed paths:
    M Source/bmalloc/libpas/src/libpas/jit_heap_config.c
    M Source/bmalloc/libpas/src/libpas/pas_basic_heap_config_enumerator_data.c
    M Source/bmalloc/libpas/src/libpas/pas_enumerable_range_list.c
    M Source/bmalloc/libpas/src/libpas/pas_enumerate_bitfit_heaps.c
    M 
Source/bmalloc/libpas/src/libpas/pas_enumerate_initially_unaccounted_pages.c
    M Source/bmalloc/libpas/src/libpas/pas_enumerate_segregated_heaps.c
    M Source/bmalloc/libpas/src/libpas/pas_enumerator.c
    M Source/bmalloc/libpas/src/libpas/pas_enumerator.h
    M Source/bmalloc/libpas/src/libpas/pas_hashtable.h
    M Source/bmalloc/libpas/src/libpas/pas_heap_config_utils.c
    M Source/bmalloc/libpas/src/libpas/pas_lenient_compact_ptr_inlines.h
    M Source/bmalloc/libpas/src/test/EnumerationTests.cpp
    M Source/bmalloc/libpas/src/test/IsoHeapChaosTests.cpp

  Log Message:
  -----------
  [libpas] Enumerator should not assume remote mappings persist across calls to 
memory_reader_t
https://bugs.webkit.org/show_bug.cgi?id=294130
rdar://143300973

Reviewed by Yusuke Suzuki.

A tool that calls into the enumerator provides a memory_reader_t
callback to allow the enumerator to map the remote memory of the
target process. The address returned by the memory_reader_t callback is
guaranteed to persist only to the next call to the memory_reader_t
callback. This is documented in malloc.h.

The libpas enumerator was violating this by keeping addresses alive
across calls to the reader callback.

A few techniques are used to fix this:

1. The libpas compact heap (which is limited in size and stores
   libpas metadata) is copied into the local process, and pointers
   into the remote compact heap are translated to local pointers using
   pointer arithmetic. The only change here is to copy the compact
   heap during pas_enumerator_create(). The accessors generated by
   the compact pointer macros do not change.

2. The libpas enumerator creates a hashtable containing references to
   the local allocators. The local allocators live within the TLCs and
   the baseline allocator table, so these regions are also copied into
   the local process. Then the local allocators are accessed directly
   via hashtable lookups, as before.

3. Some other important "root" structures are copied during
   pas_enumerator_create and referenced directly by the pas_enumerator
   structure (this was mostly already done in 277271@main).

4. The final piece of metadata needed before recording objects is the
   page header, which are variable sized. Rather than deal with copying
   these variable sized structures, a pinning interface is used to
   ensure no other mapping (i.e. calls to the reader callback) is
   established while using this pointer.

5. The lenient compact pointer case is a weird case where the pointer
   may reference either the compact heap or bounce through the compact heap
   to another heap. This is used to store the fully alloc bits, which
   sometimes come from the local allocator and sometimes from the
   compact heap and are variable sized data structure.
   These are copied out into a special purpose resizable buffer when
   necessary. This code can be deleted if the partial view code is deleted.

6. All other remote address accesses (the common case) are handled by
   copying the remote scalar or structure into an automatic stack variable.
   i.e. the enumerator doesn't get direct access to the mapped address
   and thus no pointer lifetime issues can exist. This requires reworking
   e.g. list and hashtable traversals a bit so that pointer dereferencing
   occurs up front rather than between iterations (because the
   current iteration will make another call into the reader callback,
   potentially invalidating the mapping holding the "next" pointer).

Testing:
- The IsoHeapChaosTests provides good coverage of the enumerator code,
  but the reader implementation was caching all previous mappings.
  Changed the test reader to clobber all previously returned buffers
  to emulate the behavior that pointers returned by the reader can be
  invalidated by the next reader call.
- Run leaks and heap tools on WebContent with these changes and see that
  they work.

Canonical link: https://commits.webkit.org/296003@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to