[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