Skip to content

Commit cd3cec0

Browse files
robertosassupcmoore
authored andcommitted
ima: Move to LSM infrastructure
Move hardcoded IMA function calls (not appraisal-specific functions) from various places in the kernel to the LSM infrastructure, by introducing a new LSM named 'ima' (at the end of the LSM list and always enabled like 'integrity'). Having IMA before EVM in the Makefile is sufficient to preserve the relative order of the new 'ima' LSM in respect to the upcoming 'evm' LSM, and thus the order of IMA and EVM function calls as when they were hardcoded. Make moved functions as static (except ima_post_key_create_or_update(), which is not in ima_main.c), and register them as implementation of the respective hooks in the new function init_ima_lsm(). Select CONFIG_SECURITY_PATH, to ensure that the path-based LSM hook path_post_mknod is always available and ima_post_path_mknod() is always executed to mark files as new, as before the move. A slight difference is that IMA and EVM functions registered for the inode_post_setattr, inode_post_removexattr, path_post_mknod, inode_post_create_tmpfile, inode_post_set_acl and inode_post_remove_acl won't be executed for private inodes. Since those inodes are supposed to be fs-internal, they should not be of interest to IMA or EVM. The S_PRIVATE flag is used for anonymous inodes, hugetlbfs, reiserfs xattrs, XFS scrub and kernel-internal tmpfs files. Conditionally register ima_post_key_create_or_update() if CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS is enabled. Also, conditionally register ima_kernel_module_request() if CONFIG_INTEGRITY_ASYMMETRIC_KEYS is enabled. Finally, add the LSM_ID_IMA case in lsm_list_modules_test.c. Signed-off-by: Roberto Sassu <[email protected]> Acked-by: Chuck Lever <[email protected]> Acked-by: Casey Schaufler <[email protected]> Acked-by: Christian Brauner <[email protected]> Reviewed-by: Stefan Berger <[email protected]> Reviewed-by: Mimi Zohar <[email protected]> Acked-by: Mimi Zohar <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 06cca51 commit cd3cec0

File tree

14 files changed

+83
-200
lines changed

14 files changed

+83
-200
lines changed

fs/file_table.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include <linux/percpu_counter.h>
2727
#include <linux/percpu.h>
2828
#include <linux/task_work.h>
29-
#include <linux/ima.h>
3029
#include <linux/swap.h>
3130
#include <linux/kmemleak.h>
3231

@@ -368,7 +367,6 @@ static void __fput(struct file *file)
368367
locks_remove_file(file);
369368

370369
security_file_release(file);
371-
ima_file_free(file);
372370
if (unlikely(file->f_flags & FASYNC)) {
373371
if (file->f_op->fasync)
374372
file->f_op->fasync(-1, file, 0);

fs/namei.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <linux/fsnotify.h>
2828
#include <linux/personality.h>
2929
#include <linux/security.h>
30-
#include <linux/ima.h>
3130
#include <linux/syscalls.h>
3231
#include <linux/mount.h>
3332
#include <linux/audit.h>
@@ -3641,8 +3640,6 @@ static int do_open(struct nameidata *nd,
36413640
error = vfs_open(&nd->path, file);
36423641
if (!error)
36433642
error = security_file_post_open(file, op->acc_mode);
3644-
if (!error)
3645-
error = ima_file_check(file, op->acc_mode);
36463643
if (!error && do_truncate)
36473644
error = handle_truncate(idmap, file);
36483645
if (unlikely(error > 0)) {
@@ -3706,7 +3703,6 @@ static int vfs_tmpfile(struct mnt_idmap *idmap,
37063703
spin_unlock(&inode->i_lock);
37073704
}
37083705
security_inode_post_create_tmpfile(idmap, inode);
3709-
ima_post_create_tmpfile(idmap, inode);
37103706
return 0;
37113707
}
37123708

@@ -4052,8 +4048,6 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
40524048
case 0: case S_IFREG:
40534049
error = vfs_create(idmap, path.dentry->d_inode,
40544050
dentry, mode, true);
4055-
if (!error)
4056-
ima_post_path_mknod(idmap, dentry);
40574051
break;
40584052
case S_IFCHR: case S_IFBLK:
40594053
error = vfs_mknod(idmap, path.dentry->d_inode,

fs/nfsd/vfs.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <linux/posix_acl_xattr.h>
2626
#include <linux/xattr.h>
2727
#include <linux/jhash.h>
28-
#include <linux/ima.h>
2928
#include <linux/pagemap.h>
3029
#include <linux/slab.h>
3130
#include <linux/uaccess.h>
@@ -883,12 +882,6 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
883882
goto out;
884883
}
885884

886-
host_err = ima_file_check(file, may_flags);
887-
if (host_err) {
888-
fput(file);
889-
goto out;
890-
}
891-
892885
if (may_flags & NFSD_MAY_64BIT_COOKIE)
893886
file->f_mode |= FMODE_64BITHASH;
894887
else

fs/open.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include <linux/audit.h>
3030
#include <linux/falloc.h>
3131
#include <linux/fs_struct.h>
32-
#include <linux/ima.h>
3332
#include <linux/dnotify.h>
3433
#include <linux/compat.h>
3534
#include <linux/mnt_idmapping.h>

include/linux/ima.h

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,6 @@ struct linux_binprm;
1616

1717
#ifdef CONFIG_IMA
1818
extern enum hash_algo ima_get_current_hash_algo(void);
19-
extern int ima_bprm_check(struct linux_binprm *bprm);
20-
extern int ima_file_check(struct file *file, int mask);
21-
extern void ima_post_create_tmpfile(struct mnt_idmap *idmap,
22-
struct inode *inode);
23-
extern void ima_file_free(struct file *file);
24-
extern int ima_file_mmap(struct file *file, unsigned long reqprot,
25-
unsigned long prot, unsigned long flags);
26-
extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
27-
unsigned long prot);
28-
extern int ima_load_data(enum kernel_load_data_id id, bool contents);
29-
extern int ima_post_load_data(char *buf, loff_t size,
30-
enum kernel_load_data_id id, char *description);
31-
extern int ima_read_file(struct file *file, enum kernel_read_file_id id,
32-
bool contents);
33-
extern int ima_post_read_file(struct file *file, char *buf, loff_t size,
34-
enum kernel_read_file_id id);
35-
extern void ima_post_path_mknod(struct mnt_idmap *idmap,
36-
struct dentry *dentry);
3719
extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
3820
extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size);
3921
extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);
@@ -58,68 +40,6 @@ static inline enum hash_algo ima_get_current_hash_algo(void)
5840
return HASH_ALGO__LAST;
5941
}
6042

61-
static inline int ima_bprm_check(struct linux_binprm *bprm)
62-
{
63-
return 0;
64-
}
65-
66-
static inline int ima_file_check(struct file *file, int mask)
67-
{
68-
return 0;
69-
}
70-
71-
static inline void ima_post_create_tmpfile(struct mnt_idmap *idmap,
72-
struct inode *inode)
73-
{
74-
}
75-
76-
static inline void ima_file_free(struct file *file)
77-
{
78-
return;
79-
}
80-
81-
static inline int ima_file_mmap(struct file *file, unsigned long reqprot,
82-
unsigned long prot, unsigned long flags)
83-
{
84-
return 0;
85-
}
86-
87-
static inline int ima_file_mprotect(struct vm_area_struct *vma,
88-
unsigned long reqprot, unsigned long prot)
89-
{
90-
return 0;
91-
}
92-
93-
static inline int ima_load_data(enum kernel_load_data_id id, bool contents)
94-
{
95-
return 0;
96-
}
97-
98-
static inline int ima_post_load_data(char *buf, loff_t size,
99-
enum kernel_load_data_id id,
100-
char *description)
101-
{
102-
return 0;
103-
}
104-
105-
static inline int ima_read_file(struct file *file, enum kernel_read_file_id id,
106-
bool contents)
107-
{
108-
return 0;
109-
}
110-
111-
static inline int ima_post_read_file(struct file *file, char *buf, loff_t size,
112-
enum kernel_read_file_id id)
113-
{
114-
return 0;
115-
}
116-
117-
static inline void ima_post_path_mknod(struct mnt_idmap *idmap,
118-
struct dentry *dentry)
119-
{
120-
return;
121-
}
122-
12343
static inline int ima_file_hash(struct file *file, char *buf, size_t buf_size)
12444
{
12545
return -EOPNOTSUPP;
@@ -170,20 +90,6 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
17090
{}
17191
#endif
17292

173-
#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
174-
extern void ima_post_key_create_or_update(struct key *keyring,
175-
struct key *key,
176-
const void *payload, size_t plen,
177-
unsigned long flags, bool create);
178-
#else
179-
static inline void ima_post_key_create_or_update(struct key *keyring,
180-
struct key *key,
181-
const void *payload,
182-
size_t plen,
183-
unsigned long flags,
184-
bool create) {}
185-
#endif /* CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS */
186-
18793
#ifdef CONFIG_IMA_APPRAISE
18894
extern bool is_ima_appraise_enabled(void);
18995
extern void ima_inode_post_setattr(struct mnt_idmap *idmap,
@@ -256,14 +162,4 @@ static inline bool ima_appraise_signature(enum kernel_read_file_id func)
256162
return false;
257163
}
258164
#endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
259-
260-
#if defined(CONFIG_IMA) && defined(CONFIG_INTEGRITY_ASYMMETRIC_KEYS)
261-
extern int ima_kernel_module_request(char *kmod_name);
262-
#else
263-
static inline int ima_kernel_module_request(char *kmod_name)
264-
{
265-
return 0;
266-
}
267-
268-
#endif
269165
#endif /* _LINUX_IMA_H */

include/uapi/linux/lsm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct lsm_ctx {
6262
#define LSM_ID_LOCKDOWN 108
6363
#define LSM_ID_BPF 109
6464
#define LSM_ID_LANDLOCK 110
65+
#define LSM_ID_IMA 111
6566

6667
/*
6768
* LSM_ATTR_XXX definitions identify different LSM attributes

security/integrity/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o
1818
integrity-$(CONFIG_LOAD_PPC_KEYS) += platform_certs/efi_parser.o \
1919
platform_certs/load_powerpc.o \
2020
platform_certs/keyring_handler.o
21+
# The relative order of the 'ima' and 'evm' LSMs depends on the order below.
2122
obj-$(CONFIG_IMA) += ima/
2223
obj-$(CONFIG_EVM) += evm/

security/integrity/ima/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ config IMA
88
select CRYPTO_HMAC
99
select CRYPTO_SHA1
1010
select CRYPTO_HASH_INFO
11+
select SECURITY_PATH
1112
select TCG_TPM if HAS_IOMEM
1213
select TCG_TIS if TCG_TPM && X86
1314
select TCG_CRB if TCG_TPM && ACPI

security/integrity/ima/ima.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ void ima_load_kexec_buffer(void);
127127
static inline void ima_load_kexec_buffer(void) {}
128128
#endif /* CONFIG_HAVE_IMA_KEXEC */
129129

130+
#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
131+
void ima_post_key_create_or_update(struct key *keyring, struct key *key,
132+
const void *payload, size_t plen,
133+
unsigned long flags, bool create);
134+
#endif
135+
130136
/*
131137
* The default binary_runtime_measurements list format is defined as the
132138
* platform native format. The canonical format is defined as little-endian.

0 commit comments

Comments
 (0)