[libc-commits] [libc] [libc] Add secure_getenv implementation for Linux (PR #225013)

via libc-commits libc-commits at lists.llvm.org
Mon Sep 21 13:07:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Jeff Bailey (kaladron)

<details>
<summary>Changes</summary>

Add implementation of POSIX.1-2024 secure_getenv for Linux.

* Fullbuild mode only
* Query AT_SECURE from the auxiliary vector, failing closed if missing or non-zero.
* Add integration test verifying normal operation and secure execution mode behavior.

Assisted-by: Automated tooling, human reviewed.

---
Full diff: https://github.com/llvm/llvm-project/pull/225013.diff


10 Files Affected:

- (modified) libc/config/linux/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+1) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1) 
- (modified) libc/include/stdlib.yaml (+6) 
- (modified) libc/src/stdlib/CMakeLists.txt (+7) 
- (modified) libc/src/stdlib/linux/CMakeLists.txt (+14) 
- (added) libc/src/stdlib/linux/secure_getenv.cpp (+34) 
- (added) libc/src/stdlib/secure_getenv.h (+25) 
- (modified) libc/test/integration/src/stdlib/CMakeLists.txt (+16) 
- (added) libc/test/integration/src/stdlib/secure_getenv_test.cpp (+61) 


``````````diff
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f7b2c3059df43d..831b5f95f4761a 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1286,6 +1286,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.stdlib.exit
     libc.src.stdlib.getenv
     libc.src.stdlib.putenv
+    libc.src.stdlib.secure_getenv
     libc.src.stdlib.setenv
     libc.src.stdlib.system
     libc.src.stdlib.unsetenv
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 2cabbc7031f228..1a5bdce3e5ae24 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1471,6 +1471,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.stdlib.exit
     libc.src.stdlib.getenv
     libc.src.stdlib.putenv
+    libc.src.stdlib.secure_getenv
     libc.src.stdlib.setenv
     libc.src.stdlib.system
     libc.src.stdlib.unsetenv
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index bba74cf8907f90..5d5b236f392837 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1486,6 +1486,7 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.stdlib.exit
     libc.src.stdlib.getenv
     libc.src.stdlib.putenv
+    libc.src.stdlib.secure_getenv
     libc.src.stdlib.setenv
     libc.src.stdlib.unsetenv
     libc.src.stdlib.mbstowcs
diff --git a/libc/include/stdlib.yaml b/libc/include/stdlib.yaml
index eb0ca6ce42eef7..7f2c2f03b35ffd 100644
--- a/libc/include/stdlib.yaml
+++ b/libc/include/stdlib.yaml
@@ -248,6 +248,12 @@ functions:
     return_type: void
     arguments:
       - type: unsigned int
+  - name: secure_getenv
+    standards:
+      - posix
+    return_type: char *
+    arguments:
+      - type: const char *
   - name: setenv
     standards:
       - posix
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 45f27c6da36199..bbab9e4f535b3f 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -693,6 +693,13 @@ add_entrypoint_object(
     libc.src.__support.str_to_integer
 )
 
+add_entrypoint_object(
+  secure_getenv
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.secure_getenv
+)
+
 add_entrypoint_object(
   setenv
   ALIAS
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index a996d131fb580f..5295d024216b80 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -37,6 +37,20 @@ add_entrypoint_object(
     libc.src.string.memory_utils.inline_memcpy
 )
 
+add_entrypoint_object(
+  secure_getenv
+  SRCS
+    secure_getenv.cpp
+  HDRS
+    ../secure_getenv.h
+  DEPENDS
+    libc.hdr.sys_auxv_macros
+    libc.src.__support.OSUtil.linux.auxv
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.stdlib.environ_internal
+)
+
 add_entrypoint_object(
   setenv
   SRCS
diff --git a/libc/src/stdlib/linux/secure_getenv.cpp b/libc/src/stdlib/linux/secure_getenv.cpp
new file mode 100644
index 00000000000000..d631b7f6216252
--- /dev/null
+++ b/libc/src/stdlib/linux/secure_getenv.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of the POSIX secure_getenv function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/secure_getenv.h"
+#include "hdr/sys_auxv_macros.h"
+#include "src/__support/OSUtil/linux/auxv.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/stdlib/environ_internal.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(char *, secure_getenv, (const char *name)) {
+  if (name == nullptr || name[0] == '\0')
+    return nullptr;
+
+  // Fail closed if AT_SECURE is non-zero or missing from auxv.
+  if (auxv::get(AT_SECURE).value_or(1) != 0)
+    return nullptr;
+
+  return internal::EnvironmentManager::get_instance().get(name);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/secure_getenv.h b/libc/src/stdlib/secure_getenv.h
new file mode 100644
index 00000000000000..cf4365125e736b
--- /dev/null
+++ b/libc/src/stdlib/secure_getenv.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for secure_getenv.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_SECURE_GETENV_H
+#define LLVM_LIBC_SRC_STDLIB_SECURE_GETENV_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+char *secure_getenv(const char *name);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_SECURE_GETENV_H
diff --git a/libc/test/integration/src/stdlib/CMakeLists.txt b/libc/test/integration/src/stdlib/CMakeLists.txt
index db04fd05e6a281..7976e3833e282b 100644
--- a/libc/test/integration/src/stdlib/CMakeLists.txt
+++ b/libc/test/integration/src/stdlib/CMakeLists.txt
@@ -18,6 +18,22 @@ add_integration_test(
 )
 
 if(${LIBC_TARGET_OS} STREQUAL "linux")
+  add_integration_test(
+    secure_getenv_test
+    SUITE
+      stdlib-integration-tests
+    SRCS
+      secure_getenv_test.cpp
+    DEPENDS
+      libc.hdr.sys_auxv_macros
+      libc.src.__support.CPP.scope
+      libc.src.__support.OSUtil.linux.auxv
+      libc.src.stdlib.secure_getenv
+    ENV
+      FRANCE=Paris
+      GERMANY=Berlin
+  )
+
   add_integration_test(
     setenv_test
     SUITE
diff --git a/libc/test/integration/src/stdlib/secure_getenv_test.cpp b/libc/test/integration/src/stdlib/secure_getenv_test.cpp
new file mode 100644
index 00000000000000..18bf3a81da3c56
--- /dev/null
+++ b/libc/test/integration/src/stdlib/secure_getenv_test.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Integration test for secure_getenv.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/sys_auxv_macros.h"
+#include "src/__support/CPP/scope.h"
+#include "src/__support/OSUtil/linux/auxv.h"
+#include "src/stdlib/secure_getenv.h"
+
+#include "test/IntegrationTest/test.h"
+
+TEST_MAIN([[maybe_unused]] int argc, [[maybe_unused]] char **argv,
+          [[maybe_unused]] char **envp) {
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv(nullptr), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv(""), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("="), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("MISSING ENV VARIABLE"), nullptr);
+  EXPECT_NE(LIBC_NAMESPACE::secure_getenv("PATH"), nullptr);
+  EXPECT_STREQ(LIBC_NAMESPACE::secure_getenv("FRANCE"), "Paris");
+  EXPECT_STREQ(LIBC_NAMESPACE::secure_getenv("GERMANY"), "Berlin");
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("FRANC"), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("FRANCE1"), nullptr);
+
+  constexpr LIBC_NAMESPACE::auxv::Entry SECURE_AUXV[] = {
+      {AT_SECURE, 1},
+      {AT_NULL, AT_NULL},
+  };
+  constexpr LIBC_NAMESPACE::auxv::Entry NORMAL_AUXV[] = {
+      {AT_SECURE, 0},
+      {AT_NULL, AT_NULL},
+  };
+  constexpr LIBC_NAMESPACE::auxv::Entry EMPTY_AUXV[] = {
+      {AT_NULL, AT_NULL},
+  };
+
+  LIBC_NAMESPACE::auxv::Vector::initialize_unsafe(SECURE_AUXV);
+  LIBC_NAMESPACE::cpp::scope_exit restore_auxv(
+      [&] { LIBC_NAMESPACE::auxv::Vector::initialize_unsafe(NORMAL_AUXV); });
+
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("FRANCE"), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("GERMANY"), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("PATH"), nullptr);
+
+  LIBC_NAMESPACE::auxv::Vector::initialize_unsafe(EMPTY_AUXV);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("FRANCE"), nullptr);
+  EXPECT_EQ(LIBC_NAMESPACE::secure_getenv("PATH"), nullptr);
+
+  LIBC_NAMESPACE::auxv::Vector::initialize_unsafe(NORMAL_AUXV);
+  EXPECT_STREQ(LIBC_NAMESPACE::secure_getenv("FRANCE"), "Paris");
+
+  return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/225013


More information about the libc-commits mailing list