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