NoExecPaths=/ + nested ExecPaths= exception does not grant exec permission — binary remains blocked despite being explicitly listed
systemd version the issue has been seen with
257.13-1~deb13u1
Used distribution
Debian 13
Linux kernel version used
6.12.107+deb13-amd64
CPU architectures issue was seen on
x86_64
Component
systemd
Expected behaviour you didn't see
Per systemd.exec(5): "Nest ExecPaths= inside of NoExecPaths= in order to provide executable content within non-executable directories." A binary listed in ExecPaths= should remain executable even when NoExecPaths=/ denies execution everywhere else.
Unexpected behaviour you saw
The nested ExecPaths= exception has no effect. The listed binary is denied exactly as if it were not listed at all.
Steps to reproduce the problem
Minimal reproduction via systemd-run (no unit file, no other directives):
Baseline: ExecPaths alone (no deny in effect) - works, as expected
systemd-run --pty --unit=exectestA \
-p ExecPaths=/usr/bin/doveconf \
/usr/bin/doveconf -n
# -> succeeds, prints configBaseline: NoExecPaths=/ alone - correctly denies, as expected
systemd-run --pty --unit=exectestB \
-p NoExecPaths=/ \
/usr/bin/doveconf -n
# -> journalctl -u exectestB:
# "Unable to locate executable '/usr/bin/doveconf': Permission denied"
# "Failed at step EXEC spawning /usr/bin/doveconf: Permission denied"Combined, per documented usage - should succeed (binary is explicitly listed in ExecPaths=), but fails identically to the NoExecPaths-alone case:
systemd-run --pty --unit=exectest1 \
-p NoExecPaths=/ \
-p ExecPaths=/usr/bin/doveconf \
/usr/bin/doveconf -n
# -> journalctl -u exectest1:
# "Failed to execute /usr/bin/doveconf: Permission denied"
# "Failed at step EXEC spawning /usr/bin/doveconf: Permission denied"No other hardening directives (ProtectSystem, capabilities, syscall filters, etc.) are present in this reproduction - this was deliberately isolated to rule out interaction effects after this exact combination failed inside a much larger hardening profile applied to a production Dovecot service.
Possibly related: #39935 (PrivateTmp=true causing NoExecPaths= to be silently ignored on the resulting bind mount) - different trigger, same general area (NoExecPaths=/ExecPaths= composition with other mount namespace setup).
Regards, Terry
Additional program output to the terminal or log subsystem illustrating the issue
Source: systemd/systemd