xref: /linux/security/ipe/ipe.c (revision a430d95c5efa2b545d26a094eb5f624e36732af0)
103115077SDeven Bowers // SPDX-License-Identifier: GPL-2.0
203115077SDeven Bowers /*
303115077SDeven Bowers  * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
403115077SDeven Bowers  */
503115077SDeven Bowers #include <uapi/linux/lsm.h>
603115077SDeven Bowers 
703115077SDeven Bowers #include "ipe.h"
8a8a74df1SFan Wu #include "eval.h"
952443cb6SDeven Bowers #include "hooks.h"
1003115077SDeven Bowers 
11*ba199dc9SDeven Bowers extern const char *const ipe_boot_policy;
122261306fSDeven Bowers bool ipe_enabled;
132261306fSDeven Bowers 
1403115077SDeven Bowers static struct lsm_blob_sizes ipe_blobs __ro_after_init = {
15a8a74df1SFan Wu 	.lbs_superblock = sizeof(struct ipe_superblock),
16e155858dSDeven Bowers #ifdef CONFIG_IPE_PROP_DM_VERITY
17e155858dSDeven Bowers 	.lbs_bdev = sizeof(struct ipe_bdev),
18e155858dSDeven Bowers #endif /* CONFIG_IPE_PROP_DM_VERITY */
1931f8c868SFan Wu #ifdef CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG
2031f8c868SFan Wu 	.lbs_inode = sizeof(struct ipe_inode),
2131f8c868SFan Wu #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
2203115077SDeven Bowers };
2303115077SDeven Bowers 
2403115077SDeven Bowers static const struct lsm_id ipe_lsmid = {
2503115077SDeven Bowers 	.name = "ipe",
2603115077SDeven Bowers 	.id = LSM_ID_IPE,
2703115077SDeven Bowers };
2803115077SDeven Bowers 
ipe_sb(const struct super_block * sb)29a8a74df1SFan Wu struct ipe_superblock *ipe_sb(const struct super_block *sb)
30a8a74df1SFan Wu {
31a8a74df1SFan Wu 	return sb->s_security + ipe_blobs.lbs_superblock;
32a8a74df1SFan Wu }
33a8a74df1SFan Wu 
34e155858dSDeven Bowers #ifdef CONFIG_IPE_PROP_DM_VERITY
ipe_bdev(struct block_device * b)35e155858dSDeven Bowers struct ipe_bdev *ipe_bdev(struct block_device *b)
36e155858dSDeven Bowers {
37e155858dSDeven Bowers 	return b->bd_security + ipe_blobs.lbs_bdev;
38e155858dSDeven Bowers }
39e155858dSDeven Bowers #endif /* CONFIG_IPE_PROP_DM_VERITY */
40e155858dSDeven Bowers 
4131f8c868SFan Wu #ifdef CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG
ipe_inode(const struct inode * inode)4231f8c868SFan Wu struct ipe_inode *ipe_inode(const struct inode *inode)
4331f8c868SFan Wu {
4431f8c868SFan Wu 	return inode->i_security + ipe_blobs.lbs_inode;
4531f8c868SFan Wu }
4631f8c868SFan Wu #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
4731f8c868SFan Wu 
4803115077SDeven Bowers static struct security_hook_list ipe_hooks[] __ro_after_init = {
4952443cb6SDeven Bowers 	LSM_HOOK_INIT(bprm_check_security, ipe_bprm_check_security),
5052443cb6SDeven Bowers 	LSM_HOOK_INIT(mmap_file, ipe_mmap_file),
5152443cb6SDeven Bowers 	LSM_HOOK_INIT(file_mprotect, ipe_file_mprotect),
5252443cb6SDeven Bowers 	LSM_HOOK_INIT(kernel_read_file, ipe_kernel_read_file),
5352443cb6SDeven Bowers 	LSM_HOOK_INIT(kernel_load_data, ipe_kernel_load_data),
54a8a74df1SFan Wu 	LSM_HOOK_INIT(initramfs_populated, ipe_unpack_initramfs),
55e155858dSDeven Bowers #ifdef CONFIG_IPE_PROP_DM_VERITY
56e155858dSDeven Bowers 	LSM_HOOK_INIT(bdev_free_security, ipe_bdev_free_security),
57e155858dSDeven Bowers 	LSM_HOOK_INIT(bdev_setintegrity, ipe_bdev_setintegrity),
58e155858dSDeven Bowers #endif /* CONFIG_IPE_PROP_DM_VERITY */
5931f8c868SFan Wu #ifdef CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG
6031f8c868SFan Wu 	LSM_HOOK_INIT(inode_setintegrity, ipe_inode_setintegrity),
6131f8c868SFan Wu #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
6203115077SDeven Bowers };
6303115077SDeven Bowers 
6403115077SDeven Bowers /**
6503115077SDeven Bowers  * ipe_init() - Entry point of IPE.
6603115077SDeven Bowers  *
6703115077SDeven Bowers  * This is called at LSM init, which happens occurs early during kernel
6803115077SDeven Bowers  * start up. During this phase, IPE registers its hooks and loads the
6903115077SDeven Bowers  * builtin boot policy.
7003115077SDeven Bowers  *
7103115077SDeven Bowers  * Return:
7203115077SDeven Bowers  * * %0		- OK
7303115077SDeven Bowers  * * %-ENOMEM	- Out of memory (OOM)
7403115077SDeven Bowers  */
ipe_init(void)7503115077SDeven Bowers static int __init ipe_init(void)
7603115077SDeven Bowers {
77*ba199dc9SDeven Bowers 	struct ipe_policy *p = NULL;
78*ba199dc9SDeven Bowers 
7903115077SDeven Bowers 	security_add_hooks(ipe_hooks, ARRAY_SIZE(ipe_hooks), &ipe_lsmid);
802261306fSDeven Bowers 	ipe_enabled = true;
8103115077SDeven Bowers 
82*ba199dc9SDeven Bowers 	if (ipe_boot_policy) {
83*ba199dc9SDeven Bowers 		p = ipe_new_policy(ipe_boot_policy, strlen(ipe_boot_policy),
84*ba199dc9SDeven Bowers 				   NULL, 0);
85*ba199dc9SDeven Bowers 		if (IS_ERR(p))
86*ba199dc9SDeven Bowers 			return PTR_ERR(p);
87*ba199dc9SDeven Bowers 
88*ba199dc9SDeven Bowers 		rcu_assign_pointer(ipe_active_policy, p);
89*ba199dc9SDeven Bowers 	}
90*ba199dc9SDeven Bowers 
9103115077SDeven Bowers 	return 0;
9203115077SDeven Bowers }
9303115077SDeven Bowers 
9403115077SDeven Bowers DEFINE_LSM(ipe) = {
9503115077SDeven Bowers 	.name = "ipe",
9603115077SDeven Bowers 	.init = ipe_init,
9703115077SDeven Bowers 	.blobs = &ipe_blobs,
9803115077SDeven Bowers };
99