[libc-commits] [libc] [libc] add getrandom vDSO symbol (PR #151630)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Wed Aug 6 06:32:35 PDT 2025


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/151630

>From f3df7ef178b1096d9876f9dbdb903a37034a179d Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 31 Jul 2025 23:07:08 -0400
Subject: [PATCH 1/2] [libc][arc4random 2/n] add getrandom vDSO symbol

---
 .../src/__support/OSUtil/linux/aarch64/vdso.h |  2 ++
 libc/src/__support/OSUtil/linux/vdso_sym.h    |  6 ++++-
 libc/src/__support/OSUtil/linux/x86_64/vdso.h |  2 ++
 .../src/__support/OSUtil/linux/vdso_test.cpp  | 24 +++++++++++++++++--
 4 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/aarch64/vdso.h b/libc/src/__support/OSUtil/linux/aarch64/vdso.h
index 3c4c6205071da..ee5777ad67f6d 100644
--- a/libc/src/__support/OSUtil/linux/aarch64/vdso.h
+++ b/libc/src/__support/OSUtil/linux/aarch64/vdso.h
@@ -23,6 +23,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) {
     return "__kernel_clock_gettime";
   case VDSOSym::ClockGetRes:
     return "__kernel_clock_getres";
+  case VDSOSym::GetRandom:
+    return "__kernel_getrandom";
   default:
     return "";
   }
diff --git a/libc/src/__support/OSUtil/linux/vdso_sym.h b/libc/src/__support/OSUtil/linux/vdso_sym.h
index 968e1536c4d27..01f0b72a4ed9c 100644
--- a/libc/src/__support/OSUtil/linux/vdso_sym.h
+++ b/libc/src/__support/OSUtil/linux/vdso_sym.h
@@ -35,7 +35,8 @@ enum class VDSOSym {
   RTSigReturn,
   FlushICache,
   RiscvHwProbe,
-  VDSOSymCount
+  GetRandom,
+  VDSOSymCount,
 };
 
 template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() {
@@ -60,6 +61,9 @@ template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() {
   else if constexpr (sym == VDSOSym::RiscvHwProbe)
     return static_cast<int (*)(riscv_hwprobe *, size_t, size_t, cpu_set_t *,
                                unsigned)>(nullptr);
+  else if constexpr (sym == VDSOSym::GetRandom)
+    return static_cast<int (*)(void *, size_t, unsigned int, void *, size_t)>(
+        nullptr);
   else
     return static_cast<void *>(nullptr);
 }
diff --git a/libc/src/__support/OSUtil/linux/x86_64/vdso.h b/libc/src/__support/OSUtil/linux/x86_64/vdso.h
index abe7c33e07cfa..f46fcb038f2e6 100644
--- a/libc/src/__support/OSUtil/linux/x86_64/vdso.h
+++ b/libc/src/__support/OSUtil/linux/x86_64/vdso.h
@@ -29,6 +29,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) {
     return "__vdso_time";
   case VDSOSym::ClockGetRes:
     return "__vdso_clock_getres";
+  case VDSOSym::GetRandom:
+    return "__vdso_getrandom";
   default:
     return "";
   }
diff --git a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
index 2f68470e8f678..e44d702899c71 100644
--- a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
+++ b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
@@ -110,8 +110,8 @@ TEST(LlvmLibcOSUtilVDSOTest, RtSigReturn) {
   using namespace testing::ErrnoSetterMatcher;
   // must use struct since there is a function of the same name in the same
   // scope.
-  struct sigaction sa {};
-  struct sigaction old_sa {};
+  struct sigaction sa{};
+  struct sigaction old_sa{};
   sa.sa_handler = sigprof_handler;
   sa.sa_flags = SA_RESTORER;
   vdso::TypedSymbol<vdso::VDSOSym::RTSigReturn> symbol;
@@ -158,4 +158,24 @@ TEST(LlvmLibcOSUtilVDSOTest, RiscvHwProbe) {
   }
 }
 
+TEST(LlvmLibcOSUtilVDSOTest, GetRandom) {
+  using namespace testing::ErrnoSetterMatcher;
+  vdso::TypedSymbol<vdso::VDSOSym::GetRandom> symbol;
+  if (!symbol)
+    return;
+  struct VGetrandomOpaqueParams {
+    uint32_t size_of_opaque_states;
+    uint32_t mmap_prot;
+    uint32_t mmap_flags;
+    uint32_t reserved[13];
+  };
+  VGetrandomOpaqueParams param{0, 0, 0, {}};
+  int res = symbol(
+      /*buf=*/nullptr, /*count=*/0, /*flags=*/0,
+      /*opaque_states=*/&param,
+      /*size_of_opaque_states=*/~0);
+  EXPECT_EQ(res, 0);
+  EXPECT_GT(param.size_of_opaque_states, 0u);
+}
+
 } // namespace LIBC_NAMESPACE_DECL

>From 0af9de2afc7ac1ada02391781df55d552dc68148 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 6 Aug 2025 09:32:20 -0400
Subject: [PATCH 2/2] address copilot suggestions partially

---
 libc/test/src/__support/OSUtil/linux/vdso_test.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
index e44d702899c71..71892a055daba 100644
--- a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
+++ b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
@@ -163,6 +163,8 @@ TEST(LlvmLibcOSUtilVDSOTest, GetRandom) {
   vdso::TypedSymbol<vdso::VDSOSym::GetRandom> symbol;
   if (!symbol)
     return;
+  // This structure exists in kernel UAPI header; but we define it on our own to
+  // make sure we can test it even on platform without support.
   struct VGetrandomOpaqueParams {
     uint32_t size_of_opaque_states;
     uint32_t mmap_prot;
@@ -170,10 +172,14 @@ TEST(LlvmLibcOSUtilVDSOTest, GetRandom) {
     uint32_t reserved[13];
   };
   VGetrandomOpaqueParams param{0, 0, 0, {}};
+  // When getrandom vDSO symbol is called with special parameters (~0 for state
+  // size), it populates the desired configuration into VGetrandomOpaqueParams.
   int res = symbol(
       /*buf=*/nullptr, /*count=*/0, /*flags=*/0,
       /*opaque_states=*/&param,
       /*size_of_opaque_states=*/~0);
+  // Test that the size of the states are correctly populated after a successful
+  // call.
   EXPECT_EQ(res, 0);
   EXPECT_GT(param.size_of_opaque_states, 0u);
 }



More information about the libc-commits mailing list