Skip to content

Commit 54a88cd

Browse files
bowerscd-corppcmoore
authored andcommitted
ipe: add policy parser
IPE's interpretation of the what the user trusts is accomplished through its policy. IPE's design is to not provide support for a single trust provider, but to support multiple providers to enable the end-user to choose the best one to seek their needs. This requires the policy to be rather flexible and modular so that integrity providers, like fs-verity, dm-verity, or some other system, can plug into the policy with minimal code changes. Signed-off-by: Deven Bowers <[email protected]> Signed-off-by: Fan Wu <[email protected]> [PM: added NULL check in parse_rule() as discussed] Signed-off-by: Paul Moore <[email protected]>
1 parent 0311507 commit 54a88cd

File tree

5 files changed

+697
-0
lines changed

5 files changed

+697
-0
lines changed

security/ipe/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77

88
obj-$(CONFIG_SECURITY_IPE) += \
99
ipe.o \
10+
policy.o \
11+
policy_parser.o \

security/ipe/policy.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
4+
*/
5+
6+
#include <linux/errno.h>
7+
#include <linux/verification.h>
8+
9+
#include "ipe.h"
10+
#include "policy.h"
11+
#include "policy_parser.h"
12+
13+
/**
14+
* ipe_free_policy() - Deallocate a given IPE policy.
15+
* @p: Supplies the policy to free.
16+
*
17+
* Safe to call on IS_ERR/NULL.
18+
*/
19+
void ipe_free_policy(struct ipe_policy *p)
20+
{
21+
if (IS_ERR_OR_NULL(p))
22+
return;
23+
24+
ipe_free_parsed_policy(p->parsed);
25+
/*
26+
* p->text is allocated only when p->pkcs7 is not NULL
27+
* otherwise it points to the plaintext data inside the pkcs7
28+
*/
29+
if (!p->pkcs7)
30+
kfree(p->text);
31+
kfree(p->pkcs7);
32+
kfree(p);
33+
}
34+
35+
static int set_pkcs7_data(void *ctx, const void *data, size_t len,
36+
size_t asn1hdrlen __always_unused)
37+
{
38+
struct ipe_policy *p = ctx;
39+
40+
p->text = (const char *)data;
41+
p->textlen = len;
42+
43+
return 0;
44+
}
45+
46+
/**
47+
* ipe_new_policy() - Allocate and parse an ipe_policy structure.
48+
*
49+
* @text: Supplies a pointer to the plain-text policy to parse.
50+
* @textlen: Supplies the length of @text.
51+
* @pkcs7: Supplies a pointer to a pkcs7-signed IPE policy.
52+
* @pkcs7len: Supplies the length of @pkcs7.
53+
*
54+
* @text/@textlen Should be NULL/0 if @pkcs7/@pkcs7len is set.
55+
*
56+
* Return:
57+
* * a pointer to the ipe_policy structure - Success
58+
* * %-EBADMSG - Policy is invalid
59+
* * %-ENOMEM - Out of memory (OOM)
60+
* * %-ERANGE - Policy version number overflow
61+
* * %-EINVAL - Policy version parsing error
62+
*/
63+
struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
64+
const char *pkcs7, size_t pkcs7len)
65+
{
66+
struct ipe_policy *new = NULL;
67+
int rc = 0;
68+
69+
new = kzalloc(sizeof(*new), GFP_KERNEL);
70+
if (!new)
71+
return ERR_PTR(-ENOMEM);
72+
73+
if (!text) {
74+
new->pkcs7len = pkcs7len;
75+
new->pkcs7 = kmemdup(pkcs7, pkcs7len, GFP_KERNEL);
76+
if (!new->pkcs7) {
77+
rc = -ENOMEM;
78+
goto err;
79+
}
80+
81+
rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len, NULL,
82+
VERIFYING_UNSPECIFIED_SIGNATURE,
83+
set_pkcs7_data, new);
84+
if (rc)
85+
goto err;
86+
} else {
87+
new->textlen = textlen;
88+
new->text = kstrdup(text, GFP_KERNEL);
89+
if (!new->text) {
90+
rc = -ENOMEM;
91+
goto err;
92+
}
93+
}
94+
95+
rc = ipe_parse_policy(new);
96+
if (rc)
97+
goto err;
98+
99+
return new;
100+
err:
101+
ipe_free_policy(new);
102+
return ERR_PTR(rc);
103+
}

security/ipe/policy.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
4+
*/
5+
#ifndef _IPE_POLICY_H
6+
#define _IPE_POLICY_H
7+
8+
#include <linux/list.h>
9+
#include <linux/types.h>
10+
11+
enum ipe_op_type {
12+
IPE_OP_EXEC = 0,
13+
IPE_OP_FIRMWARE,
14+
IPE_OP_KERNEL_MODULE,
15+
IPE_OP_KEXEC_IMAGE,
16+
IPE_OP_KEXEC_INITRAMFS,
17+
IPE_OP_POLICY,
18+
IPE_OP_X509,
19+
__IPE_OP_MAX,
20+
};
21+
22+
#define IPE_OP_INVALID __IPE_OP_MAX
23+
24+
enum ipe_action_type {
25+
IPE_ACTION_ALLOW = 0,
26+
IPE_ACTION_DENY,
27+
__IPE_ACTION_MAX
28+
};
29+
30+
#define IPE_ACTION_INVALID __IPE_ACTION_MAX
31+
32+
enum ipe_prop_type {
33+
__IPE_PROP_MAX
34+
};
35+
36+
#define IPE_PROP_INVALID __IPE_PROP_MAX
37+
38+
struct ipe_prop {
39+
struct list_head next;
40+
enum ipe_prop_type type;
41+
void *value;
42+
};
43+
44+
struct ipe_rule {
45+
enum ipe_op_type op;
46+
enum ipe_action_type action;
47+
struct list_head props;
48+
struct list_head next;
49+
};
50+
51+
struct ipe_op_table {
52+
struct list_head rules;
53+
enum ipe_action_type default_action;
54+
};
55+
56+
struct ipe_parsed_policy {
57+
const char *name;
58+
struct {
59+
u16 major;
60+
u16 minor;
61+
u16 rev;
62+
} version;
63+
64+
enum ipe_action_type global_default_action;
65+
66+
struct ipe_op_table rules[__IPE_OP_MAX];
67+
};
68+
69+
struct ipe_policy {
70+
const char *pkcs7;
71+
size_t pkcs7len;
72+
73+
const char *text;
74+
size_t textlen;
75+
76+
struct ipe_parsed_policy *parsed;
77+
};
78+
79+
struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
80+
const char *pkcs7, size_t pkcs7len);
81+
void ipe_free_policy(struct ipe_policy *pol);
82+
83+
#endif /* _IPE_POLICY_H */

0 commit comments

Comments
 (0)