0003-libsanitizer-uclibc-sigset-size.patch 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. libsanitizer: __sanitizer_sigset_t for uClibc-ng matches kernel size
  2. libsanitizer assumes Linux sigset_t is glibc-sized (128 bytes / 1024
  3. bits). uClibc-ng deliberately keeps sigset_t the same size as the
  4. kernel sigset (8 bytes / 64 bits, except 16 bytes / 128 bits on MIPS)
  5. so its syscall wrappers can pass userspace sigset directly without
  6. translation. See libc/sysdeps/linux/common/bits/sigset.h.
  7. Without an override here, CHECK_TYPE_SIZE(sigset_t) and
  8. CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask) static asserts
  9. would fail. An earlier attempt bumped uClibc-ng's _SIGSET_NWORDS to
  10. the glibc value, which made the asserts pass at compile time but
  11. caused all sigaction()/sigprocmask() syscalls to return EINVAL at
  12. runtime, because the kernel rejects an over-sized sigsetsize argument
  13. ("runsvdir: Failed to ignore SIGCHLD: Invalid argument").
  14. Right thing: uClibc-ng's design is correct, libsanitizer just has to
  15. learn its actual layout. Add a SANITIZER_UCLIBC branch above the
  16. SANITIZER_LINUX fallback that produces the smaller sigset_t (16 bytes
  17. on MIPS, 8 bytes elsewhere).
  18. Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
  19. ---
  20. --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
  21. +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
  22. @@ -570,6 +570,19 @@
  23. # endif
  24. #elif SANITIZER_APPLE
  25. typedef unsigned __sanitizer_sigset_t;
  26. +#elif SANITIZER_UCLIBC
  27. +// uClibc-ng deliberately keeps sigset_t the same size as the kernel's
  28. +// sigset_t to avoid translation in syscall wrappers (see uClibc-ng
  29. +// libc/sysdeps/linux/common/bits/sigset.h). Mirror that size here so
  30. +// CHECK_TYPE_SIZE(sigset_t) and the sigaction sa_mask offset checks
  31. +// agree with the actual uClibc-ng layout.
  32. +struct __sanitizer_sigset_t {
  33. +# if defined(__mips__)
  34. + unsigned long val[128 / (sizeof(unsigned long) * 8)];
  35. +# else
  36. + unsigned long val[64 / (sizeof(unsigned long) * 8)];
  37. +# endif
  38. +};
  39. #elif SANITIZER_LINUX
  40. struct __sanitizer_sigset_t {
  41. // The size is determined by looking at sizeof of real sigset_t on linux.