1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "extract-word.h"
5 #include "image-policy.h"
8 #include "string-util.h"
11 /* Rationale for the chosen syntax:
13 * → one line, so that it can be reasonably added to a shell command line, for example via `systemd-dissect
14 * --image-policy=…` or to the kernel command line via `systemd.image_policy=`.
16 * → no use of "," or ";" as separators, so that it can be included in mount/fstab-style option strings and
17 * doesn't require escaping. Instead, separators are ":", "=", "+" which should be fine both in shell
18 * command lines and in mount/fstab style option strings.
21 static int partition_policy_compare(const PartitionPolicy
*a
, const PartitionPolicy
*b
) {
22 return CMP(ASSERT_PTR(a
)->designator
, ASSERT_PTR(b
)->designator
);
25 static const PartitionPolicy
* image_policy_bsearch(const ImagePolicy
*policy
, PartitionDesignator designator
) {
29 return typesafe_bsearch(
30 &(const PartitionPolicy
) { .designator
= designator
},
31 ASSERT_PTR(policy
)->policies
,
32 ASSERT_PTR(policy
)->n_policies
,
33 partition_policy_compare
);
36 PartitionPolicyFlags
partition_policy_flags_extend(PartitionPolicyFlags flags
) {
37 /* If some parts of a flags field are left unspecified, let's fill in all options. */
39 /* If no protection flag is set, then this means all are set */
40 if ((flags
& _PARTITION_POLICY_USE_MASK
) == 0)
41 flags
|= PARTITION_POLICY_OPEN
;
43 /* If the gpt flags bits are not specified, set both options for each */
44 if ((flags
& _PARTITION_POLICY_READ_ONLY_MASK
) == 0)
45 flags
|= PARTITION_POLICY_READ_ONLY_ON
|PARTITION_POLICY_READ_ONLY_OFF
;
47 if ((flags
& _PARTITION_POLICY_GROWFS_MASK
) == 0)
48 flags
|= PARTITION_POLICY_GROWFS_ON
|PARTITION_POLICY_GROWFS_OFF
;
53 static PartitionPolicyFlags
partition_policy_normalized_flags(const PartitionPolicy
*policy
) {
54 PartitionPolicyFlags flags
= ASSERT_PTR(policy
)->flags
;
56 /* This normalizes the per-partition policy flags. This means if the user left some things
57 * unspecified, we'll fill in the appropriate "dontcare" policy instead. We'll also mask out bits
58 * that do not make any sense for specific partition types. */
60 flags
= partition_policy_flags_extend(flags
);
62 /* If this is a verity or verity signature designator, then mask off all protection bits, this after
63 * all needs no protection, because it *is* the protection */
64 if (partition_verity_to_data(policy
->designator
) >= 0 ||
65 partition_verity_sig_to_data(policy
->designator
) >= 0)
66 flags
&= ~(PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
);
68 /* if this designator has no verity concept, then mask off verity protection flags */
69 if (partition_verity_of(policy
->designator
) < 0)
70 flags
&= ~(PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
);
72 /* If the partition must be absent, then the gpt flags don't matter */
73 if ((flags
& _PARTITION_POLICY_USE_MASK
) == PARTITION_POLICY_ABSENT
)
74 flags
&= ~(_PARTITION_POLICY_READ_ONLY_MASK
|_PARTITION_POLICY_GROWFS_MASK
);
79 PartitionPolicyFlags
image_policy_get(const ImagePolicy
*policy
, PartitionDesignator designator
) {
80 PartitionDesignator data_designator
= _PARTITION_DESIGNATOR_INVALID
;
81 const PartitionPolicy
*pp
;
83 /* No policy means: everything may be used in any mode */
85 return partition_policy_normalized_flags(
86 &(const PartitionPolicy
) {
87 .flags
= PARTITION_POLICY_OPEN
,
88 .designator
= designator
,
91 pp
= image_policy_bsearch(policy
, designator
);
93 return partition_policy_normalized_flags(pp
);
95 /* Hmm, so this didn't work, then let's see if we can derive some policy from the underlying data
96 * partition in case of verity/signature partitions */
98 data_designator
= partition_verity_to_data(designator
);
99 if (data_designator
>= 0) {
100 PartitionPolicyFlags data_flags
;
102 /* So we are asked for the policy for a verity partition, and there's no explicit policy for
103 * that case. Let's synthesize a policy from the protection setting for the underlying data
106 data_flags
= image_policy_get(policy
, data_designator
);
110 /* We need verity if verity or verity with sig is requested */
111 if (!(data_flags
& (PARTITION_POLICY_SIGNED
|PARTITION_POLICY_VERITY
)))
112 return _PARTITION_POLICY_FLAGS_INVALID
;
114 /* If the data partition may be unused or absent, then the verity partition may too. Also, inherit the partition flags policy */
115 return partition_policy_normalized_flags(
116 &(const PartitionPolicy
) {
117 .flags
= PARTITION_POLICY_UNPROTECTED
| (data_flags
& (PARTITION_POLICY_UNUSED
|PARTITION_POLICY_ABSENT
)) |
118 (data_flags
& _PARTITION_POLICY_PFLAGS_MASK
),
119 .designator
= designator
,
123 data_designator
= partition_verity_sig_to_data(designator
);
124 if (data_designator
>= 0) {
125 PartitionPolicyFlags data_flags
;
127 /* Similar case as for verity partitions, but slightly more strict rules */
129 data_flags
= image_policy_get(policy
, data_designator
);
133 if (!(data_flags
& PARTITION_POLICY_SIGNED
))
134 return _PARTITION_POLICY_FLAGS_INVALID
;
136 return partition_policy_normalized_flags(
137 &(const PartitionPolicy
) {
138 .flags
= PARTITION_POLICY_UNPROTECTED
| (data_flags
& (PARTITION_POLICY_UNUSED
|PARTITION_POLICY_ABSENT
)) |
139 (data_flags
& _PARTITION_POLICY_PFLAGS_MASK
),
140 .designator
= designator
,
144 return _PARTITION_POLICY_FLAGS_INVALID
; /* got nothing */
147 PartitionPolicyFlags
image_policy_get_exhaustively(const ImagePolicy
*policy
, PartitionDesignator designator
) {
148 PartitionPolicyFlags flags
;
150 /* This is just like image_policy_get() but whenever there is no policy for a specific designator, we
151 * return the default policy. */
153 flags
= image_policy_get(policy
, designator
);
155 return partition_policy_normalized_flags(
156 &(const PartitionPolicy
) {
157 .flags
= image_policy_default(policy
),
158 .designator
= designator
,
164 static PartitionPolicyFlags
policy_flag_from_string_one(const char *s
) {
167 /* This is a bitmask (i.e. not dense), hence we don't use the "string-table.h" stuff here. */
169 if (streq(s
, "verity"))
170 return PARTITION_POLICY_VERITY
;
171 if (streq(s
, "signed"))
172 return PARTITION_POLICY_SIGNED
;
173 if (streq(s
, "encrypted"))
174 return PARTITION_POLICY_ENCRYPTED
;
175 if (streq(s
, "unprotected"))
176 return PARTITION_POLICY_UNPROTECTED
;
177 if (streq(s
, "unused"))
178 return PARTITION_POLICY_UNUSED
;
179 if (streq(s
, "absent"))
180 return PARTITION_POLICY_ABSENT
;
181 if (streq(s
, "open")) /* shortcut alias */
182 return PARTITION_POLICY_OPEN
;
183 if (streq(s
, "ignore")) /* ditto */
184 return PARTITION_POLICY_IGNORE
;
185 if (streq(s
, "read-only-on"))
186 return PARTITION_POLICY_READ_ONLY_ON
;
187 if (streq(s
, "read-only-off"))
188 return PARTITION_POLICY_READ_ONLY_OFF
;
189 if (streq(s
, "growfs-on"))
190 return PARTITION_POLICY_GROWFS_ON
;
191 if (streq(s
, "growfs-off"))
192 return PARTITION_POLICY_GROWFS_OFF
;
194 return _PARTITION_POLICY_FLAGS_INVALID
;
197 PartitionPolicyFlags
partition_policy_flags_from_string(const char *s
) {
198 PartitionPolicyFlags flags
= 0;
203 if (empty_or_dash(s
))
207 _cleanup_free_
char *f
= NULL
;
208 PartitionPolicyFlags ff
;
210 r
= extract_first_word(&s
, &f
, "+", EXTRACT_DONT_COALESCE_SEPARATORS
);
216 ff
= policy_flag_from_string_one(strstrip(f
));
218 return -EBADRQC
; /* recognizable error */
226 static ImagePolicy
* image_policy_new(size_t n_policies
) {
229 if (n_policies
> (SIZE_MAX
- offsetof(ImagePolicy
, policies
)) / sizeof(PartitionPolicy
)) /* overflow check */
232 p
= malloc(offsetof(ImagePolicy
, policies
) + sizeof(PartitionPolicy
) * n_policies
);
237 .default_flags
= PARTITION_POLICY_IGNORE
,
242 int image_policy_from_string(const char *s
, ImagePolicy
**ret
) {
243 _cleanup_free_ ImagePolicy
*p
= NULL
;
246 PartitionPolicyFlags symbolic_policy
;
250 assert_cc(sizeof(dmask
) * 8 >= _PARTITION_DESIGNATOR_MAX
);
252 /* Recognizable errors:
254 * ENOTUNIQ → Two or more rules for the same partition
255 * EBADSLT → Unknown partition designator
256 * EBADRQC → Unknown policy flags
259 /* First, let's handle "symbolic" policies, i.e. "-", "*", "~" */
260 if (empty_or_dash(s
))
261 /* ignore policy: everything may exist, but nothing used */
262 symbolic_policy
= PARTITION_POLICY_IGNORE
;
263 else if (streq(s
, "*"))
264 /* allow policy: everything is allowed */
265 symbolic_policy
= PARTITION_POLICY_OPEN
;
266 else if (streq(s
, "~"))
267 /* deny policy: nothing may exist */
268 symbolic_policy
= PARTITION_POLICY_ABSENT
;
270 symbolic_policy
= _PARTITION_POLICY_FLAGS_INVALID
;
272 if (symbolic_policy
>= 0) {
276 p
= image_policy_new(0);
280 p
->default_flags
= symbolic_policy
;
285 /* Allocate the policy at maximum size, i.e. for all designators. We might overshoot a bit, but the
286 * items are cheap, and we can return unused space to libc once we know we don't need it */
287 p
= image_policy_new(_PARTITION_DESIGNATOR_MAX
);
292 bool default_specified
= false;
294 _cleanup_free_
char *e
= NULL
, *d
= NULL
;
295 PartitionDesignator designator
;
296 PartitionPolicyFlags flags
;
299 r
= extract_first_word(&q
, &e
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
);
306 r
= extract_first_word((const char**) &f
, &d
, "=", EXTRACT_DONT_COALESCE_SEPARATORS
);
310 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "Expected designator name followed by '='; got instead: %s", e
);
311 if (!f
) /* no separator? */
312 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
), "Missing '=' in policy expression: %s", e
);
316 /* Not partition name? then it's the default policy */
317 if (default_specified
)
318 return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ
), "Default partition policy flags specified more than once.");
320 designator
= _PARTITION_DESIGNATOR_INVALID
;
321 default_specified
= true;
323 designator
= partition_designator_from_string(ds
);
325 return log_debug_errno(SYNTHETIC_ERRNO(EBADSLT
), "Unknown partition designator: %s", ds
); /* recognizable error */
326 if (dmask
& (UINT64_C(1) << designator
))
327 return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ
), "Partition designator specified more than once: %s", ds
);
328 dmask
|= UINT64_C(1) << designator
;
332 flags
= partition_policy_flags_from_string(fs
);
333 if (flags
== -EBADRQC
)
334 return log_debug_errno(flags
, "Unknown partition policy flag: %s", fs
);
336 return log_debug_errno(flags
, "Failed to parse partition policy flags '%s': %m", fs
);
339 p
->default_flags
= flags
;
341 p
->policies
[p
->n_policies
++] = (PartitionPolicy
) {
342 .designator
= designator
,
348 assert(p
->n_policies
<= _PARTITION_DESIGNATOR_MAX
);
350 /* Return unused space to libc */
351 t
= realloc(p
, offsetof(ImagePolicy
, policies
) + sizeof(PartitionPolicy
) * p
->n_policies
);
355 typesafe_qsort(p
->policies
, p
->n_policies
, partition_policy_compare
);
363 int partition_policy_flags_to_string(PartitionPolicyFlags flags
, bool simplify
, char **ret
) {
364 _cleanup_free_
char *buf
= NULL
;
365 const char *l
[CONST_LOG2U(_PARTITION_POLICY_MASK
) + 1]; /* one string per known flag at most */
373 /* If 'simplify' is false we'll output the precise value of every single flag.
375 * If 'simplify' is true we'll try to make the output shorter, by doing the following:
377 * → we'll spell the long form "verity+signed+encrypted+unprotected+unused+absent" via its
378 * equivalent shortcut form "open" (which we happily parse btw, see above)
380 * → we'll spell the long form "unused+absent" via its shortcut "ignore" (which we are also happy
383 * → if the read-only/growfs policy flags are both set, we suppress them. this thus removes the
384 * distinction between "user explicitly declared don't care" and "we implied don't care because
385 * user didn't say anything".
387 * net result: the resulting string is shorter, but the effective policy declared that way will have
388 * the same results as the long form. */
390 if (simplify
&& (flags
& _PARTITION_POLICY_USE_MASK
) == PARTITION_POLICY_OPEN
)
392 else if (simplify
&& (flags
& _PARTITION_POLICY_USE_MASK
) == PARTITION_POLICY_IGNORE
)
395 if (flags
& PARTITION_POLICY_VERITY
)
397 if (flags
& PARTITION_POLICY_SIGNED
)
399 if (flags
& PARTITION_POLICY_ENCRYPTED
)
400 l
[m
++] = "encrypted";
401 if (flags
& PARTITION_POLICY_UNPROTECTED
)
402 l
[m
++] = "unprotected";
403 if (flags
& PARTITION_POLICY_UNUSED
)
405 if (flags
& PARTITION_POLICY_ABSENT
)
409 if (!simplify
|| (!(flags
& PARTITION_POLICY_READ_ONLY_ON
) != !(flags
& PARTITION_POLICY_READ_ONLY_OFF
))) {
410 if (flags
& PARTITION_POLICY_READ_ONLY_ON
)
411 l
[m
++] = "read-only-on";
412 if (flags
& PARTITION_POLICY_READ_ONLY_OFF
)
413 l
[m
++] = "read-only-off";
416 if (!simplify
|| (!(flags
& PARTITION_POLICY_GROWFS_ON
) != !(flags
& PARTITION_POLICY_GROWFS_OFF
))) {
417 if (flags
& PARTITION_POLICY_GROWFS_OFF
)
418 l
[m
++] = "growfs-off";
419 if (flags
& PARTITION_POLICY_GROWFS_ON
)
420 l
[m
++] = "growfs-on";
426 assert(m
+1 < ELEMENTSOF(l
));
429 buf
= strv_join((char**) l
, "+");
434 *ret
= TAKE_PTR(buf
);
438 static bool partition_policy_flags_extended_equal(PartitionPolicyFlags a
, PartitionPolicyFlags b
) {
439 return partition_policy_flags_extend(a
) == partition_policy_flags_extend(b
);
442 static int image_policy_flags_all_match(const ImagePolicy
*policy
, PartitionPolicyFlags expected
) {
447 if (!partition_policy_flags_extended_equal(image_policy_default(policy
), expected
))
450 for (PartitionDesignator d
= 0; d
< _PARTITION_DESIGNATOR_MAX
; d
++) {
451 PartitionPolicyFlags f
, w
;
453 f
= image_policy_get_exhaustively(policy
, d
);
457 w
= partition_policy_normalized_flags(
458 &(const PartitionPolicy
) {
471 bool image_policy_equiv_ignore(const ImagePolicy
*policy
) {
472 /* Checks if this is the ignore policy (or equivalent to it), i.e. everything is ignored, aka '-', aka '' */
473 return image_policy_flags_all_match(policy
, PARTITION_POLICY_IGNORE
);
476 bool image_policy_equiv_allow(const ImagePolicy
*policy
) {
477 /* Checks if this is the allow policy (or equivalent to it), i.e. everything is allowed, aka '*' */
478 return image_policy_flags_all_match(policy
, PARTITION_POLICY_OPEN
);
481 bool image_policy_equiv_deny(const ImagePolicy
*policy
) {
482 /* Checks if this is the deny policy (or equivalent to it), i.e. everything must be absent, aka '~' */
483 return image_policy_flags_all_match(policy
, PARTITION_POLICY_ABSENT
);
486 int image_policy_to_string(const ImagePolicy
*policy
, bool simplify
, char **ret
) {
487 _cleanup_free_
char *s
= NULL
;
495 if (image_policy_equiv_allow(policy
))
497 else if (image_policy_equiv_ignore(policy
))
499 else if (image_policy_equiv_deny(policy
))
514 for (size_t i
= 0; i
< image_policy_n_entries(policy
); i
++) {
515 const PartitionPolicy
*p
= policy
->policies
+ i
;
516 _cleanup_free_
char *f
= NULL
;
519 assert(i
== 0 || p
->designator
> policy
->policies
[i
-1].designator
); /* Validate perfect ordering */
521 assert_se(t
= partition_designator_to_string(p
->designator
));
524 /* Skip policy entries that match the default anyway */
525 PartitionPolicyFlags df
;
527 df
= partition_policy_normalized_flags(
528 &(const PartitionPolicy
) {
529 .flags
= image_policy_default(policy
),
530 .designator
= p
->designator
,
539 r
= partition_policy_flags_to_string(p
->flags
, simplify
, &f
);
543 if (!strextend(&s
, isempty(s
) ? "" : ":", t
, "=", f
))
547 if (!simplify
|| !partition_policy_flags_extended_equal(image_policy_default(policy
), PARTITION_POLICY_IGNORE
)) {
548 _cleanup_free_
char *df
= NULL
;
550 r
= partition_policy_flags_to_string(image_policy_default(policy
), simplify
, &df
);
554 if (!strextend(&s
, isempty(s
) ? "" : ":", "=", df
))
558 if (isempty(s
)) { /* no rule and default policy? then let's return "-" */
568 bool image_policy_equal(const ImagePolicy
*a
, const ImagePolicy
*b
) {
571 if (image_policy_n_entries(a
) != image_policy_n_entries(b
))
573 if (image_policy_default(a
) != image_policy_default(b
))
575 for (size_t i
= 0; i
< image_policy_n_entries(a
); i
++) {
576 if (a
->policies
[i
].designator
!= b
->policies
[i
].designator
)
578 if (a
->policies
[i
].flags
!= b
->policies
[i
].flags
)
585 int image_policy_equivalent(const ImagePolicy
*a
, const ImagePolicy
*b
) {
587 /* The image_policy_equal() function checks if the policy is defined the exact same way. This
588 * function here instead looks at the outcome of the two policies instead. Where does this come to
589 * different results you ask? We imply some logic regarding Verity/Encryption: when no rule is
590 * defined for a verity partition we can synthesize it from the protection level of the data
591 * partition it protects. Or: any per-partition rule that is identical to the default rule is
592 * redundant, and will be recognized as such by image_policy_equivalent() but not by
593 * image_policy_equal()- */
595 if (!partition_policy_flags_extended_equal(image_policy_default(a
), image_policy_default(b
)))
598 for (PartitionDesignator d
= 0; d
< _PARTITION_DESIGNATOR_MAX
; d
++) {
599 PartitionPolicyFlags f
, w
;
601 f
= image_policy_get_exhaustively(a
, d
);
605 w
= image_policy_get_exhaustively(b
, d
);
616 int config_parse_image_policy(
618 const char *filename
,
621 unsigned section_line
,
628 _cleanup_(image_policy_freep
) ImagePolicy
*np
= NULL
;
629 ImagePolicy
**p
= ASSERT_PTR(data
);
634 if (isempty(rvalue
)) {
635 *p
= image_policy_free(*p
);
639 r
= image_policy_from_string(rvalue
, &np
);
641 return log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Duplicate rule in image policy, refusing: %s", rvalue
);
643 return log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Unknown partition type in image policy, refusing: %s", rvalue
);
645 return log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Unknown partition policy flag in image policy, refusing: %s", rvalue
);
647 return log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse image policy, refusing: %s", rvalue
);
649 return free_and_replace_full(*p
, np
, image_policy_free
);
652 int parse_image_policy_argument(const char *s
, ImagePolicy
**policy
) {
653 _cleanup_(image_policy_freep
) ImagePolicy
*np
= NULL
;
660 * This function is intended to be used in command line parsers.
662 * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON SUCCESS!
663 * Hence, do not pass in uninitialized pointers.
666 r
= image_policy_from_string(s
, &np
);
668 return log_error_errno(r
, "Duplicate rule in image policy: %s", s
);
670 return log_error_errno(r
, "Unknown partition type in image policy: %s", s
);
672 return log_error_errno(r
, "Unknown partition policy flag in image policy: %s", s
);
674 return log_error_errno(r
, "Failed to parse image policy: %s", s
);
676 return free_and_replace_full(*policy
, np
, image_policy_free
);
679 const ImagePolicy image_policy_allow
= {
682 .default_flags
= PARTITION_POLICY_OPEN
,
685 const ImagePolicy image_policy_deny
= {
688 .default_flags
= PARTITION_POLICY_ABSENT
,
691 const ImagePolicy image_policy_ignore
= {
694 .default_flags
= PARTITION_POLICY_IGNORE
,
697 const ImagePolicy image_policy_sysext
= {
698 /* For system extensions, honour root file system, and /usr/ and ignore everything else. After all,
699 * we are only interested in /usr/ + /opt/ trees anyway, and that's really the only place they can
703 { PARTITION_ROOT
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
704 { PARTITION_USR
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
706 .default_flags
= PARTITION_POLICY_IGNORE
,
709 const ImagePolicy image_policy_sysext_strict
= {
710 /* For system extensions, requiring signing */
713 { PARTITION_ROOT
, PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ABSENT
},
714 { PARTITION_USR
, PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ABSENT
},
716 .default_flags
= PARTITION_POLICY_IGNORE
,
719 const ImagePolicy image_policy_confext
= {
720 /* For configuration extensions, honour root file system, and ignore everything else. After all, we
721 * are only interested in the /etc/ tree anyway, and that's really the only place it can be. */
724 { PARTITION_ROOT
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
726 .default_flags
= PARTITION_POLICY_IGNORE
,
729 const ImagePolicy image_policy_confext_strict
= {
732 { PARTITION_ROOT
, PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ABSENT
},
734 .default_flags
= PARTITION_POLICY_IGNORE
,
737 const ImagePolicy image_policy_container
= {
738 /* For systemd-nspawn containers we use all partitions, with the exception of swap */
741 { PARTITION_ROOT
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
742 { PARTITION_USR
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
743 { PARTITION_HOME
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
744 { PARTITION_SRV
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
745 { PARTITION_ESP
, PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
746 { PARTITION_XBOOTLDR
, PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
747 { PARTITION_TMP
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
748 { PARTITION_VAR
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
750 .default_flags
= PARTITION_POLICY_IGNORE
,
753 const ImagePolicy image_policy_host
= {
754 /* For the host policy we basically use everything */
757 { PARTITION_ROOT
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
758 { PARTITION_USR
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
759 { PARTITION_HOME
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
760 { PARTITION_SRV
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
761 { PARTITION_ESP
, PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
762 { PARTITION_XBOOTLDR
, PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
763 { PARTITION_SWAP
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
764 { PARTITION_TMP
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
765 { PARTITION_VAR
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
767 .default_flags
= PARTITION_POLICY_IGNORE
,
770 const ImagePolicy image_policy_service
= {
771 /* For RootImage= in services we skip ESP/XBOOTLDR and swap */
774 { PARTITION_ROOT
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
775 { PARTITION_USR
, PARTITION_POLICY_VERITY
|PARTITION_POLICY_SIGNED
|PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
776 { PARTITION_HOME
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
777 { PARTITION_SRV
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
778 { PARTITION_TMP
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
779 { PARTITION_VAR
, PARTITION_POLICY_ENCRYPTED
|PARTITION_POLICY_UNPROTECTED
|PARTITION_POLICY_ABSENT
},
781 .default_flags
= PARTITION_POLICY_IGNORE
,