← Documents Documentation/userspace-api/no_new_privs.rst GitHub 원문 ↗

Linux 6.18.37 · 사용자 공간 API

새 권한 금지 플래그

execve가 새 권한을 부여하지 못하게 하는 no_new_privs의 보장, 설정법, 제약과 사용 사례를 설명합니다.

Source pathDocumentation/userspace-api/no_new_privs.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

no_new_privs.rst:1-63

`no_new_privs`는 샌드박스 자체가 아니라 execve를 통한 권한 상승을 차단하는 단방향 프로세스 속성입니다. 상속되고 해제할 수 없다는 점, LSM이 exec에서 제약을 더 강화하지 않을 수도 있다는 점, execve 밖의 권한 변경은 막지 않는다는 점을 함께 고려해야 합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ======================
2 No New Privileges Flag
3 ======================
4
5 The execve system call can grant a newly-started program privileges that
6 its parent did not have. The most obvious examples are setuid/setgid
7 programs and file capabilities. To prevent the parent program from
8 gaining these privileges as well, the kernel and user code must be
9 careful to prevent the parent from doing anything that could subvert the
10 child. For example:
11
12 - The dynamic loader handles ``LD_*`` environment variables differently if
13 a program is setuid.
14
15 - chroot is disallowed to unprivileged processes, since it would allow
16 ``/etc/passwd`` to be replaced from the point of view of a process that
17 inherited chroot.
18
19 - The exec code has special handling for ptrace.
20
21 These are all ad-hoc fixes. The ``no_new_privs`` bit (since Linux 3.5) is a
22 new, generic mechanism to make it safe for a process to modify its
23 execution environment in a manner that persists across execve. Any task
24 can set ``no_new_privs``. Once the bit is set, it is inherited across fork,
25 clone, and execve and cannot be unset. With ``no_new_privs`` set, ``execve()``
26 promises not to grant the privilege to do anything that could not have
27 been done without the execve call. For example, the setuid and setgid
28 bits will no longer change the uid or gid; file capabilities will not
29 add to the permitted set, and LSMs will not relax constraints after
30 execve.
31
32 To set ``no_new_privs``, use::
33
34 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
35
36 Be careful, though: LSMs might also not tighten constraints on exec
37 in ``no_new_privs`` mode. (This means that setting up a general-purpose
38 service launcher to set ``no_new_privs`` before execing daemons may
39 interfere with LSM-based sandboxing.)
40
41 Note that ``no_new_privs`` does not prevent privilege changes that do not
42 involve ``execve()``. An appropriately privileged task can still call
43 ``setuid(2)`` and receive SCM_RIGHTS datagrams.
44
45 There are two main use cases for ``no_new_privs`` so far:
46
47 - Filters installed for the seccomp mode 2 sandbox persist across
48 execve and can change the behavior of newly-executed programs.
49 Unprivileged users are therefore only allowed to install such filters
50 if ``no_new_privs`` is set.
51
52 - By itself, ``no_new_privs`` can be used to reduce the attack surface
53 available to an unprivileged user. If everything running with a
54 given uid has ``no_new_privs`` set, then that uid will be unable to
55 escalate its privileges by directly attacking setuid, setgid, and
56 fcap-using binaries; it will need to compromise something without the
57 ``no_new_privs`` bit set first.
58
59 In the future, other potentially dangerous kernel features could become
60 available to unprivileged tasks if ``no_new_privs`` is set. In principle,
61 several options to ``unshare(2)`` and ``clone(2)`` would be safe when
62 ``no_new_privs`` is set, and ``no_new_privs`` + ``chroot`` is considerable less
63 dangerous than chroot by itself.
64

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

execve 권한 상승과 기존 방어

1-20

`execve` 시스템 호출은 새로 시작하는 프로그램에 부모가 갖지 않았던 권한을 부여할 수 있습니다. 대표적인 예는 setuid/setgid 프로그램과 파일 capability입니다. 부모가 이 권한을 함께 얻지 못하게 하려면 커널과 사용자 공간 코드가 부모의 자식 실행 환경 교란을 막아야 합니다.

execve 권한 전환을 둘러싼 기존 방어
영역특수 처리
동적 로더프로그램이 setuid이면 `LD_*` 환경 변수를 다르게 처리합니다.
chrootchroot를 물려받은 프로세스 관점에서 `/etc/passwd`를 바꾸는 공격을 막기 위해 비특권 프로세스의 chroot를 금지합니다.
ptraceexec 코드가 ptrace 상황을 별도로 처리합니다.

각 하위 시스템이 특수한 경우를 개별적으로 처리해 왔습니다.

======================
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.

no_new_privs의 보장과 설정

21-35

이러한 처리는 모두 임시방편입니다. Linux 3.5부터 제공되는 `no_new_privs` 비트는 프로세스가 `execve` 뒤에도 유지되는 실행 환경을 안전하게 변경하도록 하는 일반 메커니즘입니다.

어떤 태스크든 `no_new_privs`를 설정할 수 있습니다. 한 번 설정하면 fork, clone, execve를 거쳐 상속되며 해제할 수 없습니다.

`no_new_privs`가 설정된 상태에서 `execve()`는 호출 전에는 할 수 없었던 일을 가능하게 하는 권한을 부여하지 않겠다고 보장합니다. setuid와 setgid 비트는 uid나 gid를 바꾸지 않고, 파일 capability는 permitted 집합에 권한을 추가하지 않으며, LSM도 execve 뒤에 제약을 완화하지 않습니다.

다음 `prctl()` 호출로 플래그를 설정합니다.

prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
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);

LSM과 execve 밖의 권한 변경

36-44

주의할 점은 `no_new_privs` 모드에서 LSM이 exec 시 제약을 더 강화하지 않을 수도 있다는 것입니다. 범용 서비스 실행기가 데몬을 exec하기 전에 `no_new_privs`를 설정하면 LSM 기반 샌드박스와 충돌할 수 있습니다.

`no_new_privs`는 `execve()`가 관여하지 않는 권한 변경을 막지 않습니다. 필요한 권한을 가진 태스크는 여전히 `setuid(2)`를 호출할 수 있고 SCM_RIGHTS 데이터그램으로 파일 디스크립터를 받을 수 있습니다.

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.

현재 용도와 확장 가능성

45-63

현재 `no_new_privs`의 주요 용도는 두 가지입니다.

no_new_privs 주요 용도
용도효과
seccomp mode 2필터가 execve 뒤에도 유지되어 새 프로그램의 동작을 바꿀 수 있으므로 비특권 사용자는 `no_new_privs`가 설정된 경우에만 필터를 설치할 수 있습니다.
공격 표면 축소한 uid의 모든 프로세스가 플래그를 설정하면 setuid, setgid, 파일 capability 사용 바이너리를 직접 공격해 권한을 올릴 수 없고, 먼저 플래그가 없는 대상을 침해해야 합니다.

플래그는 execve를 가로지르는 정책의 안전 조건이 됩니다.

앞으로는 `no_new_privs`를 조건으로 잠재적으로 위험한 다른 커널 기능을 비특권 태스크에 허용할 수도 있습니다. 원칙적으로 `unshare(2)`와 `clone(2)`의 일부 옵션은 이 조건에서 안전해질 수 있고, `no_new_privs`와 결합한 `chroot`는 chroot 단독 사용보다 훨씬 덜 위험합니다.

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.