dl-osinfo.h 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* Operating system specific code for generic dynamic loader functions. Linux.
  2. Copyright (C) 2000-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <dl-sysdep.h>
  16. #include <endian.h>
  17. #include <fcntl.h>
  18. #include <stdint.h>
  19. #include <not-cancel.h>
  20. #ifndef MIN
  21. # define MIN(a,b) (((a)<(b))?(a):(b))
  22. #endif
  23. #define DL_SYSDEP_OSCHECK(FATAL) \
  24. do { \
  25. /* Test whether the kernel is new enough. This test is only performed \
  26. if the library is not compiled to run on all kernels. */ \
  27. \
  28. int version = _dl_discover_osversion (); \
  29. if (__glibc_likely (version >= 0)) \
  30. { \
  31. if (__builtin_expect (GLRO(dl_osversion) == 0, 1) \
  32. || GLRO(dl_osversion) > version) \
  33. GLRO(dl_osversion) = version; \
  34. \
  35. /* Now we can test with the required version. */ \
  36. if (__LINUX_KERNEL_VERSION > 0 && version < __LINUX_KERNEL_VERSION) \
  37. /* Not sufficent. */ \
  38. FATAL ("FATAL: kernel too old\n"); \
  39. } \
  40. else if (__LINUX_KERNEL_VERSION > 0) \
  41. FATAL ("FATAL: cannot determine kernel version\n"); \
  42. } while (0)
  43. static inline uintptr_t __attribute__ ((always_inline))
  44. _dl_setup_stack_chk_guard (void *dl_random)
  45. {
  46. union
  47. {
  48. uintptr_t num;
  49. unsigned char bytes[sizeof (uintptr_t)];
  50. } ret;
  51. /* We need in the moment only 8 bytes on 32-bit platforms and 16
  52. bytes on 64-bit platforms. Therefore we can use the data
  53. directly and not use the kernel-provided data to seed a PRNG. */
  54. memcpy (ret.bytes, dl_random, sizeof (ret));
  55. #if BYTE_ORDER == LITTLE_ENDIAN
  56. ret.num &= ~(uintptr_t) 0xff;
  57. #elif BYTE_ORDER == BIG_ENDIAN
  58. ret.num &= ~((uintptr_t) 0xff << (8 * (sizeof (ret) - 1)));
  59. #else
  60. # error "BYTE_ORDER unknown"
  61. #endif
  62. return ret.num;
  63. }
  64. static inline uintptr_t __attribute__ ((always_inline))
  65. _dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard)
  66. {
  67. uintptr_t ret;
  68. memcpy (&ret, (char *) dl_random + sizeof (ret), sizeof (ret));
  69. return ret;
  70. }