0007-seedrng-fix-getrandom-detection-for-non-glibc-libc.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. From b2d26d449ec855602b9a88f58c2eb675de0224f2 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be>
  3. Date: Tue, 18 Apr 2023 15:54:43 +0200
  4. Subject: [PATCH v4] seedrng: fix getrandom() detection for non-glibc libc
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. glibc <= 2.24 does not provide getrandom(). A check for it has been
  9. added in 200a9669fbf6f06894e4243cccc9fc11a1a6073a and fixed in
  10. cb57abb46f06f4ede8d9ccbdaac67377fdf416cf.
  11. However, building with a libc other than glibc can lead to the same
  12. problem as not every other libc has getrandom() either:
  13. - uClibc provides it from v1.0.2 onwards, but requires to define
  14. _GNU_SOURCE (all versions - we already define it by default), and
  15. stddef to be included first (when using uClibc < 1.0.35 - we already
  16. include it through libbb.h).
  17. - musl libc has getrandom(), but only from version 1.1.20 onwards. As
  18. musl does not provide __MUSL__ or version information, it's not
  19. possible to check for it like we did for glibc.
  20. All of this makes it difficult (or impossible in case of musl) to
  21. check what we need to do to have getrandom() based on each libc
  22. versions.
  23. On top of that, getrandom() is also not available on older kernels. As
  24. an example, when using a 3.10 kernel with uClibc 1.0.26, getrandom()
  25. is declared so compiling works, but it fails at link time because
  26. getrandom() is not defined.
  27. To make it easier, take a similar approach to what was done for the
  28. crypt library: try to build a sample program to see if we have
  29. getrandom(). To keep it compatible with different versions of
  30. make (for reference see [1]), a variable for '#' is also introduced.
  31. Based on the new Makefile variable, we now either use the
  32. libc-provided getrandom() when it's available, or use our own
  33. implementation when it's not (like it was the case already for glibc <
  34. 2.25).
  35. This should fix compiling with many libc/kernel combinations.
  36. [1]: https://git.savannah.gnu.org/cgit/make.git/commit/?id=c6966b323811c37acedff05b576b907b06aea5f4
  37. Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
  38. Upstream: http://lists.busybox.net/pipermail/busybox/2023-May/090317.html
  39. ---
  40. Changes v3 -> v4:
  41. - use a variable for '#' for compatibility with GNU make 4.2.1 and earlier.
  42. Changes v2 -> v3:
  43. - fix _GNU_SOURCE define location
  44. Changes v1 -> v2:
  45. - move _GNU_SOURCE to bb_libtest.c
  46. - remove GRND_NONBLOCK
  47. Note that I was not able to test every single combination, but I could
  48. confirm it builds successfully for:
  49. uClibc 10.0.24, linux headers 3.10 (libc getrandom NOT used)
  50. uClibc 1.0.36, linux headers 4.9 (libc getrandom used)
  51. musl 1.1.16, linux headers 4.12 (libc getrandom NOT used)
  52. musl 1.2.1, linux headers (libc getrandom used)
  53. glibc 2.25, linux headers 4.10 (libc getrandom used)
  54. Makefile.flags | 12 ++++++++++++
  55. miscutils/seedrng.c | 8 ++++----
  56. 2 files changed, 16 insertions(+), 4 deletions(-)
  57. diff --git a/Makefile.flags b/Makefile.flags
  58. index 1cec5ba20..0d437303a 100644
  59. --- a/Makefile.flags
  60. +++ b/Makefile.flags
  61. @@ -161,6 +161,18 @@ ifeq ($(RT_AVAILABLE),y)
  62. LDLIBS += rt
  63. endif
  64. +# GNU Make version 4.2.1 and earlier require number signs ('#')
  65. +# inside function invocations to be escaped, while versions 4.3+
  66. +# require them to be unescaped. Use a variable for it so that it works
  67. +# for both versions:
  68. +C := \#
  69. +# Not all libc versions have getrandom, so check for it:
  70. +HAVE_GETRANDOM := $(shell printf '$Cdefine _GNU_SOURCE\n$Cinclude <stddef.h>\n$Cinclude <sys/random.h>\nint main(void){char buf[256];\ngetrandom(buf,sizeof(buf),0);}' >bb_libtest.c; $(CC) $(CFLAGS) $(CFLAGS_busybox) -o /dev/null bb_libtest.c >/dev/null 2>&1 && echo "y"; rm bb_libtest.c)
  71. +
  72. +ifeq ($(HAVE_GETRANDOM),y)
  73. +CFLAGS += -DHAVE_GETRANDOM
  74. +endif
  75. +
  76. # libpam may use libpthread, libdl and/or libaudit.
  77. # On some platforms that requires an explicit -lpthread, -ldl, -laudit.
  78. # However, on *other platforms* it fails when some of those flags
  79. diff --git a/miscutils/seedrng.c b/miscutils/seedrng.c
  80. index 3bf6e2ea7..2f1e18c32 100644
  81. --- a/miscutils/seedrng.c
  82. +++ b/miscutils/seedrng.c
  83. @@ -44,8 +44,10 @@
  84. #include <linux/random.h>
  85. #include <sys/file.h>
  86. -/* Fix up glibc <= 2.24 not having getrandom() */
  87. -#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 24
  88. +/* Fix up some libc (e.g. glibc <= 2.24) not having getrandom() */
  89. +#if defined HAVE_GETRANDOM
  90. +#include <sys/random.h>
  91. +#else /* No getrandom */
  92. #include <sys/syscall.h>
  93. static ssize_t getrandom(void *buffer, size_t length, unsigned flags)
  94. {
  95. @@ -56,8 +58,6 @@ static ssize_t getrandom(void *buffer, size_t length, unsigned flags)
  96. return -1;
  97. # endif
  98. }
  99. -#else
  100. -#include <sys/random.h>
  101. #endif
  102. /* Apparently some headers don't ship with this yet. */
  103. --
  104. 2.39.1