Skip to content

Commit a8a74df

Browse files
jxwufanpcmoore
authored andcommitted
ipe: introduce 'boot_verified' as a trust provider
IPE is designed to provide system level trust guarantees, this usually implies that trust starts from bootup with a hardware root of trust, which validates the bootloader. After this, the bootloader verifies the kernel and the initramfs. As there's no currently supported integrity method for initramfs, and it's typically already verified by the bootloader. This patch introduces a new IPE property `boot_verified` which allows author of IPE policy to indicate trust for files from initramfs. The implementation of this feature utilizes the newly added `initramfs_populated` hook. This hook marks the superblock of the rootfs after the initramfs has been unpacked into it. Before mounting the real rootfs on top of the initramfs, initramfs script will recursively remove all files and directories on the initramfs. This is typically implemented by using switch_root(8) (https://man7.org/linux/man-pages/man8/switch_root.8.html). Therefore the initramfs will be empty and not accessible after the real rootfs takes over. It is advised to switch to a different policy that doesn't rely on the `boot_verified` property after this point. This ensures that the trust policies remain relevant and effective throughout the system's operation. Signed-off-by: Deven Bowers <[email protected]> Signed-off-by: Fan Wu <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 2fea0c2 commit a8a74df

File tree

8 files changed

+101
-6
lines changed

8 files changed

+101
-6
lines changed

security/ipe/eval.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616

1717
struct ipe_policy __rcu *ipe_active_policy;
1818

19+
#define FILE_SUPERBLOCK(f) ((f)->f_path.mnt->mnt_sb)
20+
21+
/**
22+
* build_ipe_sb_ctx() - Build initramfs field of an ipe evaluation context.
23+
* @ctx: Supplies a pointer to the context to be populated.
24+
* @file: Supplies the file struct of the file triggered IPE event.
25+
*/
26+
static void build_ipe_sb_ctx(struct ipe_eval_ctx *ctx, const struct file *const file)
27+
{
28+
ctx->initramfs = ipe_sb(FILE_SUPERBLOCK(file))->initramfs;
29+
}
30+
1931
/**
2032
* ipe_build_eval_ctx() - Build an ipe evaluation context.
2133
* @ctx: Supplies a pointer to the context to be populated.
@@ -28,15 +40,31 @@ void ipe_build_eval_ctx(struct ipe_eval_ctx *ctx,
2840
{
2941
ctx->file = file;
3042
ctx->op = op;
43+
44+
if (file)
45+
build_ipe_sb_ctx(ctx, file);
46+
}
47+
48+
/**
49+
* evaluate_boot_verified() - Evaluate @ctx for the boot verified property.
50+
* @ctx: Supplies a pointer to the context being evaluated.
51+
*
52+
* Return:
53+
* * %true - The current @ctx match the @p
54+
* * %false - The current @ctx doesn't match the @p
55+
*/
56+
static bool evaluate_boot_verified(const struct ipe_eval_ctx *const ctx)
57+
{
58+
return ctx->initramfs;
3159
}
3260

3361
/**
3462
* evaluate_property() - Analyze @ctx against a rule property.
3563
* @ctx: Supplies a pointer to the context to be evaluated.
3664
* @p: Supplies a pointer to the property to be evaluated.
3765
*
38-
* This is a placeholder. The actual function will be introduced in the
39-
* latter commits.
66+
* This function Determines whether the specified @ctx
67+
* matches the conditions defined by a rule property @p.
4068
*
4169
* Return:
4270
* * %true - The current @ctx match the @p
@@ -45,7 +73,14 @@ void ipe_build_eval_ctx(struct ipe_eval_ctx *ctx,
4573
static bool evaluate_property(const struct ipe_eval_ctx *const ctx,
4674
struct ipe_prop *p)
4775
{
48-
return false;
76+
switch (p->type) {
77+
case IPE_PROP_BOOT_VERIFIED_FALSE:
78+
return !evaluate_boot_verified(ctx);
79+
case IPE_PROP_BOOT_VERIFIED_TRUE:
80+
return evaluate_boot_verified(ctx);
81+
default:
82+
return false;
83+
}
4984
}
5085

5186
/**

security/ipe/eval.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@
1515

1616
extern struct ipe_policy __rcu *ipe_active_policy;
1717

18+
struct ipe_superblock {
19+
bool initramfs;
20+
};
21+
1822
struct ipe_eval_ctx {
1923
enum ipe_op_type op;
2024

2125
const struct file *file;
26+
bool initramfs;
2227
};
2328

2429
void ipe_build_eval_ctx(struct ipe_eval_ctx *ctx,

security/ipe/hooks.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
#include <linux/fs.h>
7+
#include <linux/fs_struct.h>
78
#include <linux/types.h>
89
#include <linux/binfmts.h>
910
#include <linux/mman.h>
@@ -182,3 +183,11 @@ int ipe_kernel_load_data(enum kernel_load_data_id id, bool contents)
182183
ipe_build_eval_ctx(&ctx, NULL, op);
183184
return ipe_evaluate_event(&ctx);
184185
}
186+
187+
/**
188+
* ipe_unpack_initramfs() - Mark the current rootfs as initramfs.
189+
*/
190+
void ipe_unpack_initramfs(void)
191+
{
192+
ipe_sb(current->fs->root.mnt->mnt_sb)->initramfs = true;
193+
}

security/ipe/hooks.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ int ipe_kernel_read_file(struct file *file, enum kernel_read_file_id id,
2222

2323
int ipe_kernel_load_data(enum kernel_load_data_id id, bool contents);
2424

25+
void ipe_unpack_initramfs(void);
26+
2527
#endif /* _IPE_HOOKS_H */

security/ipe/ipe.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,30 @@
55
#include <uapi/linux/lsm.h>
66

77
#include "ipe.h"
8+
#include "eval.h"
89
#include "hooks.h"
910

1011
static struct lsm_blob_sizes ipe_blobs __ro_after_init = {
12+
.lbs_superblock = sizeof(struct ipe_superblock),
1113
};
1214

1315
static const struct lsm_id ipe_lsmid = {
1416
.name = "ipe",
1517
.id = LSM_ID_IPE,
1618
};
1719

20+
struct ipe_superblock *ipe_sb(const struct super_block *sb)
21+
{
22+
return sb->s_security + ipe_blobs.lbs_superblock;
23+
}
24+
1825
static struct security_hook_list ipe_hooks[] __ro_after_init = {
1926
LSM_HOOK_INIT(bprm_check_security, ipe_bprm_check_security),
2027
LSM_HOOK_INIT(mmap_file, ipe_mmap_file),
2128
LSM_HOOK_INIT(file_mprotect, ipe_file_mprotect),
2229
LSM_HOOK_INIT(kernel_read_file, ipe_kernel_read_file),
2330
LSM_HOOK_INIT(kernel_load_data, ipe_kernel_load_data),
31+
LSM_HOOK_INIT(initramfs_populated, ipe_unpack_initramfs),
2432
};
2533

2634
/**

security/ipe/ipe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
#define pr_fmt(fmt) "ipe: " fmt
1313

1414
#include <linux/lsm_hooks.h>
15+
struct ipe_superblock *ipe_sb(const struct super_block *sb);
1516

1617
#endif /* _IPE_H */

security/ipe/policy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ enum ipe_action_type {
3030
#define IPE_ACTION_INVALID __IPE_ACTION_MAX
3131

3232
enum ipe_prop_type {
33+
IPE_PROP_BOOT_VERIFIED_FALSE,
34+
IPE_PROP_BOOT_VERIFIED_TRUE,
3335
__IPE_PROP_MAX
3436
};
3537

security/ipe/policy_parser.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,19 @@ static enum ipe_action_type parse_action(char *t)
270270
return match_token(t, action_tokens, args);
271271
}
272272

273+
static const match_table_t property_tokens = {
274+
{IPE_PROP_BOOT_VERIFIED_FALSE, "boot_verified=FALSE"},
275+
{IPE_PROP_BOOT_VERIFIED_TRUE, "boot_verified=TRUE"},
276+
{IPE_PROP_INVALID, NULL}
277+
};
278+
273279
/**
274280
* parse_property() - Parse a rule property given a token string.
275281
* @t: Supplies the token string to be parsed.
276282
* @r: Supplies the ipe_rule the parsed property will be associated with.
277283
*
278-
* This is a placeholder. The actual function will be introduced in the
279-
* latter commits.
284+
* This function parses and associates a property with an IPE rule based
285+
* on a token string.
280286
*
281287
* Return:
282288
* * %0 - Success
@@ -285,7 +291,34 @@ static enum ipe_action_type parse_action(char *t)
285291
*/
286292
static int parse_property(char *t, struct ipe_rule *r)
287293
{
288-
return -EBADMSG;
294+
substring_t args[MAX_OPT_ARGS];
295+
struct ipe_prop *p = NULL;
296+
int rc = 0;
297+
int token;
298+
299+
p = kzalloc(sizeof(*p), GFP_KERNEL);
300+
if (!p)
301+
return -ENOMEM;
302+
303+
token = match_token(t, property_tokens, args);
304+
305+
switch (token) {
306+
case IPE_PROP_BOOT_VERIFIED_FALSE:
307+
case IPE_PROP_BOOT_VERIFIED_TRUE:
308+
p->type = token;
309+
break;
310+
default:
311+
rc = -EBADMSG;
312+
break;
313+
}
314+
if (rc)
315+
goto err;
316+
list_add_tail(&p->next, &r->props);
317+
318+
return rc;
319+
err:
320+
kfree(p);
321+
return rc;
289322
}
290323

291324
/**

0 commit comments

Comments
 (0)