Skip to content
shellhacks.dev
Security

Limit a Script's Linux Capabilities with setpriv

Remove Linux capabilities from a command and its children with setpriv --bounding-set=-chown,-dac_override. Even root then fails to read protected files or chown.

2 min read
Summarize in AI

A script has to run as root but should not be able to change file ownership or ignore file permissions.

Shell
echo secret > locked.txt
chown 1000:1000 locked.txt
chmod 000 locked.txt
touch f
echo "as root with every capability:"
cat locked.txt
chown 1000 f && echo "chown worked"
echo "with chown and dac_override removed:"
setpriv --bounding-set=-chown,-dac_override sh -c 'cat locked.txt; chown 1000 f'
grep CapBnd /proc/self/status
setpriv --bounding-set=-chown,-dac_override grep CapBnd /proc/self/status
Text
as root with every capability:
secret
chown worked
with chown and dac_override removed:
cat: locked.txt: Permission denied
chown: changing ownership of 'f': Operation not permitted
CapBnd:	00000000a80425fb
CapBnd:	00000000a80425f8

Root normally holds every capability, so cat read a file with mode 000 owned by another user, which needs CAP_DAC_OVERRIDE, and chown worked, which needs CAP_CHOWN. Starting the command through setpriv --bounding-set=-chown,-dac_override removes both from the set the new process can ever hold, and the same two operations failed with Permission denied and Operation not permitted. The CapBnd value in /proc/self/status changed from a80425fb to a80425f8, which is bits 0 and 1 cleared. See capabilities.

The bounding set restricts programs started after the change, not ones already running. Changing it needs CAP_SETPCAP, and many containers have already dropped capabilities, so the value on your machine will differ. For a real sandbox combine it with --no-new-privs and a non-root user.

Share

More snippets

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.