Page MenuHomeFreeBSD

compiler-rt: re-exec with ASLR disabled when necessary
ClosedPublic

Authored by emaste on Jan 18 2022, 10:37 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Nov 10, 6:01 AM
Unknown Object (File)
Tue, Nov 5, 7:18 PM
Unknown Object (File)
Oct 5 2024, 7:29 AM
Unknown Object (File)
Oct 4 2024, 11:05 AM
Unknown Object (File)
Oct 2 2024, 1:28 AM
Unknown Object (File)
Oct 2 2024, 1:00 AM
Unknown Object (File)
Oct 2 2024, 12:26 AM
Unknown Object (File)
Oct 1 2024, 5:03 AM
Subscribers

Details

Summary

Some sanitizers (at least msan) currently require ASLR to be disabled[1]. When we detect that ASLR is enabled, re-exec with it disabled rather than exiting with an error.

[1] https://github.com/llvm/llvm-project/issues/53256

(Note this change has not yet been submitted to llvm.)

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

emaste created this revision.
$ proccontrol -m aslr -s enable ./a.out
This sanitizer is not compatible with enabled ASLR and binaries compiled with PIE
ASLR will be disabled and the program re-executed.
==7749==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x10b0627 in main /home/emaste/src/samples/llvm/msan/umr2.cc:10:7
    #1 0x1052c61 in _start /usr/home/emaste/src/freebsd-git/laptop/lib/csu/amd64/crt1_c.c:75:7
    #2 0x8010d6007  (<unknown module>)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/emaste/src/samples/llvm/msan/umr2.cc:10:7 in main
Exiting
$ proccontrol -m aslr -s disable ./a.out
==7751==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x10b0627 in main /home/emaste/src/samples/llvm/msan/umr2.cc:10:7
    #1 0x1052c61 in _start /usr/home/emaste/src/freebsd-git/laptop/lib/csu/amd64/crt1_c.c:75:7
    #2 0x8010d6007  (<unknown module>)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/emaste/src/samples/llvm/msan/umr2.cc:10:7 in main
Exiting
contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
2201 ↗(On Diff #101612)

This is actually Die() in stock FreeBSD; I changed it to this Printf in my wip tree while investigating this.

contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
870–877

this is actually a part of llvm/lib/Support/Unix/Path.inc std::string getMainExecutable() which tries three different approaches:

  // On FreeBSD if the exec path specified in ELF auxiliary vectors is
  // preferred, if available.  /proc/curproc/file and the KERN_PROC_PATHNAME
  // sysctl may not return the desired path if there are multiple hardlinks
  // to the file.
  char exe_path[PATH_MAX];
#if __FreeBSD_version >= 1300057
  if (elf_aux_info(AT_EXECPATH, exe_path, sizeof(exe_path)) == 0) {
    char link_path[PATH_MAX];
    if (realpath(exe_path, link_path))
      return link_path;
  }
#else
  // elf_aux_info(AT_EXECPATH, ... is not available in all supported versions,
  // fall back to finding the ELF auxiliary vectors after the process's
  // environment.
  char **p = ::environ;
  while (*p++ != 0)
    ;
  // Iterate through auxiliary vectors for AT_EXECPATH.
  for (Elf_Auxinfo *aux = (Elf_Auxinfo *)p; aux->a_type != AT_NULL; aux++) {
    if (aux->a_type == AT_EXECPATH) {
      char link_path[PATH_MAX];
      if (realpath((char *)aux->a_un.a_ptr, link_path))
        return link_path;
    }
  }
#endif
  // Fall back to argv[0] if auxiliary vectors are not available.
  if (getprogpath(exe_path, argv0) != NULL)
    return exe_path;

I don't see a way to include this in sanitizers. I'm also unsure if we need one or both of the fallback cases.

This revision is now accepted and ready to land.Feb 4 2022, 4:14 PM
This revision was automatically updated to reflect the committed changes.