[libc-commits] [libc] [libc] Implement sys/personality.h (PR #195065)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Thu Apr 30 05:12:42 PDT 2026
https://github.com/kaladron created https://github.com/llvm/llvm-project/pull/195065
Added the personality() syscall wrapper, which sets or queries the process execution domain. The function signature follows the Linux man page: int personality(unsigned long persona).
New files:
* libc/include/sys/personality.{yaml,h.def}
* libc/src/sys/personality/ (implementation + linux/ syscall)
* libc/test/src/sys/personality/ (unit tests)
Registered the entrypoint and header for x86_64, aarch64, riscv, and arm. The implementation includes <linux/personality.h> for the kernel-defined constants (PER_LINUX, ADDR_NO_RANDOMIZE, etc.) following the same pattern as sys/prctl.h.
>From 982cad4eb5466d8071de66cda8db6744a0019f4b Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 30 Apr 2026 12:56:31 +0100
Subject: [PATCH] [libc] Implement sys/personality.h
Added the personality() syscall wrapper, which sets or queries
the process execution domain. The function signature follows the
Linux man page: int personality(unsigned long persona).
New files:
* libc/include/sys/personality.{yaml,h.def}
* libc/src/sys/personality/ (implementation + linux/ syscall)
* libc/test/src/sys/personality/ (unit tests)
Registered the entrypoint and header for x86_64, aarch64, riscv,
and arm. The implementation includes <linux/personality.h> for the
kernel-defined constants (PER_LINUX, ADDR_NO_RANDOMIZE, etc.)
following the same pattern as sys/prctl.h.
---
libc/config/linux/aarch64/entrypoints.txt | 3 ++
libc/config/linux/aarch64/headers.txt | 1 +
libc/config/linux/arm/entrypoints.txt | 3 ++
libc/config/linux/arm/headers.txt | 2 +
libc/config/linux/riscv/entrypoints.txt | 3 ++
libc/config/linux/riscv/headers.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 3 ++
libc/config/linux/x86_64/headers.txt | 1 +
libc/include/CMakeLists.txt | 8 ++++
libc/include/sys/personality.h.def | 19 +++++++++
libc/include/sys/personality.yaml | 13 ++++++
.../linux/syscall_wrappers/CMakeLists.txt | 12 ++++++
.../linux/syscall_wrappers/personality.h | 31 ++++++++++++++
libc/src/sys/CMakeLists.txt | 1 +
libc/src/sys/personality/CMakeLists.txt | 10 +++++
libc/src/sys/personality/linux/CMakeLists.txt | 13 ++++++
.../src/sys/personality/linux/personality.cpp | 28 +++++++++++++
libc/src/sys/personality/personality.h | 21 ++++++++++
libc/test/src/sys/CMakeLists.txt | 1 +
libc/test/src/sys/personality/CMakeLists.txt | 3 ++
.../src/sys/personality/linux/CMakeLists.txt | 15 +++++++
.../personality/linux/personality_test.cpp | 40 +++++++++++++++++++
22 files changed, 232 insertions(+)
create mode 100644 libc/include/sys/personality.h.def
create mode 100644 libc/include/sys/personality.yaml
create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h
create mode 100644 libc/src/sys/personality/CMakeLists.txt
create mode 100644 libc/src/sys/personality/linux/CMakeLists.txt
create mode 100644 libc/src/sys/personality/linux/personality.cpp
create mode 100644 libc/src/sys/personality/personality.h
create mode 100644 libc/test/src/sys/personality/CMakeLists.txt
create mode 100644 libc/test/src/sys/personality/linux/CMakeLists.txt
create mode 100644 libc/test/src/sys/personality/linux/personality_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b15edc5e3e102..8f05bd6916e37 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -307,6 +307,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl
+ # sys/personality.h entrypoints
+ libc.src.sys.personality.personality
+
# sys/auxv.h entrypoints
libc.src.sys.auxv.getauxval
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 4784fc5d29ddc..05cd13b1980e7 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -39,6 +39,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.sys_epoll
libc.include.sys_ioctl
libc.include.sys_mman
+ libc.include.sys_personality
libc.include.sys_prctl
libc.include.sys_queue
libc.include.sys_random
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 8a4d88b5ba98c..1c4dd1a4cb879 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -183,6 +183,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl
+ # sys/personality.h entrypoints
+ libc.src.sys.personality.personality
+
# sys/epoll.h entrypoints
# Disabled due to epoll_wait syscalls not being available on this platform.
# libc.src.sys.epoll.epoll_wait
diff --git a/libc/config/linux/arm/headers.txt b/libc/config/linux/arm/headers.txt
index dad65234363b3..a9c4de1cf790a 100644
--- a/libc/config/linux/arm/headers.txt
+++ b/libc/config/linux/arm/headers.txt
@@ -20,6 +20,8 @@ set(TARGET_PUBLIC_HEADERS
libc.include.wchar
libc.include.wctype
+ libc.include.sys_personality
+
# Disabled due to epoll_wait syscalls not being available on this platform.
# libc.include.sys_epoll
)
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 6478aed3b0391..03b2f310d49cc 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -310,6 +310,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl
+ # sys/personality.h entrypoints
+ libc.src.sys.personality.personality
+
# sys/auxv.h entrypoints
libc.src.sys.auxv.getauxval
diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt
index 45c42eb65527c..218b7f8153309 100644
--- a/libc/config/linux/riscv/headers.txt
+++ b/libc/config/linux/riscv/headers.txt
@@ -39,6 +39,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.sys_epoll
libc.include.sys_ioctl
libc.include.sys_mman
+ libc.include.sys_personality
libc.include.sys_prctl
libc.include.sys_queue
libc.include.sys_random
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index d1c1d9496af67..3ac32de6949c7 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -326,6 +326,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl
+ # sys/personality.h entrypoints
+ libc.src.sys.personality.personality
+
# sys/auxv.h entrypoints
libc.src.sys.auxv.getauxval
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index fb461444b43d8..8c25137bd9de4 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -41,6 +41,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.sys_ioctl
libc.include.sys_ipc
libc.include.sys_mman
+ libc.include.sys_personality
libc.include.sys_prctl
libc.include.sys_queue
libc.include.sys_random
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 79380c5a21cd6..bca9aa68be76d 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -639,6 +639,14 @@ add_header_macro(
.llvm-libc-types.ssize_t
)
+add_header_macro(
+ sys_personality
+ ../libc/include/sys/personality.yaml
+ sys/personality.h
+ DEPENDS
+ .llvm_libc_common_h
+)
+
add_header_macro(
sys_prctl
../libc/include/sys/prctl.yaml
diff --git a/libc/include/sys/personality.h.def b/libc/include/sys/personality.h.def
new file mode 100644
index 0000000000000..15007dbf8c426
--- /dev/null
+++ b/libc/include/sys/personality.h.def
@@ -0,0 +1,19 @@
+//===-- Linux header personality.h ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SYS_PERSONALITY_H
+#define LLVM_LIBC_SYS_PERSONALITY_H
+
+#include "__llvm-libc-common.h"
+
+// The personality constants and flags are defined by the kernel.
+#include <linux/personality.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_SYS_PERSONALITY_H
diff --git a/libc/include/sys/personality.yaml b/libc/include/sys/personality.yaml
new file mode 100644
index 0000000000000..33fb51caa64f2
--- /dev/null
+++ b/libc/include/sys/personality.yaml
@@ -0,0 +1,13 @@
+header: sys/personality.h
+header_template: personality.h.def
+macros: []
+types: []
+enums: []
+objects: []
+functions:
+ - name: personality
+ standards:
+ - Linux
+ return_type: int
+ arguments:
+ - type: unsigned long
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 049eeac913780..0417456a31ce6 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -159,6 +159,18 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ personality
+ HDRS
+ personality.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
add_header_library(
utimensat
HDRS
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h
new file mode 100644
index 0000000000000..163c1c4113c9d
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h
@@ -0,0 +1,31 @@
+//===-- Syscall wrapper for personality -------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PERSONALITY_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PERSONALITY_H
+
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> personality(unsigned long persona) {
+ long ret = syscall_impl<long>(SYS_personality, persona);
+ if (ret < 0)
+ return Error(-static_cast<int>(ret));
+ return static_cast<int>(ret);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PERSONALITY_H
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index 41becce798ddd..585b8f7b158eb 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(auxv)
add_subdirectory(epoll)
add_subdirectory(ipc)
add_subdirectory(mman)
+add_subdirectory(personality)
add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(select)
diff --git a/libc/src/sys/personality/CMakeLists.txt b/libc/src/sys/personality/CMakeLists.txt
new file mode 100644
index 0000000000000..d2f655305e64f
--- /dev/null
+++ b/libc/src/sys/personality/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+ personality
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.personality
+)
diff --git a/libc/src/sys/personality/linux/CMakeLists.txt b/libc/src/sys/personality/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..b7aff12947632
--- /dev/null
+++ b/libc/src/sys/personality/linux/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_entrypoint_object(
+ personality
+ SRCS
+ personality.cpp
+ HDRS
+ ../personality.h
+ DEPENDS
+ libc.src.__support.OSUtil.linux.syscall_wrappers.personality
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+)
diff --git a/libc/src/sys/personality/linux/personality.cpp b/libc/src/sys/personality/linux/personality.cpp
new file mode 100644
index 0000000000000..c2f97b479f0a5
--- /dev/null
+++ b/libc/src/sys/personality/linux/personality.cpp
@@ -0,0 +1,28 @@
+//===--------- Linux implementation of the personality function -----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/personality/personality.h"
+
+#include "src/__support/OSUtil/linux/syscall_wrappers/personality.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, personality, (unsigned long persona)) {
+ auto result = linux_syscalls::personality(persona);
+ if (!result.has_value()) {
+ libc_errno = static_cast<int>(result.error());
+ return -1;
+ }
+ return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/personality/personality.h b/libc/src/sys/personality/personality.h
new file mode 100644
index 0000000000000..e5c9ebf9aa9f6
--- /dev/null
+++ b/libc/src/sys/personality/personality.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for personality ---------------------*-C++-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_PERSONALITY_PERSONALITY_H
+#define LLVM_LIBC_SRC_SYS_PERSONALITY_PERSONALITY_H
+
+#include "src/__support/macros/config.h"
+#include <sys/personality.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+int personality(unsigned long persona);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_PERSONALITY_PERSONALITY_H
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 444f86f5d00a9..9af889bffa46d 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(mman)
+add_subdirectory(personality)
add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(select)
diff --git a/libc/test/src/sys/personality/CMakeLists.txt b/libc/test/src/sys/personality/CMakeLists.txt
new file mode 100644
index 0000000000000..b4bbe81c92ff2
--- /dev/null
+++ b/libc/test/src/sys/personality/CMakeLists.txt
@@ -0,0 +1,3 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${LIBC_TARGET_OS})
+endif()
diff --git a/libc/test/src/sys/personality/linux/CMakeLists.txt b/libc/test/src/sys/personality/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..18ab52d33dc65
--- /dev/null
+++ b/libc/test/src/sys/personality/linux/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_custom_target(libc_sys_personality_unittests)
+
+add_libc_unittest(
+ personality_test
+ SUITE
+ libc_sys_personality_unittests
+ SRCS
+ personality_test.cpp
+ DEPENDS
+ libc.include.sys_personality
+ libc.src.sys.personality.personality
+ libc.src.errno.errno
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
diff --git a/libc/test/src/sys/personality/linux/personality_test.cpp b/libc/test/src/sys/personality/linux/personality_test.cpp
new file mode 100644
index 0000000000000..6fdaa756857b9
--- /dev/null
+++ b/libc/test/src/sys/personality/linux/personality_test.cpp
@@ -0,0 +1,40 @@
+//===-- Unittests for personality -----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/personality/personality.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include <sys/personality.h>
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcSysPersonalityTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSysPersonalityTest, GetPersonality) {
+ // Passing 0xffffffff retrieves the current persona without changing it.
+ int persona = LIBC_NAMESPACE::personality(0xffffffff);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GE(persona, 0);
+}
+
+TEST_F(LlvmLibcSysPersonalityTest, SetAndRestore) {
+ // Get the current persona.
+ int original = LIBC_NAMESPACE::personality(0xffffffff);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_GE(original, 0);
+
+ // Set the personality to the same value; should succeed and return the
+ // previous persona.
+ int prev = LIBC_NAMESPACE::personality(original);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(prev, original);
+
+ // Verify the personality is unchanged.
+ int current = LIBC_NAMESPACE::personality(0xffffffff);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(current, original);
+}
More information about the libc-commits
mailing list