Read a Process Personality from /proc Without Guessing
The hexadecimal value sitting in /proc/<pid>/personality looks cryptic, but it is just the Linux execution domain a process is running under. This walkthrough gives you a reproducible way to read it and prove when a child process has inherited a flag. The examples use the local Linux man-pages 6.7 documentation and util-linux 2.41.3.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and a Linux system with procfs mounted. Reading your own process needs no elevated privileges. Reading another user's process may be rejected by the kernel's ptrace access check, so do not reach for sudo just to make an unexplained result disappear.
1. Check the file and read your own process
The file is read-only. It exposes the execution domain selected for a process by the personality(2) system call, and reports the value in hexadecimal. Start with the shell's own process:
$ test -r /proc/self/personality && echo readable
readable
$ cat /proc/self/personality
00000000
/proc/self is a procfs link the kernel resolves for the process doing the read, so the exact value is host- and launcher-dependent. On an ordinary Linux process, 00000000 represents the base Linux personality, but treat the output as a value to inspect rather than text that names a mode.
Checkpoint
If the file is missing, check that procfs is mounted and that you are actually on Linux. If it exists but cannot be read for another PID, record that as an access-control result, not a bug.
2. Read a specific PID safely
Swap in a process ID you are allowed to inspect for PID. This is an ordinary read-only command:
$ PID=12345
$ test -r "/proc/$PID/personality" && cat "/proc/$PID/personality"
00000000
- Process can vanish mid-check. A missing file, a changed PID or a permission error is normal failure handling, not evidence that the process has no personality.
- Confirm identity first. Run
ps -p "$PID" -o pid=,comm=to check the PID still names the process you meant. - No write interface. Do not try to write a new value to this file, and do not describe it as a configuration file. Changing a personality needs a program calling
personality(2), or a launcher such assetarch(8).
3. Display the name and the raw value with setarch
If util-linux is installed, setarch --show gives a human-readable view of the current personality:
$ setarch --version
setarch from util-linux 2.41.3
$ setarch --show
PER_LINUX
The name is useful, but it does not replace the procfs value. The personality is a 32-bit value: the low byte identifies the base personality, and the upper bytes carry flags that alter selected kernel behaviour. Read /proc/self/personality inside the command you are investigating when you need the exact value.
Do not assume every value has a useful name. Some historical execution domains have little or no effect on current kernels, and flags can be combined. The man-page's descriptions of PER_LINUX, PER_LINUX32 and the flags are more reliable than pattern-matching a number from a log.
4. Prove inheritance with a harmless child
A personality belongs to a process. Use setarch --uname-2.6 to launch a short-lived child with the documented UNAME26 flag, then inspect that child from inside:
$ setarch --uname-2.6 -- /bin/sh -c 'cat /proc/self/personality; printf "\n"; uname -r'
00020000
2.6.68-139-generic
The hexadecimal value 00020000 is the UNAME26 flag in this run. The kernel makes uname(2) report a 2.6-style version, so the second line is deliberately not the host's real release string. Your version will differ. The child exits when the shell command finishes, and no persistent system setting changes.
Checkpoint
Repeat the check without the flag:
$ /bin/sh -c 'printf "personality="; cat /proc/self/personality; printf "release="; uname -r'
personality=00000000
release=6.14.0-27-generic
The release shown is illustrative of this machine and will vary. The comparison that matters is the personality value, and the fact that the flag affects only the child.
5. Inspect a memory-layout flag without changing the host
--addr-no-randomize sets the ADDR_NO_RANDOMIZE flag for the launched process. It is security-sensitive because address-space-layout randomisation defends against some memory-exploitation techniques, so use it only for a controlled diagnostic, never as a blanket workaround for a service:
$ setarch --addr-no-randomize -- /bin/sh -c 'cat /proc/self/personality; printf "\n"'
00040000
Warning
This changes the child process's personality, not the kernel's global policy. Do not combine it with an untrusted program merely to make that program easier to debug. If a debugger or test genuinely requires the flag, record the exact launcher command and remove it when the test is complete.
Diagnose confusing results
- No such file or directory. Running
cat /proc/$PID/personalityand seeing this means the process probably exited or the PID was wrong. - Permission denied. The ptrace access mode
PTRACE_MODE_ATTACH_FSCREDSis the relevant boundary. Check ownership, dumpability and the host's security policy before escalating privileges. - Surprising child value. Inspect the complete command line and its ancestors: a wrapper, test runner, container entrypoint or debugger may have set flags before your program started. Compare the value inside the target process, not in the parent shell.
- Do not overtrust a flag. The kernel may ignore obsolete personalities, and some flags apply only to specific architectures or system calls. Use the documented effect and a focused test such as
uname, rather than relying on the number alone.
Done means
- Read without writing. You read
/proc/self/personalitywithout attempting to write it. - Handled disappearing PIDs. You know another PID can vanish or be protected by ptrace access checks.
- Decoded the value. You can relate a hexadecimal value to a base personality and optional flags.
- Proved inheritance. You verified it with a short-lived
setarchchild. - Left the host alone. Diagnostic flags stayed local to test processes; no persistent service or kernel setting changed.