← Documents Documentation/admin-guide/LSM/ipe.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / LSM

Integrity Policy Enforcement (IPE)

IPE의 불변 속성 기반 신뢰 모델, policy 문법과 서명·배포·활성화 절차, audit event, dm-verity·fs-verity property와 예제 policy를 설명합니다.

Source pathDocumentation/admin-guide/LSM/ipe.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

불변 속성 기반 접근 제어

ipe.rst:1-139

IPE의 신뢰 모델, 적합한 사용 사례, 알려진 제한과 위협 범위를 설명합니다.

Policy 작성과 배포

ipe.rst:140-312

Rule 문법, DEFAULT, boot policy, PKCS#7 서명, securityfs 배포·활성화·삭제 절차를 정리합니다.

Mode와 audit event

ipe.rst:313-539

Permissive/enforced mode와 네 종류의 audit record, field 및 error code를 설명합니다.

Operation과 무결성 property

ipe.rst:540-702

`op`, `action`, initramfs, dm-verity, fs-verity 관련 property를 설명합니다.

Policy 예제와 참고 자료

ipe.rst:703-824

허용·거부 policy 예제, IMA·LoadPin 비교와 관련 자료를 제공합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 Integrity Policy Enforcement (IPE)
4 ==================================
5
6 .. NOTE::
7
8 This is the documentation for admins, system builders, or individuals
9 attempting to use IPE. If you're looking for more developer-focused
10 documentation about IPE please see :doc:`the design docs </security/ipe>`.
11
12 Overview
13 --------
14
15 Integrity Policy Enforcement (IPE) is a Linux Security Module that takes a
16 complementary approach to access control. Unlike traditional access control
17 mechanisms that rely on labels and paths for decision-making, IPE focuses
18 on the immutable security properties inherent to system components. These
19 properties are fundamental attributes or features of a system component
20 that cannot be altered, ensuring a consistent and reliable basis for
21 security decisions.
22
23 To elaborate, in the context of IPE, system components primarily refer to
24 files or the devices these files reside on. However, this is just a
25 starting point. The concept of system components is flexible and can be
26 extended to include new elements as the system evolves. The immutable
27 properties include the origin of a file, which remains constant and
28 unchangeable over time. For example, IPE policies can be crafted to trust
29 files originating from the initramfs. Since initramfs is typically verified
30 by the bootloader, its files are deemed trustworthy; "file is from
31 initramfs" becomes an immutable property under IPE's consideration.
32
33 The immutable property concept extends to the security features enabled on
34 a file's origin, such as dm-verity or fs-verity, which provide a layer of
35 integrity and trust. For example, IPE allows the definition of policies
36 that trust files from a dm-verity protected device. dm-verity ensures the
37 integrity of an entire device by providing a verifiable and immutable state
38 of its contents. Similarly, fs-verity offers filesystem-level integrity
39 checks, allowing IPE to enforce policies that trust files protected by
40 fs-verity. These two features cannot be turned off once established, so
41 they are considered immutable properties. These examples demonstrate how
42 IPE leverages immutable properties, such as a file's origin and its
43 integrity protection mechanisms, to make access control decisions.
44
45 For the IPE policy, specifically, it grants the ability to enforce
46 stringent access controls by assessing security properties against
47 reference values defined within the policy. This assessment can be based on
48 the existence of a security property (e.g., verifying if a file originates
49 from initramfs) or evaluating the internal state of an immutable security
50 property. The latter includes checking the roothash of a dm-verity
51 protected device, determining whether dm-verity possesses a valid
52 signature, assessing the digest of a fs-verity protected file, or
53 determining whether fs-verity possesses a valid built-in signature. This
54 nuanced approach to policy enforcement enables a highly secure and
55 customizable system defense mechanism, tailored to specific security
56 requirements and trust models.
57
58 To enable IPE, ensure that ``CONFIG_SECURITY_IPE`` (under
59 :menuselection:`Security -> Integrity Policy Enforcement (IPE)`) config
60 option is enabled.
61
62 Use Cases
63 ---------
64
65 IPE works best in fixed-function devices: devices in which their purpose
66 is clearly defined and not supposed to be changed (e.g. network firewall
67 device in a data center, an IoT device, etcetera), where all software and
68 configuration is built and provisioned by the system owner.
69
70 IPE is a long-way off for use in general-purpose computing: the Linux
71 community as a whole tends to follow a decentralized trust model (known as
72 the web of trust), which IPE has no support for it yet. Instead, IPE
73 supports PKI (public key infrastructure), which generally designates a
74 set of trusted entities that provide a measure of absolute trust.
75
76 Additionally, while most packages are signed today, the files inside
77 the packages (for instance, the executables), tend to be unsigned. This
78 makes it difficult to utilize IPE in systems where a package manager is
79 expected to be functional, without major changes to the package manager
80 and ecosystem behind it.
81
82 The digest_cache LSM [#digest_cache_lsm]_ is a system that when combined with IPE,
83 could be used to enable and support general-purpose computing use cases.
84
85 Known Limitations
86 -----------------
87
88 IPE cannot verify the integrity of anonymous executable memory, such as
89 the trampolines created by gcc closures and libffi (<3.4.2), or JIT'd code.
90 Unfortunately, as this is dynamically generated code, there is no way
91 for IPE to ensure the integrity of this code to form a trust basis.
92
93 IPE cannot verify the integrity of programs written in interpreted
94 languages when these scripts are invoked by passing these program files
95 to the interpreter. This is because the way interpreters execute these
96 files; the scripts themselves are not evaluated as executable code
97 through one of IPE's hooks, but they are merely text files that are read
98 (as opposed to compiled executables) [#interpreters]_.
99
100 Threat Model
101 ------------
102
103 IPE specifically targets the risk of tampering with user-space executable
104 code after the kernel has initially booted, including the kernel modules
105 loaded from userspace via ``modprobe`` or ``insmod``.
106
107 To illustrate, consider a scenario where an untrusted binary, possibly
108 malicious, is downloaded along with all necessary dependencies, including a
109 loader and libc. The primary function of IPE in this context is to prevent
110 the execution of such binaries and their dependencies.
111
112 IPE achieves this by verifying the integrity and authenticity of all
113 executable code before allowing them to run. It conducts a thorough
114 check to ensure that the code's integrity is intact and that they match an
115 authorized reference value (digest, signature, etc) as per the defined
116 policy. If a binary does not pass this verification process, either
117 because its integrity has been compromised or it does not meet the
118 authorization criteria, IPE will deny its execution. Additionally, IPE
119 generates audit logs which may be utilized to detect and analyze failures
120 resulting from policy violation.
121
122 Tampering threat scenarios include modification or replacement of
123 executable code by a range of actors including:
124
125 - Actors with physical access to the hardware
126 - Actors with local network access to the system
127 - Actors with access to the deployment system
128 - Compromised internal systems under external control
129 - Malicious end users of the system
130 - Compromised end users of the system
131 - Remote (external) compromise of the system
132
133 IPE does not mitigate threats arising from malicious but authorized
134 developers (with access to a signing certificate), or compromised
135 developer tools used by them (i.e. return-oriented programming attacks).
136 Additionally, IPE draws hard security boundary between userspace and
137 kernelspace. As a result, kernel-level exploits are considered outside
138 the scope of IPE and mitigation is left to other mechanisms.
139
140 Policy
141 ------
142
143 IPE policy is a plain-text [#devdoc]_ policy composed of multiple statements
144 over several lines. There is one required line, at the top of the
145 policy, indicating the policy name, and the policy version, for
146 instance::
147
148 policy_name=Ex_Policy policy_version=0.0.0
149
150 The policy name is a unique key identifying this policy in a human
151 readable name. This is used to create nodes under securityfs as well as
152 uniquely identify policies to deploy new policies vs update existing
153 policies.
154
155 The policy version indicates the current version of the policy (NOT the
156 policy syntax version). This is used to prevent rollback of policy to
157 potentially insecure previous versions of the policy.
158
159 The next portion of IPE policy are rules. Rules are formed by key=value
160 pairs, known as properties. IPE rules require two properties: ``action``,
161 which determines what IPE does when it encounters a match against the
162 rule, and ``op``, which determines when the rule should be evaluated.
163 The ordering is significant, a rule must start with ``op``, and end with
164 ``action``. Thus, a minimal rule is::
165
166 op=EXECUTE action=ALLOW
167
168 This example will allow any execution. Additional properties are used to
169 assess immutable security properties about the files being evaluated.
170 These properties are intended to be descriptions of systems within the
171 kernel that can provide a measure of integrity verification, such that IPE
172 can determine the trust of the resource based on the value of the property.
173
174 Rules are evaluated top-to-bottom. As a result, any revocation rules,
175 or denies should be placed early in the file to ensure that these rules
176 are evaluated before a rule with ``action=ALLOW``.
177
178 IPE policy supports comments. The character '#' will function as a
179 comment, ignoring all characters to the right of '#' until the newline.
180
181 The default behavior of IPE evaluations can also be expressed in policy,
182 through the ``DEFAULT`` statement. This can be done at a global level,
183 or a per-operation level::
184
185 # Global
186 DEFAULT action=ALLOW
187
188 # Operation Specific
189 DEFAULT op=EXECUTE action=ALLOW
190
191 A default must be set for all known operations in IPE. If you want to
192 preserve older policies being compatible with newer kernels that can introduce
193 new operations, set a global default of ``ALLOW``, then override the
194 defaults on a per-operation basis (as above).
195
196 With configurable policy-based LSMs, there's several issues with
197 enforcing the configurable policies at startup, around reading and
198 parsing the policy:
199
200 1. The kernel *should* not read files from userspace, so directly reading
201 the policy file is prohibited.
202 2. The kernel command line has a character limit, and one kernel module
203 should not reserve the entire character limit for its own
204 configuration.
205 3. There are various boot loaders in the kernel ecosystem, so handing
206 off a memory block would be costly to maintain.
207
208 As a result, IPE has addressed this problem through a concept of a "boot
209 policy". A boot policy is a minimal policy which is compiled into the
210 kernel. This policy is intended to get the system to a state where
211 userspace is set up and ready to receive commands, at which point a more
212 complex policy can be deployed via securityfs. The boot policy can be
213 specified via ``SECURITY_IPE_BOOT_POLICY`` config option, which accepts
214 a path to a plain-text version of the IPE policy to apply. This policy
215 will be compiled into the kernel. If not specified, IPE will be disabled
216 until a policy is deployed and activated through securityfs.
217
218 Deploying Policies
219 ~~~~~~~~~~~~~~~~~~
220
221 Policies can be deployed from userspace through securityfs. These policies
222 are signed through the PKCS#7 message format to enforce some level of
223 authorization of the policies (prohibiting an attacker from gaining
224 unconstrained root, and deploying an "allow all" policy). These
225 policies must be signed by a certificate that chains to the
226 ``SYSTEM_TRUSTED_KEYRING``, or to the secondary and/or platform keyrings if
227 ``CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING`` and/or
228 ``CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING`` are enabled, respectively.
229 With openssl, the policy can be signed by::
230
231 openssl smime -sign \
232 -in "$MY_POLICY" \
233 -signer "$MY_CERTIFICATE" \
234 -inkey "$MY_PRIVATE_KEY" \
235 -noattr \
236 -nodetach \
237 -nosmimecap \
238 -outform der \
239 -out "$MY_POLICY.p7b"
240
241 Deploying the policies is done through securityfs, through the
242 ``new_policy`` node. To deploy a policy, simply cat the file into the
243 securityfs node::
244
245 cat "$MY_POLICY.p7b" > /sys/kernel/security/ipe/new_policy
246
247 Upon success, this will create one subdirectory under
248 ``/sys/kernel/security/ipe/policies/``. The subdirectory will be the
249 ``policy_name`` field of the policy deployed, so for the example above,
250 the directory will be ``/sys/kernel/security/ipe/policies/Ex_Policy``.
251 Within this directory, there will be seven files: ``pkcs7``, ``policy``,
252 ``name``, ``version``, ``active``, ``update``, and ``delete``.
253
254 The ``pkcs7`` file is read-only. Reading it returns the raw PKCS#7 data
255 that was provided to the kernel, representing the policy. If the policy being
256 read is the boot policy, this will return ``ENOENT``, as it is not signed.
257
258 The ``policy`` file is read only. Reading it returns the PKCS#7 inner
259 content of the policy, which will be the plain text policy.
260
261 The ``active`` file is used to set a policy as the currently active policy.
262 This file is rw, and accepts a value of ``"1"`` to set the policy as active.
263 Since only a single policy can be active at one time, all other policies
264 will be marked inactive. The policy being marked active must have a policy
265 version greater or equal to the currently-running version.
266
267 The ``update`` file is used to update a policy that is already present
268 in the kernel. This file is write-only and accepts a PKCS#7 signed
269 policy. Two checks will always be performed on this policy: First, the
270 ``policy_names`` must match with the updated version and the existing
271 version. Second the updated policy must have a policy version greater than
272 the currently-running version. This is to prevent rollback attacks.
273
274 The ``delete`` file is used to remove a policy that is no longer needed.
275 This file is write-only and accepts a value of ``1`` to delete the policy.
276 On deletion, the securityfs node representing the policy will be removed.
277 However, delete the current active policy is not allowed and will return
278 an operation not permitted error.
279
280 Similarly, writing to both ``update`` and ``new_policy`` could result in
281 bad message(policy syntax error) or file exists error. The latter error happens
282 when trying to deploy a policy with a ``policy_name`` while the kernel already
283 has a deployed policy with the same ``policy_name``.
284
285 Deploying a policy will *not* cause IPE to start enforcing the policy. IPE will
286 only enforce the policy marked active. Note that only one policy can be active
287 at a time.
288
289 Once deployment is successful, the policy can be activated, by writing file
290 ``/sys/kernel/security/ipe/policies/$policy_name/active``.
291 For example, the ``Ex_Policy`` can be activated by::
292
293 echo 1 > "/sys/kernel/security/ipe/policies/Ex_Policy/active"
294
295 From above point on, ``Ex_Policy`` is now the enforced policy on the
296 system.
297
298 IPE also provides a way to delete policies. This can be done via the
299 ``delete`` securityfs node,
300 ``/sys/kernel/security/ipe/policies/$policy_name/delete``.
301 Writing ``1`` to that file deletes the policy::
302
303 echo 1 > "/sys/kernel/security/ipe/policies/$policy_name/delete"
304
305 There is only one requirement to delete a policy: the policy being deleted
306 must be inactive.
307
308 .. NOTE::
309
310 If a traditional MAC system is enabled (SELinux, apparmor, smack), all
311 writes to ipe's securityfs nodes require ``CAP_MAC_ADMIN``.
312
313 Modes
314 ~~~~~
315
316 IPE supports two modes of operation: permissive (similar to SELinux's
317 permissive mode) and enforced. In permissive mode, all events are
318 checked and policy violations are logged, but the policy is not really
319 enforced. This allows users to test policies before enforcing them.
320
321 The default mode is enforce, and can be changed via the kernel command
322 line parameter ``ipe.enforce=(0|1)``, or the securityfs node
323 ``/sys/kernel/security/ipe/enforce``.
324
325 .. NOTE::
326
327 If a traditional MAC system is enabled (SELinux, apparmor, smack, etcetera),
328 all writes to ipe's securityfs nodes require ``CAP_MAC_ADMIN``.
329
330 Audit Events
331 ~~~~~~~~~~~~
332
333 1420 AUDIT_IPE_ACCESS
334 ^^^^^^^^^^^^^^^^^^^^^
335 Event Examples::
336
337 type=1420 audit(1653364370.067:61): ipe_op=EXECUTE ipe_hook=MMAP enforcing=1 pid=2241 comm="ld-linux.so" path="/deny/lib/libc.so.6" dev="sda2" ino=14549020 rule="DEFAULT action=DENY"
338 type=1300 audit(1653364370.067:61): SYSCALL arch=c000003e syscall=9 success=no exit=-13 a0=7f1105a28000 a1=195000 a2=5 a3=812 items=0 ppid=2219 pid=2241 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="ld-linux.so" exe="/tmp/ipe-test/lib/ld-linux.so" subj=unconfined key=(null)
339 type=1327 audit(1653364370.067:61): 707974686F6E3300746573742F6D61696E2E7079002D6E00
340
341 type=1420 audit(1653364735.161:64): ipe_op=EXECUTE ipe_hook=MMAP enforcing=1 pid=2472 comm="mmap_test" path=? dev=? ino=? rule="DEFAULT action=DENY"
342 type=1300 audit(1653364735.161:64): SYSCALL arch=c000003e syscall=9 success=no exit=-13 a0=0 a1=1000 a2=4 a3=21 items=0 ppid=2219 pid=2472 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="mmap_test" exe="/root/overlake_test/upstream_test/vol_fsverity/bin/mmap_test" subj=unconfined key=(null)
343 type=1327 audit(1653364735.161:64): 707974686F6E3300746573742F6D61696E2E7079002D6E00
344
345 This event indicates that IPE made an access control decision; the IPE
346 specific record (1420) is always emitted in conjunction with a
347 ``AUDITSYSCALL`` record.
348
349 Determining whether IPE is in permissive or enforced mode can be derived
350 from ``success`` property and exit code of the ``AUDITSYSCALL`` record.
351
352
353 Field descriptions:
354
355 +-----------+------------+-----------+---------------------------------------------------------------------------------+
356 | Field | Value Type | Optional? | Description of Value |
357 +===========+============+===========+=================================================================================+
358 | ipe_op | string | No | The IPE operation name associated with the log |
359 +-----------+------------+-----------+---------------------------------------------------------------------------------+
360 | ipe_hook | string | No | The name of the LSM hook that triggered the IPE event |
361 +-----------+------------+-----------+---------------------------------------------------------------------------------+
362 | enforcing | integer | No | The current IPE enforcing state 1 is in enforcing mode, 0 is in permissive mode |
363 +-----------+------------+-----------+---------------------------------------------------------------------------------+
364 | pid | integer | No | The pid of the process that triggered the IPE event. |
365 +-----------+------------+-----------+---------------------------------------------------------------------------------+
366 | comm | string | No | The command line program name of the process that triggered the IPE event |
367 +-----------+------------+-----------+---------------------------------------------------------------------------------+
368 | path | string | Yes | The absolute path to the evaluated file |
369 +-----------+------------+-----------+---------------------------------------------------------------------------------+
370 | ino | integer | Yes | The inode number of the evaluated file |
371 +-----------+------------+-----------+---------------------------------------------------------------------------------+
372 | dev | string | Yes | The device name of the evaluated file, e.g. vda |
373 +-----------+------------+-----------+---------------------------------------------------------------------------------+
374 | rule | string | No | The matched policy rule |
375 +-----------+------------+-----------+---------------------------------------------------------------------------------+
376
377 1421 AUDIT_IPE_CONFIG_CHANGE
378 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
379
380 Event Example::
381
382 type=1421 audit(1653425583.136:54): old_active_pol_name="Allow_All" old_active_pol_version=0.0.0 old_policy_digest=sha256:E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 new_active_pol_name="boot_verified" new_active_pol_version=0.0.0 new_policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F26765076DD8EED7B8F4DB auid=4294967295 ses=4294967295 lsm=ipe res=1
383 type=1300 audit(1653425583.136:54): SYSCALL arch=c000003e syscall=1 success=yes exit=2 a0=3 a1=5596fcae1fb0 a2=2 a3=2 items=0 ppid=184 pid=229 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4294967295 comm="python3" exe="/usr/bin/python3.10" key=(null)
384 type=1327 audit(1653425583.136:54): PROCTITLE proctitle=707974686F6E3300746573742F6D61696E2E7079002D66002E2
385
386 This event indicates that IPE switched the active poliy from one to another
387 along with the version and the hash digest of the two policies.
388 Note IPE can only have one policy active at a time, all access decision
389 evaluation is based on the current active policy.
390 The normal procedure to deploy a new policy is loading the policy to deploy
391 into the kernel first, then switch the active policy to it.
392
393 This record will always be emitted in conjunction with a ``AUDITSYSCALL`` record for the ``write`` syscall.
394
395 Field descriptions:
396
397 +------------------------+------------+-----------+---------------------------------------------------+
398 | Field | Value Type | Optional? | Description of Value |
399 +========================+============+===========+===================================================+
400 | old_active_pol_name | string | Yes | The name of previous active policy |
401 +------------------------+------------+-----------+---------------------------------------------------+
402 | old_active_pol_version | string | Yes | The version of previous active policy |
403 +------------------------+------------+-----------+---------------------------------------------------+
404 | old_policy_digest | string | Yes | The hash of previous active policy |
405 +------------------------+------------+-----------+---------------------------------------------------+
406 | new_active_pol_name | string | No | The name of current active policy |
407 +------------------------+------------+-----------+---------------------------------------------------+
408 | new_active_pol_version | string | No | The version of current active policy |
409 +------------------------+------------+-----------+---------------------------------------------------+
410 | new_policy_digest | string | No | The hash of current active policy |
411 +------------------------+------------+-----------+---------------------------------------------------+
412 | auid | integer | No | The login user ID |
413 +------------------------+------------+-----------+---------------------------------------------------+
414 | ses | integer | No | The login session ID |
415 +------------------------+------------+-----------+---------------------------------------------------+
416 | lsm | string | No | The lsm name associated with the event |
417 +------------------------+------------+-----------+---------------------------------------------------+
418 | res | integer | No | The result of the audited operation(success/fail) |
419 +------------------------+------------+-----------+---------------------------------------------------+
420
421 1422 AUDIT_IPE_POLICY_LOAD
422 ^^^^^^^^^^^^^^^^^^^^^^^^^^
423
424 Event Example::
425
426 type=1422 audit(1653425529.927:53): policy_name="boot_verified" policy_version=0.0.0 policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F26765076DD8EED7B8F4DB auid=4294967295 ses=4294967295 lsm=ipe res=1 errno=0
427 type=1300 audit(1653425529.927:53): arch=c000003e syscall=1 success=yes exit=2567 a0=3 a1=5596fcae1fb0 a2=a07 a3=2 items=0 ppid=184 pid=229 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4294967295 comm="python3" exe="/usr/bin/python3.10" key=(null)
428 type=1327 audit(1653425529.927:53): PROCTITLE proctitle=707974686F6E3300746573742F6D61696E2E7079002D66002E2E
429
430 This record indicates a new policy has been loaded into the kernel with the policy name, policy version and policy hash.
431
432 This record will always be emitted in conjunction with a ``AUDITSYSCALL`` record for the ``write`` syscall.
433
434 Field descriptions:
435
436 +----------------+------------+-----------+-------------------------------------------------------------+
437 | Field | Value Type | Optional? | Description of Value |
438 +================+============+===========+=============================================================+
439 | policy_name | string | Yes | The policy_name |
440 +----------------+------------+-----------+-------------------------------------------------------------+
441 | policy_version | string | Yes | The policy_version |
442 +----------------+------------+-----------+-------------------------------------------------------------+
443 | policy_digest | string | Yes | The policy hash |
444 +----------------+------------+-----------+-------------------------------------------------------------+
445 | auid | integer | No | The login user ID |
446 +----------------+------------+-----------+-------------------------------------------------------------+
447 | ses | integer | No | The login session ID |
448 +----------------+------------+-----------+-------------------------------------------------------------+
449 | lsm | string | No | The lsm name associated with the event |
450 +----------------+------------+-----------+-------------------------------------------------------------+
451 | res | integer | No | The result of the audited operation(success/fail) |
452 +----------------+------------+-----------+-------------------------------------------------------------+
453 | errno | integer | No | Error code from policy loading operations (see table below) |
454 +----------------+------------+-----------+-------------------------------------------------------------+
455
456 Policy error codes (errno):
457
458 The following table lists the error codes that may appear in the errno field while loading or updating the policy:
459
460 +----------------+--------------------------------------------------------+
461 | Error Code | Description |
462 +================+========================================================+
463 | 0 | Success |
464 +----------------+--------------------------------------------------------+
465 | -EPERM | Insufficient permission |
466 +----------------+--------------------------------------------------------+
467 | -EEXIST | Same name policy already deployed |
468 +----------------+--------------------------------------------------------+
469 | -EBADMSG | Policy is invalid |
470 +----------------+--------------------------------------------------------+
471 | -ENOMEM | Out of memory (OOM) |
472 +----------------+--------------------------------------------------------+
473 | -ERANGE | Policy version number overflow |
474 +----------------+--------------------------------------------------------+
475 | -EINVAL | Policy version parsing error |
476 +----------------+--------------------------------------------------------+
477 | -ENOKEY | Key used to sign the IPE policy not found in keyring |
478 +----------------+--------------------------------------------------------+
479 | -EKEYREJECTED | Policy signature verification failed |
480 +----------------+--------------------------------------------------------+
481 | -ESTALE | Attempting to update an IPE policy with older version |
482 +----------------+--------------------------------------------------------+
483 | -ENOENT | Policy was deleted while updating |
484 +----------------+--------------------------------------------------------+
485
486 1404 AUDIT_MAC_STATUS
487 ^^^^^^^^^^^^^^^^^^^^^
488
489 Event Examples::
490
491 type=1404 audit(1653425689.008:55): enforcing=0 old_enforcing=1 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1
492 type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=)
493 type=1327 audit(1653425689.008:55): proctitle="-bash"
494
495 type=1404 audit(1653425689.008:55): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1
496 type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=)
497 type=1327 audit(1653425689.008:55): proctitle="-bash"
498
499 This record will always be emitted in conjunction with a ``AUDITSYSCALL`` record for the ``write`` syscall.
500
501 Field descriptions:
502
503 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
504 | Field | Value Type | Optional? | Description of Value |
505 +===============+============+===========+=================================================================================================+
506 | enforcing | integer | No | The enforcing state IPE is being switched to, 1 is in enforcing mode, 0 is in permissive mode |
507 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
508 | old_enforcing | integer | No | The enforcing state IPE is being switched from, 1 is in enforcing mode, 0 is in permissive mode |
509 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
510 | auid | integer | No | The login user ID |
511 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
512 | ses | integer | No | The login session ID |
513 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
514 | enabled | integer | No | The new TTY audit enabled setting |
515 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
516 | old-enabled | integer | No | The old TTY audit enabled setting |
517 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
518 | lsm | string | No | The lsm name associated with the event |
519 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
520 | res | integer | No | The result of the audited operation(success/fail) |
521 +---------------+------------+-----------+-------------------------------------------------------------------------------------------------+
522
523
524 Success Auditing
525 ^^^^^^^^^^^^^^^^
526
527 IPE supports success auditing. When enabled, all events that pass IPE
528 policy and are not blocked will emit an audit event. This is disabled by
529 default, and can be enabled via the kernel command line
530 ``ipe.success_audit=(0|1)`` or
531 ``/sys/kernel/security/ipe/success_audit`` securityfs file.
532
533 This is *very* noisy, as IPE will check every userspace binary on the
534 system, but is useful for debugging policies.
535
536 .. NOTE::
537
538 If a traditional MAC system is enabled (SELinux, apparmor, smack, etcetera),
539 all writes to ipe's securityfs nodes require ``CAP_MAC_ADMIN``.
540
541 Properties
542 ----------
543
544 As explained above, IPE properties are ``key=value`` pairs expressed in IPE
545 policy. Two properties are built-into the policy parser: 'op' and 'action'.
546 The other properties are used to restrict immutable security properties
547 about the files being evaluated. Currently those properties are:
548 '``boot_verified``', '``dmverity_signature``', '``dmverity_roothash``',
549 '``fsverity_signature``', '``fsverity_digest``'. A description of all
550 properties supported by IPE are listed below:
551
552 op
553 ~~
554
555 Indicates the operation for a rule to apply to. Must be in every rule,
556 as the first token. IPE supports the following operations:
557
558 ``EXECUTE``
559
560 Pertains to any file attempting to be executed, or loaded as an
561 executable.
562
563 ``FIRMWARE``:
564
565 Pertains to firmware being loaded via the firmware_class interface.
566 This covers both the preallocated buffer and the firmware file
567 itself.
568
569 ``KMODULE``:
570
571 Pertains to loading kernel modules via ``modprobe`` or ``insmod``.
572
573 ``KEXEC_IMAGE``:
574
575 Pertains to kernel images loading via ``kexec``.
576
577 ``KEXEC_INITRAMFS``
578
579 Pertains to initrd images loading via ``kexec --initrd``.
580
581 ``POLICY``:
582
583 Controls loading policies via reading a kernel-space initiated read.
584
585 An example of such is loading IMA policies by writing the path
586 to the policy file to ``$securityfs/ima/policy``
587
588 ``X509_CERT``:
589
590 Controls loading IMA certificates through the Kconfigs,
591 ``CONFIG_IMA_X509_PATH`` and ``CONFIG_EVM_X509_PATH``.
592
593 action
594 ~~~~~~
595
596 Determines what IPE should do when a rule matches. Must be in every
597 rule, as the final clause. Can be one of:
598
599 ``ALLOW``:
600
601 If the rule matches, explicitly allow access to the resource to proceed
602 without executing any more rules.
603
604 ``DENY``:
605
606 If the rule matches, explicitly prohibit access to the resource to
607 proceed without executing any more rules.
608
609 boot_verified
610 ~~~~~~~~~~~~~
611
612 This property can be utilized for authorization of files from initramfs.
613 The format of this property is::
614
615 boot_verified=(TRUE|FALSE)
616
617
618 .. WARNING::
619
620 This property will trust files from initramfs(rootfs). It should
621 only be used during early booting stage. Before mounting the real
622 rootfs on top of the initramfs, initramfs script will recursively
623 remove all files and directories on the initramfs. This is typically
624 implemented by using switch_root(8) [#switch_root]_. Therefore the
625 initramfs will be empty and not accessible after the real
626 rootfs takes over. It is advised to switch to a different policy
627 that doesn't rely on the property after this point.
628 This ensures that the trust policies remain relevant and effective
629 throughout the system's operation.
630
631 dmverity_roothash
632 ~~~~~~~~~~~~~~~~~
633
634 This property can be utilized for authorization or revocation of
635 specific dm-verity volumes, identified via their root hashes. It has a
636 dependency on the DM_VERITY module. This property is controlled by
637 the ``IPE_PROP_DM_VERITY`` config option, it will be automatically
638 selected when ``SECURITY_IPE`` and ``DM_VERITY`` are all enabled.
639 The format of this property is::
640
641 dmverity_roothash=DigestName:HexadecimalString
642
643 The supported DigestNames for dmverity_roothash are [#dmveritydigests]_
644
645 + blake2b-512
646 + blake2s-256
647 + sha256
648 + sha384
649 + sha512
650 + sha3-224
651 + sha3-256
652 + sha3-384
653 + sha3-512
654 + sm3
655 + rmd160
656
657 dmverity_signature
658 ~~~~~~~~~~~~~~~~~~
659
660 This property can be utilized for authorization of all dm-verity
661 volumes that have a signed roothash that validated by a keyring
662 specified by dm-verity's configuration, either the system trusted
663 keyring, or the secondary keyring. It depends on
664 ``DM_VERITY_VERIFY_ROOTHASH_SIG`` config option and is controlled by
665 the ``IPE_PROP_DM_VERITY_SIGNATURE`` config option, it will be automatically
666 selected when ``SECURITY_IPE``, ``DM_VERITY`` and
667 ``DM_VERITY_VERIFY_ROOTHASH_SIG`` are all enabled.
668 The format of this property is::
669
670 dmverity_signature=(TRUE|FALSE)
671
672 fsverity_digest
673 ~~~~~~~~~~~~~~~
674
675 This property can be utilized for authorization of specific fsverity
676 enabled files, identified via their fsverity digests.
677 It depends on ``FS_VERITY`` config option and is controlled by
678 the ``IPE_PROP_FS_VERITY`` config option, it will be automatically
679 selected when ``SECURITY_IPE`` and ``FS_VERITY`` are all enabled.
680 The format of this property is::
681
682 fsverity_digest=DigestName:HexadecimalString
683
684 The supported DigestNames for fsverity_digest are [#fsveritydigest]_
685
686 + sha256
687 + sha512
688
689 fsverity_signature
690 ~~~~~~~~~~~~~~~~~~
691
692 This property is used to authorize all fs-verity enabled files that have
693 been verified by fs-verity's built-in signature mechanism. The signature
694 verification relies on a key stored within the ".fs-verity" keyring. It
695 depends on ``FS_VERITY_BUILTIN_SIGNATURES`` config option and
696 it is controlled by the ``IPE_PROP_FS_VERITY`` config option,
697 it will be automatically selected when ``SECURITY_IPE``, ``FS_VERITY``
698 and ``FS_VERITY_BUILTIN_SIGNATURES`` are all enabled.
699 The format of this property is::
700
701 fsverity_signature=(TRUE|FALSE)
702
703 Policy Examples
704 ---------------
705
706 Allow all
707 ~~~~~~~~~
708
709 ::
710
711 policy_name=Allow_All policy_version=0.0.0
712 DEFAULT action=ALLOW
713
714 Allow only initramfs
715 ~~~~~~~~~~~~~~~~~~~~
716
717 ::
718
719 policy_name=Allow_Initramfs policy_version=0.0.0
720 DEFAULT action=DENY
721
722 op=EXECUTE boot_verified=TRUE action=ALLOW
723
724 Allow any signed and validated dm-verity volume and the initramfs
725 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
726
727 ::
728
729 policy_name=Allow_Signed_DMV_And_Initramfs policy_version=0.0.0
730 DEFAULT action=DENY
731
732 op=EXECUTE boot_verified=TRUE action=ALLOW
733 op=EXECUTE dmverity_signature=TRUE action=ALLOW
734
735 Prohibit execution from a specific dm-verity volume
736 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
737
738 ::
739
740 policy_name=Deny_DMV_By_Roothash policy_version=0.0.0
741 DEFAULT action=DENY
742
743 op=EXECUTE dmverity_roothash=sha256:cd2c5bae7c6c579edaae4353049d58eb5f2e8be0244bf05345bc8e5ed257baff action=DENY
744
745 op=EXECUTE boot_verified=TRUE action=ALLOW
746 op=EXECUTE dmverity_signature=TRUE action=ALLOW
747
748 Allow only a specific dm-verity volume
749 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
750
751 ::
752
753 policy_name=Allow_DMV_By_Roothash policy_version=0.0.0
754 DEFAULT action=DENY
755
756 op=EXECUTE dmverity_roothash=sha256:401fcec5944823ae12f62726e8184407a5fa9599783f030dec146938 action=ALLOW
757
758 Allow any fs-verity file with a valid built-in signature
759 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
760
761 ::
762
763 policy_name=Allow_Signed_And_Validated_FSVerity policy_version=0.0.0
764 DEFAULT action=DENY
765
766 op=EXECUTE fsverity_signature=TRUE action=ALLOW
767
768 Allow execution of a specific fs-verity file
769 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
770
771 ::
772
773 policy_name=ALLOW_FSV_By_Digest policy_version=0.0.0
774 DEFAULT action=DENY
775
776 op=EXECUTE fsverity_digest=sha256:fd88f2b8824e197f850bf4c5109bea5cf0ee38104f710843bb72da796ba5af9e action=ALLOW
777
778 Additional Information
779 ----------------------
780
781 - `Github Repository <https://github.com/microsoft/ipe>`_
782 - :doc:`Developer and design docs for IPE </security/ipe>`
783
784 FAQ
785 ---
786
787 Q:
788 What's the difference between other LSMs which provide a measure of
789 trust-based access control?
790
791 A:
792
793 In general, there's two other LSMs that can provide similar functionality:
794 IMA, and Loadpin.
795
796 IMA and IPE are functionally very similar. The significant difference between
797 the two is the policy. [#devdoc]_
798
799 Loadpin and IPE differ fairly dramatically, as Loadpin only covers the IPE's
800 kernel read operations, whereas IPE is capable of controlling execution
801 on top of kernel read. The trust model is also different; Loadpin roots its
802 trust in the initial super-block, whereas trust in IPE is stemmed from kernel
803 itself (via ``SYSTEM_TRUSTED_KEYS``).
804
805 -----------
806
807 .. [#digest_cache_lsm] https://lore.kernel.org/lkml/[email protected]/
808
809 .. [#interpreters] There is `some interest in solving this issue <https://lore.kernel.org/lkml/[email protected]/>`_.
810
811 .. [#devdoc] Please see :doc:`the design docs </security/ipe>` for more on
812 this topic.
813
814 .. [#switch_root] https://man7.org/linux/man-pages/man8/switch_root.8.html
815
816 .. [#dmveritydigests] These hash algorithms are based on values accepted by
817 the Linux crypto API; IPE does not impose any
818 restrictions on the digest algorithm itself;
819 thus, this list may be out of date.
820
821 .. [#fsveritydigest] These hash algorithms are based on values accepted by the
822 kernel's fsverity support; IPE does not impose any
823 restrictions on the digest algorithm itself;
824 thus, this list may be out of date.
825

3. 한국어 전문 번역

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

문서 대상

1-10

이 문서는 IPE를 사용하려는 관리자, 시스템 제작자, 개인을 위한 문서입니다. 개발자 중심의 IPE 설명은 `security/ipe`의 설계 문서를 참조하십시오.

개요

11-21

Integrity Policy Enforcement(IPE)는 접근 제어에 보완적 접근을 취하는 Linux Security Module입니다. 의사 결정에 label과 path를 사용하는 전통적 접근 제어와 달리 IPE는 시스템 구성 요소에 내재한 불변 보안 속성에 초점을 둡니다. 이러한 속성은 변경할 수 없는 구성 요소의 근본적 특성 또는 기능이므로 일관되고 신뢰할 수 있는 보안 결정의 기반이 됩니다.

구성 요소와 출처

22-32

IPE에서 시스템 구성 요소는 주로 file 또는 그 file이 위치한 device를 뜻하지만, 시스템이 발전하면 새로운 요소를 포함하도록 확장할 수 있습니다. 불변 속성에는 시간이 지나도 바뀌지 않는 file의 출처가 포함됩니다.

예를 들어 bootloader가 일반적으로 initramfs를 검증하므로 IPE policy는 initramfs에서 온 file을 신뢰하도록 작성할 수 있습니다. 이때 `file is from initramfs`는 IPE가 판단에 사용하는 불변 속성이 됩니다.

dm-verity와 fs-verity

33-43

불변 속성 개념은 file의 출처에서 활성화된 dm-verity 또는 fs-verity 같은 보안 기능에도 적용됩니다. IPE는 dm-verity 보호 device에서 온 file을 신뢰하는 policy를 정의할 수 있습니다. dm-verity는 전체 device 내용에 검증 가능하고 불변인 상태를 제공하고, fs-verity는 filesystem 수준 무결성 검사를 제공합니다.

두 기능은 일단 설정되면 끌 수 없으므로 불변 속성으로 간주됩니다. IPE는 이처럼 file의 출처와 무결성 보호 메커니즘을 이용해 접근 제어를 결정합니다.

Policy의 기준값 평가

44-60

IPE policy는 보안 속성을 policy에 정의한 기준값과 비교해 엄격한 접근 제어를 시행합니다. 속성의 존재 여부, 예를 들어 file이 initramfs에서 왔는지를 확인하거나 불변 보안 속성의 내부 상태를 평가할 수 있습니다.

내부 상태 평가는 dm-verity 보호 device의 roothash, dm-verity의 유효한 signature 보유 여부, fs-verity 보호 file의 digest, fs-verity의 유효한 built-in signature 보유 여부 등을 확인합니다. 이 방식은 특정 보안 요구와 신뢰 모델에 맞춘 강력하고 사용자 정의 가능한 방어를 제공합니다.

IPE를 활성화하려면 `Security -> Integrity Policy Enforcement (IPE)` 아래의 `CONFIG_SECURITY_IPE` config option을 켜십시오.

사용 사례

61-84

IPE는 data center의 network firewall이나 IoT device처럼 목적이 명확하고 변경되지 않으며 모든 software와 configuration을 시스템 소유자가 구축하고 provisioning하는 고정 기능 device에 가장 적합합니다.

일반 목적 computing에 사용하기에는 아직 갈 길이 멉니다. Linux community는 대체로 분산 신뢰 모델인 web of trust를 따르지만 IPE는 아직 이를 지원하지 않습니다. 대신 절대적 신뢰 수준을 제공하는 trusted entity 집합을 지정하는 PKI(public key infrastructure)를 지원합니다.

오늘날 package 자체는 대부분 서명되지만 package 안의 executable 같은 file은 대개 서명되지 않습니다. 따라서 package manager와 그 ecosystem을 크게 바꾸지 않고 package manager가 동작해야 하는 시스템에 IPE를 적용하기는 어렵습니다.

`digest_cache` LSM은 IPE와 결합했을 때 일반 목적 computing 사용 사례를 활성화하고 지원하는 데 사용할 수 있는 시스템입니다.

알려진 제한

85-99

IPE는 gcc closure와 libffi 3.4.2 미만이 만드는 trampoline 또는 JIT code 같은 anonymous executable memory의 무결성을 검증할 수 없습니다. 동적으로 생성되는 code이므로 신뢰 기반을 만들 수 있는 무결성을 보장할 방법이 없습니다.

또한 script file을 interpreter에 인자로 넘겨 실행하는 interpreted language program의 무결성을 검증할 수 없습니다. script 자체가 IPE hook을 통해 executable code로 평가되지 않고 compiled executable과 달리 단순히 읽히는 text file이기 때문입니다.

위협 모델

100-121

IPE는 kernel이 처음 boot한 뒤 user-space executable code가 변조되는 위험을 특히 겨냥하며, `modprobe` 또는 `insmod`로 userspace에서 load하는 kernel module도 포함합니다.

예를 들어 악성일 수 있는 신뢰하지 않는 binary와 loader, libc를 포함한 모든 dependency가 download되었다면 IPE의 주된 역할은 그 binary와 dependency의 실행을 막는 것입니다.

IPE는 모든 executable code의 무결성과 진위를 실행 전에 검증합니다. code의 무결성이 유지되고 정의된 policy가 허가한 reference value(digest, signature 등)와 일치하는지 확인합니다. 무결성이 훼손되었거나 허가 기준을 충족하지 못하면 실행을 거부하고, policy 위반 실패를 탐지하고 분석할 수 있는 audit log를 생성합니다.

변조 주체와 범위 밖 위협

122-139

Executable code를 수정하거나 교체하는 변조 위협의 주체에는 다음이 포함됩니다.

위협 주체접근 경로
Hardware에 물리적으로 접근하는 주체Physical access
시스템의 local network에 접근하는 주체Local network
Deployment system에 접근하는 주체Deployment pipeline
외부 통제 아래 놓인 침해된 내부 시스템Compromised internal system
악의적인 시스템 end userMalicious end user
침해된 시스템 end userCompromised end user
시스템의 remote(external) compromiseRemote compromise

IPE는 signing certificate에 접근할 수 있는 악의적이지만 허가된 개발자나, 그 개발자가 사용하는 침해된 개발 도구에서 비롯한 위협(예: return-oriented programming attack)을 완화하지 않습니다. IPE는 userspace와 kernelspace 사이에 단단한 보안 경계를 두므로 kernel-level exploit도 범위 밖이며 다른 메커니즘이 완화해야 합니다.

Policy header

140-157

IPE policy는 여러 줄의 statement로 구성된 plain-text policy입니다. 첫 줄에는 사람이 읽을 수 있는 고유 식별자인 policy name과 현재 policy version을 반드시 지정합니다.

policy_name=Ex_Policy policy_version=0.0.0

Policy name은 securityfs node를 만들고 새 policy 배포와 기존 policy update를 구별하는 고유 key입니다. Policy version은 policy syntax version이 아니라 현재 policy 자체의 version이며, 잠재적으로 안전하지 않은 이전 policy로 rollback하는 일을 막는 데 사용됩니다.

Rule 문법과 평가 순서

158-180

IPE policy의 다음 부분은 rule입니다. Rule은 property라고 부르는 `key=value` pair로 구성됩니다. 모든 IPE rule에는 일치했을 때 수행할 동작을 정하는 `action`과 rule을 평가할 시점을 정하는 `op`가 필요합니다.

순서가 중요합니다. Rule은 `op`로 시작하고 `action`으로 끝나야 하며 최소 rule은 다음과 같습니다.

op=EXECUTE action=ALLOW

이 예는 모든 실행을 허용합니다. 추가 property는 평가 대상 file의 불변 보안 속성을 검사합니다. 이 property들은 kernel 안에서 무결성 검증 수준을 제공하는 시스템을 기술하며, IPE는 그 값으로 resource의 신뢰 여부를 결정합니다.

Rule은 위에서 아래로 평가하므로 revoke 또는 deny rule은 `action=ALLOW` rule보다 먼저 평가되도록 file 앞쪽에 두어야 합니다. `#`부터 newline까지는 comment로 무시됩니다.

DEFAULT statement

181-194

IPE 평가의 기본 동작은 `DEFAULT` statement로 policy에 표현할 수 있습니다. Global 수준 또는 operation별 수준으로 지정할 수 있습니다.

# Global
DEFAULT action=ALLOW

# Operation Specific
DEFAULT op=EXECUTE action=ALLOW

알려진 모든 IPE operation에는 default가 있어야 합니다. 새 operation을 도입한 kernel에서도 오래된 policy의 호환성을 유지하려면 global default를 `ALLOW`로 지정한 뒤 operation별 default로 덮어쓰십시오.

Boot policy

195-217

Configurable policy 기반 LSM이 시작 시 policy를 읽고 parsing하여 강제할 때는 다음 문제가 있습니다.

문제이유
Userspace file 직접 읽기Kernel은 userspace file을 읽어서는 안 되므로 policy file 직접 읽기가 금지됩니다.
Kernel command line 크기문자 수 제한이 있으므로 한 kernel module이 전체 공간을 독점해서는 안 됩니다.
Bootloader 다양성Memory block 전달 방식은 여러 bootloader를 지원하기 위한 유지 비용이 큽니다.

IPE는 이를 `boot policy`로 해결합니다. Boot policy는 kernel에 compile되는 최소 policy로, userspace가 command를 받을 준비가 될 때까지 시스템을 올린 뒤 securityfs를 통해 더 복잡한 policy를 배포하게 합니다.

`SECURITY_IPE_BOOT_POLICY` config option에 적용할 plain-text IPE policy path를 지정하면 그 policy가 kernel에 compile됩니다. 지정하지 않으면 securityfs로 policy를 배포하고 활성화할 때까지 IPE가 비활성 상태입니다.

Policy 서명

218-240

Policy는 userspace에서 securityfs를 통해 배포할 수 있습니다. 공격자가 무제한 root 권한을 얻어 `allow all` policy를 배포하지 못하도록 PKCS#7 message format으로 서명해 policy 권한을 통제합니다.

Policy는 `SYSTEM_TRUSTED_KEYRING`으로 chain되는 certificate로 서명해야 합니다. `CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING` 또는 `CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING`을 켰다면 각각 secondary 또는 platform keyring으로 chain되는 certificate도 사용할 수 있습니다.

OpenSSL로 policy를 서명하는 예는 다음과 같습니다.

openssl smime -sign \
   -in "$MY_POLICY" \
   -signer "$MY_CERTIFICATE" \
   -inkey "$MY_PRIVATE_KEY" \
   -noattr \
   -nodetach \
   -nosmimecap \
   -outform der \
   -out "$MY_POLICY.p7b"

new_policy 배포

241-253

Policy는 securityfs의 `new_policy` node에 file을 써서 배포합니다.

cat "$MY_POLICY.p7b" > /sys/kernel/security/ipe/new_policy

성공하면 `/sys/kernel/security/ipe/policies/` 아래에 배포한 `policy_name`과 같은 subdirectory가 생깁니다. 위 예에서는 `/sys/kernel/security/ipe/policies/Ex_Policy`이며 그 안에는 `pkcs7`, `policy`, `name`, `version`, `active`, `update`, `delete` 일곱 file이 있습니다.

Policy directory file

254-283
FileAccess동작
pkcs7Read-onlyKernel에 제공한 raw PKCS#7 policy data를 반환합니다. 서명되지 않은 boot policy이면 `ENOENT`를 반환합니다.
policyRead-onlyPlain-text policy인 PKCS#7 내부 content를 반환합니다.
activeRead/write`"1"`을 쓰면 active policy가 됩니다. 다른 policy는 inactive가 되며 version은 현재 실행 version 이상이어야 합니다.
updateWrite-onlyPKCS#7 signed policy를 받아 기존 policy를 update합니다. `policy_name`이 같고 version이 현재 실행 version보다 커야 합니다.
deleteWrite-only`1`을 쓰면 policy와 securityfs node를 제거합니다. 현재 active policy는 삭제할 수 없어 operation not permitted error를 반환합니다.

`update` 또는 `new_policy`에 쓸 때 policy syntax error이면 bad message가, 같은 `policy_name`의 policy가 이미 배포되어 있으면 file exists error가 발생할 수 있습니다.

활성화와 삭제

284-312

Policy를 배포하는 것만으로 IPE가 그 policy를 강제하지는 않습니다. IPE는 active로 표시한 policy만 강제하며 한 번에 하나만 active일 수 있습니다.

배포에 성공한 `Ex_Policy`를 활성화하려면 다음과 같이 `active` file에 `1`을 씁니다.

echo 1 > "/sys/kernel/security/ipe/policies/Ex_Policy/active"

이 시점부터 시스템은 `Ex_Policy`를 강제합니다.

Policy를 삭제하려면 해당 `delete` securityfs node에 `1`을 씁니다.

echo 1 > "/sys/kernel/security/ipe/policies/$policy_name/delete"

삭제 대상 policy는 inactive여야 합니다. SELinux, AppArmor, Smack 같은 전통적 MAC system이 활성화되어 있다면 IPE securityfs node에 쓰는 모든 작업에 `CAP_MAC_ADMIN`이 필요합니다.

Permissive와 enforced mode

313-329

IPE는 SELinux permissive mode와 비슷한 permissive mode와 enforced mode를 지원합니다. Permissive mode에서도 모든 event를 검사하고 policy 위반을 기록하지만 실제로 차단하지 않으므로 강제하기 전에 policy를 시험할 수 있습니다.

기본값은 enforce입니다. Kernel command line의 `ipe.enforce=(0|1)` 또는 securityfs node `/sys/kernel/security/ipe/enforce`로 바꿀 수 있습니다. 전통적 MAC system이 활성화되어 있으면 이 node에 쓰는 데 `CAP_MAC_ADMIN`이 필요합니다.

1420 AUDIT_IPE_ACCESS

330-376

IPE가 접근 제어 결정을 내렸을 때 다음과 같은 record가 생성됩니다.

type=1420 audit(1653364370.067:61): ipe_op=EXECUTE ipe_hook=MMAP enforcing=1 pid=2241 comm="ld-linux.so" path="/deny/lib/libc.so.6" dev="sda2" ino=14549020 rule="DEFAULT action=DENY"
type=1300 audit(1653364370.067:61): SYSCALL arch=c000003e syscall=9 success=no exit=-13 a0=7f1105a28000 a1=195000 a2=5 a3=812 items=0 ppid=2219 pid=2241 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="ld-linux.so" exe="/tmp/ipe-test/lib/ld-linux.so" subj=unconfined key=(null)
type=1327 audit(1653364370.067:61): 707974686F6E3300746573742F6D61696E2E7079002D6E00

type=1420 audit(1653364735.161:64): ipe_op=EXECUTE ipe_hook=MMAP enforcing=1 pid=2472 comm="mmap_test" path=? dev=? ino=? rule="DEFAULT action=DENY"
type=1300 audit(1653364735.161:64): SYSCALL arch=c000003e syscall=9 success=no exit=-13 a0=0 a1=1000 a2=4 a3=21 items=0 ppid=2219 pid=2472 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="mmap_test" exe="/root/overlake_test/upstream_test/vol_fsverity/bin/mmap_test" subj=unconfined key=(null)
type=1327 audit(1653364735.161:64): 707974686F6E3300746573742F6D61696E2E7079002D6E00

IPE 전용 record 1420은 항상 `AUDITSYSCALL` record와 함께 발생합니다. IPE가 permissive인지 enforced인지는 `AUDITSYSCALL` record의 `success` property와 exit code로 판단할 수 있습니다.

FieldValue typeOptional값 설명
ipe_opstring아니요로그와 연관된 IPE 작업 이름
ipe_hookstring아니요IPE 이벤트를 일으킨 LSM hook 이름
enforcinginteger아니요현재 IPE 강제 상태. 1은 enforcing, 0은 permissive mode
pidinteger아니요IPE 이벤트를 일으킨 process의 pid
commstring아니요IPE 이벤트를 일으킨 process의 command-line program 이름
pathstring평가한 file의 absolute path
inointeger평가한 file의 inode number
devstring평가한 file의 device 이름(예: vda)
rulestring아니요일치한 policy rule

1421 AUDIT_IPE_CONFIG_CHANGE

377-420

Active policy가 바뀌면 다음과 같은 configuration change event가 발생합니다.

type=1421 audit(1653425583.136:54): old_active_pol_name="Allow_All" old_active_pol_version=0.0.0 old_policy_digest=sha256:E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 new_active_pol_name="boot_verified" new_active_pol_version=0.0.0 new_policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F26765076DD8EED7B8F4DB auid=4294967295 ses=4294967295 lsm=ipe res=1
type=1300 audit(1653425583.136:54): SYSCALL arch=c000003e syscall=1 success=yes exit=2 a0=3 a1=5596fcae1fb0 a2=2 a3=2 items=0 ppid=184 pid=229 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4294967295 comm="python3" exe="/usr/bin/python3.10" key=(null)
type=1327 audit(1653425583.136:54): PROCTITLE proctitle=707974686F6E3300746573742F6D61696E2E7079002D66002E2

이 event는 이전 policy와 새 policy의 이름, version, hash digest를 함께 기록합니다. IPE는 한 번에 하나의 policy만 active로 둘 수 있고 모든 접근 결정은 현재 active policy를 기준으로 평가합니다.

새 policy를 배포하는 일반 절차는 먼저 kernel에 policy를 load한 다음 active policy를 그 policy로 전환하는 것입니다. 이 record는 `write` syscall의 `AUDITSYSCALL` record와 항상 함께 발생합니다.

FieldValue typeOptional값 설명
old_active_pol_namestring이전 active policy 이름
old_active_pol_versionstring이전 active policy version
old_policy_digeststring이전 active policy hash
new_active_pol_namestring아니요현재 active policy 이름
new_active_pol_versionstring아니요현재 active policy version
new_policy_digeststring아니요현재 active policy hash
auidinteger아니요login user ID
sesinteger아니요login session ID
lsmstring아니요event와 연관된 LSM 이름
resinteger아니요감사한 작업의 결과(success/fail)

1422 AUDIT_IPE_POLICY_LOAD

421-485

새 policy를 kernel에 load하면 다음 event가 policy name, version, hash와 함께 기록됩니다.

type=1422 audit(1653425529.927:53): policy_name="boot_verified" policy_version=0.0.0 policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F26765076DD8EED7B8F4DB auid=4294967295 ses=4294967295 lsm=ipe res=1 errno=0
type=1300 audit(1653425529.927:53): arch=c000003e syscall=1 success=yes exit=2567 a0=3 a1=5596fcae1fb0 a2=a07 a3=2 items=0 ppid=184 pid=229 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4294967295 comm="python3" exe="/usr/bin/python3.10" key=(null)
type=1327 audit(1653425529.927:53): PROCTITLE proctitle=707974686F6E3300746573742F6D61696E2E7079002D66002E2E

이 record는 `write` syscall의 `AUDITSYSCALL` record와 항상 함께 발생합니다.

FieldValue typeOptional값 설명
policy_namestring`policy_name`
policy_versionstring`policy_version`
policy_digeststringpolicy hash
auidinteger아니요login user ID
sesinteger아니요login session ID
lsmstring아니요event와 연관된 LSM 이름
resinteger아니요감사한 작업의 결과(success/fail)
errnointeger아니요policy load 작업의 error code(아래 표 참조)

Policy를 load하거나 update할 때 `errno` field에는 다음 error code가 나타날 수 있습니다.

Error code설명
0성공
-EPERM권한 부족
-EEXIST같은 이름의 policy가 이미 배포됨
-EBADMSGpolicy가 유효하지 않음
-ENOMEM메모리 부족(OOM)
-ERANGEpolicy version number overflow
-EINVALpolicy version parsing error
-ENOKEYIPE policy 서명에 사용한 key를 keyring에서 찾지 못함
-EKEYREJECTEDpolicy signature verification 실패
-ESTALE더 오래된 version으로 IPE policy를 update하려고 함
-ENOENTupdate 도중 policy가 삭제됨

1404 AUDIT_MAC_STATUS와 성공 감사

486-539

IPE enforcing 상태를 전환하면 다음 event가 발생합니다.

type=1404 audit(1653425689.008:55): enforcing=0 old_enforcing=1 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1
type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=)
type=1327 audit(1653425689.008:55): proctitle="-bash"

type=1404 audit(1653425689.008:55): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1
type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=)
type=1327 audit(1653425689.008:55): proctitle="-bash"

이 record는 `write` syscall의 `AUDITSYSCALL` record와 항상 함께 발생합니다.

FieldValue typeOptional값 설명
enforcinginteger아니요전환할 IPE 상태. 1은 enforcing, 0은 permissive mode
old_enforcinginteger아니요전환 전 IPE 상태. 1은 enforcing, 0은 permissive mode
auidinteger아니요login user ID
sesinteger아니요login session ID
enabledinteger아니요새 TTY audit enabled 설정
old-enabledinteger아니요이전 TTY audit enabled 설정
lsmstring아니요event와 연관된 LSM 이름
resinteger아니요감사한 작업의 결과(success/fail)

IPE는 success auditing을 지원합니다. 활성화하면 IPE policy를 통과해 차단되지 않은 모든 event가 audit event를 생성합니다. 기본값은 비활성이며 kernel command line의 `ipe.success_audit=(0|1)` 또는 securityfs file `/sys/kernel/security/ipe/success_audit`로 켤 수 있습니다.

IPE가 시스템의 모든 userspace binary를 검사하므로 매우 많은 로그가 생성되지만 policy debugging에는 유용합니다. 전통적 MAC system이 활성화되어 있으면 securityfs node에 쓰는 데 `CAP_MAC_ADMIN`이 필요합니다.

Property 개요

540-550

IPE property는 policy에 쓰는 `key=value` pair입니다. Policy parser에 내장된 두 property는 `op`와 `action`입니다. 나머지는 평가 대상 file의 불변 보안 속성을 제한하는 데 사용합니다.

현재 지원하는 보안 property는 `boot_verified`, `dmverity_signature`, `dmverity_roothash`, `fsverity_signature`, `fsverity_digest`입니다.

op

551-592

`op`는 rule을 적용할 operation을 나타내며 모든 rule의 첫 token이어야 합니다.

Operation적용 대상
EXECUTE실행되거나 executable로 load되는 모든 file
FIRMWARE`firmware_class` interface를 통해 load되는 firmware. Preallocated buffer와 firmware file 자체를 모두 포함합니다.
KMODULE`modprobe` 또는 `insmod`를 통한 kernel module load
KEXEC_IMAGE`kexec`를 통한 kernel image load
KEXEC_INITRAMFS`kexec --initrd`를 통한 initrd image load
POLICYKernel-space가 시작한 read를 통한 policy load. 예: `$securityfs/ima/policy`에 IMA policy file path를 써서 load하는 작업
X509_CERTKconfig `CONFIG_IMA_X509_PATH`와 `CONFIG_EVM_X509_PATH`를 통한 IMA certificate load

action

593-608

`action`은 rule이 일치할 때 IPE가 수행할 일을 정하며 모든 rule의 마지막 clause여야 합니다.

Action동작
ALLOW더 이상 rule을 실행하지 않고 resource 접근을 명시적으로 허용합니다.
DENY더 이상 rule을 실행하지 않고 resource 접근을 명시적으로 금지합니다.

boot_verified

609-630

`boot_verified`는 initramfs의 file을 허가하는 데 사용할 수 있으며 형식은 다음과 같습니다.

      boot_verified=(TRUE|FALSE)

경고: 이 property는 initramfs(rootfs)의 file을 신뢰하므로 초기 boot 단계에서만 사용해야 합니다. 실제 rootfs를 initramfs 위에 mount하기 전에 initramfs script는 보통 `switch_root(8)`로 initramfs의 모든 file과 directory를 재귀적으로 제거합니다.

실제 rootfs가 넘겨받은 뒤에는 initramfs가 비어 접근할 수 없으므로, 그 시점 이후에는 이 property에 의존하지 않는 다른 policy로 전환하는 것이 좋습니다. 그래야 시스템 전체 동작 중 신뢰 policy가 계속 적절하고 효과적으로 유지됩니다.

dmverity_roothash

631-656

`dmverity_roothash`는 root hash로 식별한 특정 dm-verity volume을 허가하거나 revoke하는 데 사용합니다. `DM_VERITY` module에 의존하고 `IPE_PROP_DM_VERITY` config option이 제어하며, `SECURITY_IPE`와 `DM_VERITY`를 모두 켜면 자동 선택됩니다.

형식은 다음과 같습니다.

   dmverity_roothash=DigestName:HexadecimalString
지원 DigestName
blake2b-512
blake2s-256
sha256
sha384
sha512
sha3-224
sha3-256
sha3-384
sha3-512
sm3
rmd160

dmverity_signature

657-671

`dmverity_signature`은 dm-verity configuration이 지정한 system trusted keyring 또는 secondary keyring으로 검증된 signed roothash를 가진 모든 dm-verity volume을 허가하는 데 사용합니다.

`DM_VERITY_VERIFY_ROOTHASH_SIG` config option에 의존하고 `IPE_PROP_DM_VERITY_SIGNATURE`가 제어합니다. `SECURITY_IPE`, `DM_VERITY`, `DM_VERITY_VERIFY_ROOTHASH_SIG`를 모두 켜면 자동 선택됩니다.

   dmverity_signature=(TRUE|FALSE)

fsverity_digest

672-688

`fsverity_digest`는 fs-verity digest로 식별한 특정 fs-verity enabled file을 허가하는 데 사용합니다. `FS_VERITY`에 의존하고 `IPE_PROP_FS_VERITY`가 제어하며, `SECURITY_IPE`와 `FS_VERITY`를 모두 켜면 자동 선택됩니다.

   fsverity_digest=DigestName:HexadecimalString

지원하는 `DigestName`은 `sha256`과 `sha512`입니다.

fsverity_signature

689-702

`fsverity_signature`은 fs-verity built-in signature mechanism으로 검증된 모든 fs-verity enabled file을 허가합니다. Signature verification은 `.fs-verity` keyring에 저장된 key를 사용합니다.

`FS_VERITY_BUILTIN_SIGNATURES`에 의존하고 `IPE_PROP_FS_VERITY`가 제어합니다. `SECURITY_IPE`, `FS_VERITY`, `FS_VERITY_BUILTIN_SIGNATURES`를 모두 켜면 자동 선택됩니다.

   fsverity_signature=(TRUE|FALSE)

예제: 모두 허용

703-713

모든 operation을 허용하는 policy입니다.

policy_name=Allow_All policy_version=0.0.0
DEFAULT action=ALLOW

예제: initramfs만 허용

714-723

기본적으로 거부하고 initramfs에서 온 executable만 허용합니다.

policy_name=Allow_Initramfs policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE boot_verified=TRUE action=ALLOW

예제: 서명된 dm-verity와 initramfs

724-734

Initramfs와 유효한 signature가 있는 모든 dm-verity volume의 실행을 허용합니다.

policy_name=Allow_Signed_DMV_And_Initramfs policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_signature=TRUE action=ALLOW

예제: 특정 dm-verity volume 금지

735-747

특정 dm-verity roothash의 실행을 먼저 거부하고, initramfs와 서명된 다른 dm-verity volume을 허용합니다. Rule이 위에서 아래로 평가되므로 deny rule이 앞에 있습니다.

policy_name=Deny_DMV_By_Roothash policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE dmverity_roothash=sha256:cd2c5bae7c6c579edaae4353049d58eb5f2e8be0244bf05345bc8e5ed257baff action=DENY

op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_signature=TRUE action=ALLOW

예제: 특정 dm-verity volume만 허용

748-757

기본적으로 거부하고 지정한 dm-verity roothash만 허용합니다.

policy_name=Allow_DMV_By_Roothash policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE dmverity_roothash=sha256:401fcec5944823ae12f62726e8184407a5fa9599783f030dec146938 action=ALLOW

예제: 유효한 fs-verity signature

758-767

기본적으로 거부하고 유효한 built-in signature가 있는 fs-verity file을 허용합니다.

policy_name=Allow_Signed_And_Validated_FSVerity policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE fsverity_signature=TRUE action=ALLOW

예제: 특정 fs-verity digest

768-777

기본적으로 거부하고 지정한 fs-verity digest의 file 실행만 허용합니다.

policy_name=ALLOW_FSV_By_Digest policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE fsverity_digest=sha256:fd88f2b8824e197f850bf4c5109bea5cf0ee38104f710843bb72da796ba5af9e action=ALLOW

추가 정보와 FAQ

778-803

질문: 신뢰 기반 접근 제어 수준을 제공하는 다른 LSM과 IPE의 차이는 무엇입니까?

답변: 비슷한 기능을 제공하는 다른 LSM에는 IMA와 LoadPin이 있습니다. IMA와 IPE는 기능적으로 매우 비슷하지만 중요한 차이는 policy입니다.

LoadPin과 IPE는 차이가 큽니다. LoadPin은 IPE의 kernel read operation만 다루지만 IPE는 kernel read뿐 아니라 실행도 제어할 수 있습니다. 신뢰 모델도 다릅니다. LoadPin은 initial superblock에 신뢰의 뿌리를 두지만 IPE의 신뢰는 `SYSTEM_TRUSTED_KEYS`를 통해 kernel 자체에서 시작합니다.

참고 문헌

804-824

`devdoc` 각주는 이 주제의 자세한 설명으로 `security/ipe` 설계 문서를 가리킵니다.

`dmveritydigests` 목록은 Linux crypto API가 허용하는 값을 바탕으로 합니다. IPE 자체는 digest algorithm을 제한하지 않으므로 목록이 최신이 아닐 수 있습니다.

`fsveritydigest` 목록은 kernel fs-verity 지원이 허용하는 값을 바탕으로 합니다. IPE 자체는 digest algorithm을 제한하지 않으므로 목록이 최신이 아닐 수 있습니다.