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)
Wed, Sep 25, 3:45 AM
Unknown Object (File)
Mon, Sep 23, 10:34 PM
Unknown Object (File)
Mon, Sep 23, 8:25 PM
Unknown Object (File)
Mon, Sep 16, 9:17 PM
Unknown Object (File)
Sat, Sep 7, 6:08 AM
Unknown Object (File)
Sat, Aug 31, 8:11 PM
Unknown Object (File)
Aug 25 2024, 2:41 AM
Unknown Object (File)
Aug 22 2024, 3:56 PM
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

Lint
Lint Skipped
Unit
Tests Skipped

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 ↗(On Diff #101612)

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.