forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
2.9 KiB
63 lines
2.9 KiB
====================== |
|
No New Privileges Flag |
|
====================== |
|
|
|
The execve system call can grant a newly-started program privileges that |
|
its parent did not have. The most obvious examples are setuid/setgid |
|
programs and file capabilities. To prevent the parent program from |
|
gaining these privileges as well, the kernel and user code must be |
|
careful to prevent the parent from doing anything that could subvert the |
|
child. For example: |
|
|
|
- The dynamic loader handles ``LD_*`` environment variables differently if |
|
a program is setuid. |
|
|
|
- chroot is disallowed to unprivileged processes, since it would allow |
|
``/etc/passwd`` to be replaced from the point of view of a process that |
|
inherited chroot. |
|
|
|
- The exec code has special handling for ptrace. |
|
|
|
These are all ad-hoc fixes. The ``no_new_privs`` bit (since Linux 3.5) is a |
|
new, generic mechanism to make it safe for a process to modify its |
|
execution environment in a manner that persists across execve. Any task |
|
can set ``no_new_privs``. Once the bit is set, it is inherited across fork, |
|
clone, and execve and cannot be unset. With ``no_new_privs`` set, ``execve()`` |
|
promises not to grant the privilege to do anything that could not have |
|
been done without the execve call. For example, the setuid and setgid |
|
bits will no longer change the uid or gid; file capabilities will not |
|
add to the permitted set, and LSMs will not relax constraints after |
|
execve. |
|
|
|
To set ``no_new_privs``, use:: |
|
|
|
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
|
|
|
Be careful, though: LSMs might also not tighten constraints on exec |
|
in ``no_new_privs`` mode. (This means that setting up a general-purpose |
|
service launcher to set ``no_new_privs`` before execing daemons may |
|
interfere with LSM-based sandboxing.) |
|
|
|
Note that ``no_new_privs`` does not prevent privilege changes that do not |
|
involve ``execve()``. An appropriately privileged task can still call |
|
``setuid(2)`` and receive SCM_RIGHTS datagrams. |
|
|
|
There are two main use cases for ``no_new_privs`` so far: |
|
|
|
- Filters installed for the seccomp mode 2 sandbox persist across |
|
execve and can change the behavior of newly-executed programs. |
|
Unprivileged users are therefore only allowed to install such filters |
|
if ``no_new_privs`` is set. |
|
|
|
- By itself, ``no_new_privs`` can be used to reduce the attack surface |
|
available to an unprivileged user. If everything running with a |
|
given uid has ``no_new_privs`` set, then that uid will be unable to |
|
escalate its privileges by directly attacking setuid, setgid, and |
|
fcap-using binaries; it will need to compromise something without the |
|
``no_new_privs`` bit set first. |
|
|
|
In the future, other potentially dangerous kernel features could become |
|
available to unprivileged tasks if ``no_new_privs`` is set. In principle, |
|
several options to ``unshare(2)`` and ``clone(2)`` would be safe when |
|
``no_new_privs`` is set, and ``no_new_privs`` + ``chroot`` is considerable less |
|
dangerous than chroot by itself.
|
|
|