[libc-commits] [libc] bf06603 - [libc] Implement setresuid and setresgid in unistd (#234837)
via libc-commits
libc-commits at lists.llvm.org
Fri Oct 23 02:25:21 PDT 2026
Author: Aman Maurya
Date: 2026-10-23T14:55:16+05:30
New Revision: bf0660387fd17e3765d10c3820e68be8554cd7f5
URL: https://github.com/llvm/llvm-project/commit/bf0660387fd17e3765d10c3820e68be8554cd7f5
DIFF: https://github.com/llvm/llvm-project/commit/bf0660387fd17e3765d10c3820e68be8554cd7f5.diff
LOG: [libc] Implement setresuid and setresgid in unistd (#234837)
### Summary
Implement the standard POSIX / Linux extension functions `setresuid` and
`setresgid` in `<unistd.h>`.
- Invokes existing internal `setresuid` and `setresgid` Linux syscall
wrappers.
- Adds entrypoints under `LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS`
across Linux target architectures (`aarch64`, `arm`, `riscv`, `x86_64`),
matching the design pattern established for credential-changing
(`setxid`) entrypoints.
- Adds `// TODO: Implement setxid propagation across threads.` comments.
- Adds unit tests in `libc/test/src/unistd/` covering noop (`-1`),
setting current real/effective IDs, and unprivileged invalid ID
behavior.
Fixes #234694.
Added:
libc/src/unistd/linux/setresgid.cpp
libc/src/unistd/linux/setresuid.cpp
libc/src/unistd/setresgid.h
libc/src/unistd/setresuid.h
libc/test/src/unistd/setresgid_test.cpp
libc/test/src/unistd/setresuid_test.cpp
Modified:
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/arm/entrypoints.txt
libc/config/linux/riscv/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/include/unistd.yaml
libc/src/unistd/CMakeLists.txt
libc/src/unistd/linux/CMakeLists.txt
libc/test/src/unistd/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index cae6bcab572ab..f4d7454254a53 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1552,6 +1552,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.unistd.seteuid
libc.src.unistd.setgid
libc.src.unistd.setregid
+ libc.src.unistd.setresgid
+ libc.src.unistd.setresuid
libc.src.unistd.setreuid
libc.src.unistd.setuid
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 21488b488283b..e35ca9c7211ab 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -756,6 +756,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.unistd.seteuid
libc.src.unistd.setgid
libc.src.unistd.setregid
+ libc.src.unistd.setresgid
+ libc.src.unistd.setresuid
libc.src.unistd.setreuid
libc.src.unistd.setuid
)
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index e3d6b174d951a..5400f78747115 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1754,6 +1754,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.unistd.seteuid
libc.src.unistd.setgid
libc.src.unistd.setregid
+ libc.src.unistd.setresgid
+ libc.src.unistd.setresuid
libc.src.unistd.setreuid
libc.src.unistd.setuid
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index fd6ba983e52e8..570f6d994de22 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1790,6 +1790,8 @@ if(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS)
libc.src.unistd.seteuid
libc.src.unistd.setgid
libc.src.unistd.setregid
+ libc.src.unistd.setresgid
+ libc.src.unistd.setresuid
libc.src.unistd.setreuid
libc.src.unistd.setuid
diff --git a/libc/include/unistd.yaml b/libc/include/unistd.yaml
index 82d43ad5045f0..96ce15eee40b9 100644
--- a/libc/include/unistd.yaml
+++ b/libc/include/unistd.yaml
@@ -598,6 +598,14 @@ functions:
arguments:
- type: gid_t
- type: gid_t
+ - name: setresgid
+ standards:
+ - linux
+ return_type: int
+ arguments:
+ - type: gid_t
+ - type: gid_t
+ - type: gid_t
- name: setreuid
standards:
- posix
@@ -605,6 +613,14 @@ functions:
arguments:
- type: uid_t
- type: uid_t
+ - name: setresuid
+ standards:
+ - linux
+ return_type: int
+ arguments:
+ - type: uid_t
+ - type: uid_t
+ - type: uid_t
- name: setsid
standards:
- posix
diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 90690b725db17..0424641543d93 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -455,6 +455,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.setregid
)
+add_entrypoint_object(
+ setresgid
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.setresgid
+)
+
add_entrypoint_object(
setreuid
ALIAS
@@ -462,6 +469,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.setreuid
)
+add_entrypoint_object(
+ setresuid
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.setresuid
+)
+
add_entrypoint_object(
setsid
ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index ad23e55630e75..f3a8d8f011ac9 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -843,6 +843,18 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ setresgid
+ SRCS
+ setresgid.cpp
+ HDRS
+ ../setresgid.h
+ DEPENDS
+ libc.hdr.types.gid_t
+ libc.src.__support.OSUtil.linux.syscall_wrappers.setresgid
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
setreuid
SRCS
@@ -855,6 +867,18 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ setresuid
+ SRCS
+ setresuid.cpp
+ HDRS
+ ../setresuid.h
+ DEPENDS
+ libc.hdr.types.uid_t
+ libc.src.__support.OSUtil.linux.syscall_wrappers.setresuid
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
setsid
SRCS
diff --git a/libc/src/unistd/linux/setresgid.cpp b/libc/src/unistd/linux/setresgid.cpp
new file mode 100644
index 0000000000000..2649977ff93da
--- /dev/null
+++ b/libc/src/unistd/linux/setresgid.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
+/// Linux implementation of setresgid.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/setresgid.h"
+
+#include "hdr/types/gid_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/setresgid.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, setresgid, (gid_t rgid, gid_t egid, gid_t sgid)) {
+ // TODO: Implement setxid propagation across threads.
+ auto ret = linux_syscalls::setresgid(rgid, egid, sgid);
+ if (!ret) {
+ libc_errno = ret.error();
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/linux/setresuid.cpp b/libc/src/unistd/linux/setresuid.cpp
new file mode 100644
index 0000000000000..04a4bbf602bc3
--- /dev/null
+++ b/libc/src/unistd/linux/setresuid.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
+/// Linux implementation of setresuid.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/setresuid.h"
+
+#include "hdr/types/uid_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/setresuid.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, setresuid, (uid_t ruid, uid_t euid, uid_t suid)) {
+ // TODO: Implement setxid propagation across threads.
+ auto ret = linux_syscalls::setresuid(ruid, euid, suid);
+ if (!ret) {
+ libc_errno = ret.error();
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/setresgid.h b/libc/src/unistd/setresgid.h
new file mode 100644
index 0000000000000..da5279cf3db12
--- /dev/null
+++ b/libc/src/unistd/setresgid.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 setresgid function.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_SETRESGID_H
+#define LLVM_LIBC_SRC_UNISTD_SETRESGID_H
+
+#include "hdr/types/gid_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_UNISTD_SETRESGID_H
diff --git a/libc/src/unistd/setresuid.h b/libc/src/unistd/setresuid.h
new file mode 100644
index 0000000000000..41285897c65e5
--- /dev/null
+++ b/libc/src/unistd/setresuid.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 setresuid function.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_SETRESUID_H
+#define LLVM_LIBC_SRC_UNISTD_SETRESUID_H
+
+#include "hdr/types/uid_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_UNISTD_SETRESUID_H
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 251d0e4fc1703..abbe66fcf36d7 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -582,6 +582,21 @@ add_libc_test(
libc.test.UnitTest.ErrnoSetterMatcher
)
+add_libc_test(
+ setresgid_test
+ SUITE
+ libc-unistd-tests
+ SRCS
+ setresgid_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.src.unistd.getegid
+ libc.src.unistd.getgid
+ libc.src.unistd.setresgid
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
+
add_libc_test(
setreuid_test
SUITE
@@ -597,6 +612,21 @@ add_libc_test(
libc.test.UnitTest.ErrnoSetterMatcher
)
+add_libc_test(
+ setresuid_test
+ SUITE
+ libc-unistd-tests
+ SRCS
+ setresuid_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.src.unistd.geteuid
+ libc.src.unistd.getuid
+ libc.src.unistd.setresuid
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
+
add_libc_test(
setsid_test
SUITE
diff --git a/libc/test/src/unistd/setresgid_test.cpp b/libc/test/src/unistd/setresgid_test.cpp
new file mode 100644
index 0000000000000..903516153f986
--- /dev/null
+++ b/libc/test/src/unistd/setresgid_test.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Unittests for setresgid.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "src/unistd/getegid.h"
+#include "src/unistd/getgid.h"
+#include "src/unistd/setresgid.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcSetResGidTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSetResGidTest, NoopMinusOne) {
+ // Passing -1 leaves the corresponding ID unchanged and always succeeds.
+ ASSERT_THAT(LIBC_NAMESPACE::setresgid(static_cast<gid_t>(-1),
+ static_cast<gid_t>(-1),
+ static_cast<gid_t>(-1)),
+ Succeeds());
+}
+
+TEST_F(LlvmLibcSetResGidTest, SetCurrentResGid) {
+ // Setting the real and effective GIDs to their current values should succeed.
+ ASSERT_THAT(LIBC_NAMESPACE::setresgid(LIBC_NAMESPACE::getgid(),
+ LIBC_NAMESPACE::getegid(),
+ static_cast<gid_t>(-1)),
+ Succeeds());
+}
+
+TEST_F(LlvmLibcSetResGidTest, UnprivilegedInvalidGid) {
+ if (LIBC_NAMESPACE::getgid() == 0)
+ return;
+ ASSERT_THAT(LIBC_NAMESPACE::setresgid(static_cast<gid_t>(-2),
+ static_cast<gid_t>(-2),
+ static_cast<gid_t>(-2)),
+ Fails(any_of(EINVAL, EPERM)));
+}
diff --git a/libc/test/src/unistd/setresuid_test.cpp b/libc/test/src/unistd/setresuid_test.cpp
new file mode 100644
index 0000000000000..bea6eab882f26
--- /dev/null
+++ b/libc/test/src/unistd/setresuid_test.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Unittests for setresuid.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "src/unistd/geteuid.h"
+#include "src/unistd/getuid.h"
+#include "src/unistd/setresuid.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcSetResUidTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSetResUidTest, NoopMinusOne) {
+ // Passing -1 leaves the corresponding ID unchanged and always succeeds.
+ ASSERT_THAT(LIBC_NAMESPACE::setresuid(static_cast<uid_t>(-1),
+ static_cast<uid_t>(-1),
+ static_cast<uid_t>(-1)),
+ Succeeds());
+}
+
+TEST_F(LlvmLibcSetResUidTest, SetCurrentResUid) {
+ // Setting the real and effective UIDs to their current values should succeed.
+ ASSERT_THAT(LIBC_NAMESPACE::setresuid(LIBC_NAMESPACE::getuid(),
+ LIBC_NAMESPACE::geteuid(),
+ static_cast<uid_t>(-1)),
+ Succeeds());
+}
+
+TEST_F(LlvmLibcSetResUidTest, UnprivilegedInvalidUid) {
+ if (LIBC_NAMESPACE::getuid() == 0)
+ return;
+ ASSERT_THAT(LIBC_NAMESPACE::setresuid(static_cast<uid_t>(-2),
+ static_cast<uid_t>(-2),
+ static_cast<uid_t>(-2)),
+ Fails(any_of(EINVAL, EPERM)));
+}
More information about the libc-commits
mailing list