Time Namespace
Reading time: 6 minutes
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Basic Information
The time namespace in Linux allows for per-namespace offsets to the system monotonic and boot-time clocks. It is commonly used in Linux containers to change the date/time within a container and adjust clocks after restoring from a checkpoint or snapshot.
Lab:
Create different Namespaces
CLI
sudo unshare -T [--mount-proc] /bin/bash
By mounting a new instance of the /proc
filesystem if you use the param --mount-proc
, you ensure that the new mount namespace has an accurate and isolated view of the process information specific to that namespace.
Error: bash: fork: Cannot allocate memory
When unshare
is executed without the -f
option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below:
-
Problem Explanation:
- The Linux kernel allows a process to create new namespaces using the
unshare
system call. However, the process that initiates the creation of a new PID namespace (referred to as the "unshare" process) does not enter the new namespace; only its child processes do. - Running
%unshare -p /bin/bash%
starts/bin/bash
in the same process asunshare
. Consequently,/bin/bash
and its child processes are in the original PID namespace. - The first child process of
/bin/bash
in the new namespace becomes PID 1. When this process exits, it triggers the cleanup of the namespace if there are no other processes, as PID 1 has the special role of adopting orphan processes. The Linux kernel will then disable PID allocation in that namespace.
- The Linux kernel allows a process to create new namespaces using the
-
Consequence:
- The exit of PID 1 in a new namespace leads to the cleaning of the
PIDNS_HASH_ADDING
flag. This results in thealloc_pid
function failing to allocate a new PID when creating a new process, producing the "Cannot allocate memory" error.
- The exit of PID 1 in a new namespace leads to the cleaning of the
-
Solution:
- The issue can be resolved by using the
-f
option withunshare
. This option makesunshare
fork a new process after creating the new PID namespace. - Executing
%unshare -fp /bin/bash%
ensures that theunshare
command itself becomes PID 1 in the new namespace./bin/bash
and its child processes are then safely contained within this new namespace, preventing the premature exit of PID 1 and allowing normal PID allocation.
- The issue can be resolved by using the
By ensuring that unshare
runs with the -f
flag, the new PID namespace is correctly maintained, allowing /bin/bash
and its sub-processes to operate without encountering the memory allocation error.
Docker
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
Check which namespace is your process in
ls -l /proc/self/ns/time
lrwxrwxrwx 1 root root 0 Apr 4 21:16 /proc/self/ns/time -> 'time:[4026531834]'
Find all Time namespaces
sudo find /proc -maxdepth 3 -type l -name time -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name time -exec ls -l {} \; 2>/dev/null | grep <ns-number>
Enter inside a Time namespace
nsenter -T TARGET_PID --pid /bin/bash
Manipulating Time Offsets
Starting with Linux 5.6, two clocks can be virtualised per time namespace:
CLOCK_MONOTONIC
CLOCK_BOOTTIME
Their per-namespace deltas are exposed (and can be modified) through the file /proc/<PID>/timens_offsets
:
$ sudo unshare -Tr --mount-proc bash # -T creates a new timens, -r drops capabilities
$ cat /proc/$$/timens_offsets
monotonic 0
boottime 0
The file contains two lines – one per clock – with the offset in nanoseconds. Processes that hold CAP_SYS_TIME in the time namespace can change the value:
# advance CLOCK_MONOTONIC by two days (172 800 s)
echo "monotonic 172800000000000" > /proc/$$/timens_offsets
# verify
$ cat /proc/$$/uptime # first column uses CLOCK_MONOTONIC
172801.37 13.57
If you need the wall clock (CLOCK_REALTIME
) to change as well you still have to rely on classic mechanisms (date
, hwclock
, chronyd
, …); it is not namespaced.
unshare(1)
helper flags (util-linux ≥ 2.38)
sudo unshare -T \
--monotonic="+24h" \
--boottime="+7d" \
--mount-proc \
bash
The long options automatically write the chosen deltas to timens_offsets
right after the namespace is created, saving a manual echo
.
OCI & Runtime support
- The OCI Runtime Specification v1.1 (Nov 2023) added a dedicated
time
namespace type and thelinux.timeOffsets
field so that container engines can request time virtualisation in a portable way. - runc >= 1.2.0 implements that part of the spec. A minimal
config.json
fragment looks like:
Then run the container with{ "linux": { "namespaces": [ {"type": "time"} ], "timeOffsets": { "monotonic": 86400, "boottime": 600 } } }
runc run <id>
.
NOTE: runc 1.2.6 (Feb 2025) fixed an "exec into container with private timens" bug that could lead to a hang and potential DoS. Make sure you are on ≥ 1.2.6 in production.
Security considerations
- Required capability – A process needs CAP_SYS_TIME inside its user/time namespace to change the offsets. Dropping that capability in the container (default in Docker & Kubernetes) prevents tampering.
- No wall-clock changes – Because
CLOCK_REALTIME
is shared with the host, attackers cannot spoof certificate lifetimes, JWT expiry, etc. via timens alone. - Log / detection evasion – Software that relies on
CLOCK_MONOTONIC
(e.g. rate-limiters based on uptime) can be confused if the namespace user adjusts the offset. PreferCLOCK_REALTIME
for security-relevant timestamps. - Kernel attack surface – Even with
CAP_SYS_TIME
removed, the kernel code remains accessible; keep the host patched. Linux 5.6 → 5.12 received multiple timens bug-fixes (NULL-deref, signedness issues).
Hardening checklist
- Drop
CAP_SYS_TIME
in your container runtime default profile. - Keep runtimes updated (runc ≥ 1.2.6, crun ≥ 1.12).
- Pin util-linux ≥ 2.38 if you rely on the
--monotonic/--boottime
helpers. - Audit in-container software that reads uptime or CLOCK_MONOTONIC for security-critical logic.
References
- man7.org – Time namespaces manual page: https://man7.org/linux/man-pages/man7/time_namespaces.7.html
- OCI blog – "OCI v1.1: new time and RDT namespaces" (Nov 15 2023): https://opencontainers.org/blog/2023/11/15/oci-spec-v1.1
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.