diff --git a/man/system-or-user-ns.xml b/man/system-or-user-ns.xml
new file mode 100644
index 0000000000..01d1dd022c
--- /dev/null
+++ b/man/system-or-user-ns.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+This option is only available for system services, or for services running in per-user
+ instances of the service manager when unprivileged user namespaces are available.
+
+These options are only available for system services, or for services running in per-user
+ instances of the service manager when unprivileged user namespaces are available.
+
+
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index f182919673..6f1fa6338a 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -143,7 +143,9 @@
Mounting logging sockets into root environment
BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
-
+
+
+
@@ -480,7 +482,9 @@
os-release5.
Note that usage from user units requires overlayfs support in unprivileged user namespaces,
- which was first introduced in kernel v5.11.
+ which was first introduced in kernel v5.11.
+
+
@@ -625,7 +629,7 @@
Capabilities
-
+
@@ -1254,7 +1258,7 @@ CapabilityBoundingSet=~CAP_B CAP_C
DynamicUser= is set. This setting cannot ensure protection in all cases. In
general it has the same limitations as ReadOnlyPaths=, see below.
-
+
@@ -1508,7 +1512,7 @@ NoExecPaths=/
ExecPaths=/usr/sbin/my_daemon /usr/lib /usr/lib64
-
+
@@ -1533,7 +1537,7 @@ BindReadOnlyPaths=/var/lib/systemd
then the invoked processes by the unit cannot see any files or directories under /var/ except for
/var/lib/systemd or its contents.
-
+
@@ -1561,7 +1565,7 @@ BindReadOnlyPaths=/var/lib/systemd
available), and the unit should be written in a way that does not solely rely on this setting for
security.
-
+
@@ -1595,7 +1599,7 @@ BindReadOnlyPaths=/var/lib/systemd
namespaces are not available), and the unit should be written in a way that does not solely rely on
this setting for security.
-
+
When access to some but not all devices must be possible, the DeviceAllow=
setting might be used instead. See
@@ -1629,7 +1633,7 @@ BindReadOnlyPaths=/var/lib/systemd
JoinsNamespaceOf= to listen on sockets inside of network namespaces of other
services.
-
+
@@ -1648,7 +1652,7 @@ BindReadOnlyPaths=/var/lib/systemd
When this option is used on a socket unit any sockets bound on behalf of this unit will be
bound within the specified network namespace.
-
+
@@ -1679,7 +1683,7 @@ BindReadOnlyPaths=/var/lib/systemd
not available), and the unit should be written in a way that does not solely rely on this setting for
security.
-
+
@@ -1695,7 +1699,7 @@ BindReadOnlyPaths=/var/lib/systemd
IPCNamespacePath= configured, as otherwise the network namespace of those
units is reused.
-
+
@@ -1749,7 +1753,7 @@ BindReadOnlyPaths=/var/lib/systemd
capability (e.g. services for which User= is set),
NoNewPrivileges=yes is implied.
-
+
@@ -1766,7 +1770,7 @@ BindReadOnlyPaths=/var/lib/systemd
doesn't have the CAP_SYS_ADMIN capability (e.g. services for which
User= is set), NoNewPrivileges=yes is implied.
-
+
@@ -1790,7 +1794,7 @@ BindReadOnlyPaths=/var/lib/systemd
inaccessible. If ProtectKernelTunables= is set,
MountAPIVFS=yes is implied.
-
+
@@ -1811,7 +1815,7 @@ BindReadOnlyPaths=/var/lib/systemd
but the unit doesn't have the CAP_SYS_ADMIN capability (e.g. services for
which User= is set), NoNewPrivileges=yes is implied.
-
+
@@ -1830,7 +1834,7 @@ BindReadOnlyPaths=/var/lib/systemd
capability (e.g. services for which User= is set),
NoNewPrivileges=yes is implied.
-
+
@@ -2134,7 +2138,7 @@ RestrictNamespaces=~cgroup net
option. Hence it is primarily useful to explicitly request this behaviour if none of the other settings are
used.
-
+
@@ -2164,7 +2168,7 @@ RestrictNamespaces=~cgroup net
Usually, it is best to leave this setting unmodified, and use higher level file system namespacing
options instead, in particular PrivateMounts=, see above.
-
+
diff --git a/test/units/testsuite-43.sh b/test/units/testsuite-43.sh
index 8b755b1a0f..fec936e999 100755
--- a/test/units/testsuite-43.sh
+++ b/test/units/testsuite-43.sh
@@ -74,6 +74,53 @@ runas testuser systemd-run --wait --user --unit=test-bind-mount \
-p PrivateUsers=yes -p BindPaths=/dev/null:/etc/os-release \
test ! -s /etc/os-release
+runas testuser systemd-run --wait --user --unit=test-read-write \
+ -p PrivateUsers=yes -p ReadOnlyPaths=/ \
+ -p ReadWritePaths="/var /run /tmp" \
+ -p NoExecPaths=/ -p ExecPaths=/usr \
+ test ! -w /etc/os-release
+
+runas testuser systemd-run --wait --user --unit=test-caps \
+ -p PrivateUsers=yes -p AmbientCapabilities=CAP_SYS_ADMIN \
+ -p CapabilityBoundingSet=CAP_SYS_ADMIN \
+ test -s /etc/os-release
+
+runas testuser systemd-run --wait --user --unit=test-devices \
+ -p PrivateUsers=yes -p PrivateDevices=yes -p PrivateIPC=yes \
+ sh -c "ls -1 /dev/ | wc -l | grep -q -F 18"
+
+# Same check as test/test-execute/exec-privatenetwork-yes.service
+runas testuser systemd-run --wait --user --unit=test-network \
+ -p PrivateUsers=yes -p PrivateNetwork=yes \
+ /bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"'
+
+runas testuser systemd-run --wait --user --unit=test-hostname \
+ -p PrivateUsers=yes -p ProtectHostname=yes \
+ hostnamectl hostname foo \
+ && { echo 'unexpected success'; exit 1; }
+
+runas testuser systemd-run --wait --user --unit=test-clock \
+ -p PrivateUsers=yes -p ProtectClock=yes \
+ timedatectl set-time "2012-10-30 18:17:16" \
+ && { echo 'unexpected success'; exit 1; }
+
+runas testuser systemd-run --wait --user --unit=test-kernel-tunable \
+ -p PrivateUsers=yes -p ProtectKernelTunables=yes \
+ sh -c "echo 0 > /proc/sys/user/max_user_namespaces" \
+ && { echo 'unexpected success'; exit 1; }
+
+runas testuser systemd-run --wait --user --unit=test-kernel-mod \
+ -p PrivateUsers=yes -p ProtectKernelModules=yes \
+ sh -c "modprobe -r overlay && modprobe overlay" \
+ && { echo 'unexpected success'; exit 1; }
+
+if sysctl kernel.dmesg_restrict=0; then
+ runas testuser systemd-run --wait --user --unit=test-kernel-log \
+ -p PrivateUsers=yes -p ProtectKernelLogs=yes -p LogNamespace=yes \
+ dmesg \
+ && { echo 'unexpected success'; exit 1; }
+fi
+
unsquashfs -no-xattrs -d /tmp/img /usr/share/minimal_0.raw
runas testuser systemd-run --wait --user --unit=test-root-dir \
-p PrivateUsers=yes -p RootDirectory=/tmp/img \
@@ -82,8 +129,9 @@ runas testuser systemd-run --wait --user --unit=test-root-dir \
mkdir /tmp/img_bind
mount --bind /tmp/img /tmp/img_bind
runas testuser systemd-run --wait --user --unit=test-root-dir-bind \
- -p PrivateUsers=yes -p RootDirectory=/tmp/img_bind \
+ -p PrivateUsers=yes -p RootDirectory=/tmp/img_bind -p MountFlags=private \
grep MARKER=1 /etc/os-release
+umount /tmp/img_bind
# Unprivileged overlayfs was added to Linux 5.11, so try to detect it first
mkdir -p /tmp/a /tmp/b /tmp/c
@@ -96,8 +144,6 @@ if unshare --mount --user --map-root-user mount -t overlay overlay /tmp/c -o low
grep PORTABLE_PREFIXES=app1 /usr/lib/extension-release.d/extension-release.app2
fi
-umount /tmp/img_bind
-
systemd-analyze log-level info
echo OK >/testok