Skip to content

Commit 84594c9

Browse files
robertosassupcmoore
authored andcommitted
ima: Move IMA-Appraisal to LSM infrastructure
A few additional IMA hooks are needed to reset the cached appraisal status, causing the file's integrity to be re-evaluated on next access. Register these IMA-appraisal only functions separately from the rest of IMA functions, as appraisal is a separate feature not necessarily enabled in the kernel configuration. Reuse the same approach as for other IMA functions, move hardcoded calls from various places in the kernel to the LSM infrastructure. Declare the functions as static and register them as hook implementations in init_ima_appraise_lsm(), called by init_ima_lsm(). Also move the inline function ima_inode_remove_acl() from the public ima.h header to ima_appraise.c. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> Reviewed-by: Casey Schaufler <casey@schaufler-ca.com> Acked-by: Christian Brauner <brauner@kernel.org> Acked-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
1 parent cd3cec0 commit 84594c9

File tree

6 files changed

+35
-79
lines changed

6 files changed

+35
-79
lines changed

fs/attr.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <linux/filelock.h>
1818
#include <linux/security.h>
1919
#include <linux/evm.h>
20-
#include <linux/ima.h>
2120

2221
#include "internal.h"
2322

@@ -503,7 +502,6 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
503502
if (!error) {
504503
fsnotify_change(dentry, ia_valid);
505504
security_inode_post_setattr(idmap, dentry, ia_valid);
506-
ima_inode_post_setattr(idmap, dentry, ia_valid);
507505
evm_inode_post_setattr(idmap, dentry, ia_valid);
508506
}
509507

include/linux/ima.h

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -92,66 +92,11 @@ static inline void ima_add_kexec_buffer(struct kimage *image)
9292

9393
#ifdef CONFIG_IMA_APPRAISE
9494
extern bool is_ima_appraise_enabled(void);
95-
extern void ima_inode_post_setattr(struct mnt_idmap *idmap,
96-
struct dentry *dentry, int ia_valid);
97-
extern int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
98-
const char *xattr_name, const void *xattr_value,
99-
size_t xattr_value_len, int flags);
100-
extern int ima_inode_set_acl(struct mnt_idmap *idmap,
101-
struct dentry *dentry, const char *acl_name,
102-
struct posix_acl *kacl);
103-
static inline int ima_inode_remove_acl(struct mnt_idmap *idmap,
104-
struct dentry *dentry,
105-
const char *acl_name)
106-
{
107-
return ima_inode_set_acl(idmap, dentry, acl_name, NULL);
108-
}
109-
110-
extern int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
111-
const char *xattr_name);
11295
#else
11396
static inline bool is_ima_appraise_enabled(void)
11497
{
11598
return 0;
11699
}
117-
118-
static inline void ima_inode_post_setattr(struct mnt_idmap *idmap,
119-
struct dentry *dentry, int ia_valid)
120-
{
121-
return;
122-
}
123-
124-
static inline int ima_inode_setxattr(struct mnt_idmap *idmap,
125-
struct dentry *dentry,
126-
const char *xattr_name,
127-
const void *xattr_value,
128-
size_t xattr_value_len,
129-
int flags)
130-
{
131-
return 0;
132-
}
133-
134-
static inline int ima_inode_set_acl(struct mnt_idmap *idmap,
135-
struct dentry *dentry, const char *acl_name,
136-
struct posix_acl *kacl)
137-
{
138-
139-
return 0;
140-
}
141-
142-
static inline int ima_inode_removexattr(struct mnt_idmap *idmap,
143-
struct dentry *dentry,
144-
const char *xattr_name)
145-
{
146-
return 0;
147-
}
148-
149-
static inline int ima_inode_remove_acl(struct mnt_idmap *idmap,
150-
struct dentry *dentry,
151-
const char *acl_name)
152-
{
153-
return 0;
154-
}
155100
#endif /* CONFIG_IMA_APPRAISE */
156101

157102
#if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)

security/integrity/ima/ima.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value,
334334
int xattr_len);
335335
int ima_read_xattr(struct dentry *dentry,
336336
struct evm_ima_xattr_data **xattr_value, int xattr_len);
337+
void __init init_ima_appraise_lsm(const struct lsm_id *lsmid);
337338

338339
#else
339340
static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
@@ -385,6 +386,10 @@ static inline int ima_read_xattr(struct dentry *dentry,
385386
return 0;
386387
}
387388

389+
static inline void __init init_ima_appraise_lsm(const struct lsm_id *lsmid)
390+
{
391+
}
392+
388393
#endif /* CONFIG_IMA_APPRAISE */
389394

390395
#ifdef CONFIG_IMA_APPRAISE_MODSIG

security/integrity/ima/ima_appraise.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,8 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
636636
* This function is called from notify_change(), which expects the caller
637637
* to lock the inode's i_mutex.
638638
*/
639-
void ima_inode_post_setattr(struct mnt_idmap *idmap,
640-
struct dentry *dentry, int ia_valid)
639+
static void ima_inode_post_setattr(struct mnt_idmap *idmap,
640+
struct dentry *dentry, int ia_valid)
641641
{
642642
struct inode *inode = d_backing_inode(dentry);
643643
struct integrity_iint_cache *iint;
@@ -750,9 +750,9 @@ static int validate_hash_algo(struct dentry *dentry,
750750
return -EACCES;
751751
}
752752

753-
int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
754-
const char *xattr_name, const void *xattr_value,
755-
size_t xattr_value_len, int flags)
753+
static int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
754+
const char *xattr_name, const void *xattr_value,
755+
size_t xattr_value_len, int flags)
756756
{
757757
const struct evm_ima_xattr_data *xvalue = xattr_value;
758758
int digsig = 0;
@@ -781,17 +781,17 @@ int ima_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
781781
return result;
782782
}
783783

784-
int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
785-
const char *acl_name, struct posix_acl *kacl)
784+
static int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
785+
const char *acl_name, struct posix_acl *kacl)
786786
{
787787
if (evm_revalidate_status(acl_name))
788788
ima_reset_appraise_flags(d_backing_inode(dentry), 0);
789789

790790
return 0;
791791
}
792792

793-
int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
794-
const char *xattr_name)
793+
static int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
794+
const char *xattr_name)
795795
{
796796
int result;
797797

@@ -803,3 +803,23 @@ int ima_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
803803
}
804804
return result;
805805
}
806+
807+
static int ima_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
808+
const char *acl_name)
809+
{
810+
return ima_inode_set_acl(idmap, dentry, acl_name, NULL);
811+
}
812+
813+
static struct security_hook_list ima_appraise_hooks[] __ro_after_init = {
814+
LSM_HOOK_INIT(inode_post_setattr, ima_inode_post_setattr),
815+
LSM_HOOK_INIT(inode_setxattr, ima_inode_setxattr),
816+
LSM_HOOK_INIT(inode_set_acl, ima_inode_set_acl),
817+
LSM_HOOK_INIT(inode_removexattr, ima_inode_removexattr),
818+
LSM_HOOK_INIT(inode_remove_acl, ima_inode_remove_acl),
819+
};
820+
821+
void __init init_ima_appraise_lsm(const struct lsm_id *lsmid)
822+
{
823+
security_add_hooks(ima_appraise_hooks, ARRAY_SIZE(ima_appraise_hooks),
824+
lsmid);
825+
}

security/integrity/ima/ima_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,7 @@ static const struct lsm_id ima_lsmid = {
11821182
static int __init init_ima_lsm(void)
11831183
{
11841184
security_add_hooks(ima_hooks, ARRAY_SIZE(ima_hooks), &ima_lsmid);
1185+
init_ima_appraise_lsm(&ima_lsmid);
11851186
return 0;
11861187
}
11871188

security/security.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include <linux/kernel_read_file.h>
2121
#include <linux/lsm_hooks.h>
2222
#include <linux/integrity.h>
23-
#include <linux/ima.h>
2423
#include <linux/evm.h>
2524
#include <linux/fsnotify.h>
2625
#include <linux/mman.h>
@@ -2308,9 +2307,6 @@ int security_inode_setxattr(struct mnt_idmap *idmap,
23082307

23092308
if (ret == 1)
23102309
ret = cap_inode_setxattr(dentry, name, value, size, flags);
2311-
if (ret)
2312-
return ret;
2313-
ret = ima_inode_setxattr(idmap, dentry, name, value, size, flags);
23142310
if (ret)
23152311
return ret;
23162312
return evm_inode_setxattr(idmap, dentry, name, value, size, flags);
@@ -2338,9 +2334,6 @@ int security_inode_set_acl(struct mnt_idmap *idmap,
23382334
return 0;
23392335
ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name,
23402336
kacl);
2341-
if (ret)
2342-
return ret;
2343-
ret = ima_inode_set_acl(idmap, dentry, acl_name, kacl);
23442337
if (ret)
23452338
return ret;
23462339
return evm_inode_set_acl(idmap, dentry, acl_name, kacl);
@@ -2401,9 +2394,6 @@ int security_inode_remove_acl(struct mnt_idmap *idmap,
24012394
if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
24022395
return 0;
24032396
ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name);
2404-
if (ret)
2405-
return ret;
2406-
ret = ima_inode_remove_acl(idmap, dentry, acl_name);
24072397
if (ret)
24082398
return ret;
24092399
return evm_inode_remove_acl(idmap, dentry, acl_name);
@@ -2503,9 +2493,6 @@ int security_inode_removexattr(struct mnt_idmap *idmap,
25032493
ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name);
25042494
if (ret == 1)
25052495
ret = cap_inode_removexattr(idmap, dentry, name);
2506-
if (ret)
2507-
return ret;
2508-
ret = ima_inode_removexattr(idmap, dentry, name);
25092496
if (ret)
25102497
return ret;
25112498
return evm_inode_removexattr(idmap, dentry, name);

0 commit comments

Comments
 (0)