Polyinstantiated /tmp and /var/tmp - deployment notes
This deployment note extends the proof of concept with boot-time mount propagation and antivirus considerations. Those additions are environment-specific and should be treated separately from the core pam_namespace configuration.
Purpose
On a shared administrative host, per-user temporary directories reduce accidental cross-user exposure through predictable temporary filenames and poorly permissioned application data.
Create private backing directories:
$ mkdir --mode=000 /tmp-inst $ mkdir --mode=000 /var/tmp/tmp-inst
Example /etc/security/namespace.conf:
output 2 lines
/tmp /tmp-inst/ level root,adm /var/tmp /var/tmp/tmp-inst/ level root,adm
Ensure the relevant PAM service includes:
output 1 line
session required pam_namespace.so
The exact PAM stack varies by distribution. For SSH access, verify the SSH PAM stack rather than assuming /etc/pam.d/login is sufficient.
SELinux
Where supported by policy:
$ setsebool -P polyinstantiation_enabled onPrefer persistent file-context rules with semanage fcontext plus restorecon over chcon.
Test
Open two sessions as different users and verify that a file created as /tmp/example in one session is not visible in the other. Also confirm that system services and maintenance jobs are not unintentionally isolated.
Persistent SELinux labels
Example pattern:
$ semanage fcontext -a -e /tmp /tmp-inst $ semanage fcontext -a -e /var/tmp /var/tmp/tmp-inst $ restorecon -RFv /tmp-inst /var/tmp/tmp-inst
Mount propagation
If another mount tree must be visible inside all user namespaces, configure that mount as shared before the PAM sessions are created. Prefer a systemd mount/unit dependency over rc.local.
$ mount --bind /srv/shared /srv/shared $ mount --make-rshared /srv/shared
Use rshared only when recursive propagation is required.
Antivirus
The historical environment added backing directories to ClamAV on-access scanning. Current ClamAV syntax and fanotify requirements vary by release, so consult the documentation of the installed version before copying old OnAccessIncludePath directives.
References
- pam_namespace(8): https://man7.org/linux/man-pages/man8/pam_namespace.8.html
- Red Hat SELinux documentation: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_selinux/
- mount_namespaces(7): https://man7.org/linux/man-pages/man7/mount_namespaces.7.html
- ClamAV documentation: https://docs.clamav.net/
Current practice (checked 2026-10)
- Still valid: the
pam_namespacesetup above is unchanged. The twonamespace.conflines are the examples from namespace.conf(5), and the instance parents must still have mode 000. - Less manual work on RHEL-family systems: checked on Oracle Linux 10, the same lines ship commented out in
/etc/security/namespace.conf,pam_namespace.sois already in thelogin,sshdandgdmPAM stacks, andpam_namespace.service(pam_namespace_helper) creates the configured parent directories at boot. Local additions can go into/etc/security/namespace.d. - Method without SELinux:
levelandcontextare only available with SELinux. On a host without SELinux useuser;tmpdir(instance removed when the session closes) andtmpfsare further methods. - Patch level: pam_namespace had a local privilege escalation, CVE-2025-6020, fixed in Linux-PAM 1.7.1. Make sure the installed PAM package carries that fix before relying on polyinstantiation on a shared host.
- Mount propagation: on a systemd host
/is already a shared mount, so the bind mount plusmount --make-rsharedstep is normally not needed. pam_namespace detects the shared/and makes only the polyinstantiated directories private; themount_privateoption is for the case where only a subtree is shared. - Services: for daemons the standard tool is the unit setting
PrivateTmp=yes, which gives the service its own/tmpand/var/tmpwithout PAM. - ClamAV: since ClamAV 0.102 on-access scanning is done by the separate
clamonaccclient running next toclamd;OnAccessIncludePathis still the option that names the watched paths.
$ findmnt -o TARGET,PROPAGATION /Sources: