Commit | Line | Data |
---|---|---|
4de2f084 RS |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* | |
3 | * Copyright (C) 2008 IBM Corporation | |
4 | * | |
5 | * Authors: | |
6 | * Mimi Zohar <zohar@us.ibm.com> | |
7 | * | |
8 | * File: ima_iint.c | |
9 | * - implements the IMA hook: ima_inode_free | |
10 | * - cache integrity information in the inode security blob | |
11 | */ | |
12 | #include <linux/slab.h> | |
13 | ||
14 | #include "ima.h" | |
15 | ||
16 | static struct kmem_cache *ima_iint_cache __ro_after_init; | |
17 | ||
18 | /** | |
19 | * ima_iint_find - Return the iint associated with an inode | |
20 | * @inode: Pointer to the inode | |
21 | * | |
22 | * Return the IMA integrity information (iint) associated with an inode, if the | |
23 | * inode was processed by IMA. | |
24 | * | |
25 | * Return: Found iint or NULL. | |
26 | */ | |
27 | struct ima_iint_cache *ima_iint_find(struct inode *inode) | |
28 | { | |
29 | if (!IS_IMA(inode)) | |
30 | return NULL; | |
31 | ||
32 | return ima_inode_get_iint(inode); | |
33 | } | |
34 | ||
35 | #define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH + 1) | |
36 | ||
37 | /* | |
38 | * It is not clear that IMA should be nested at all, but as long is it measures | |
39 | * files both on overlayfs and on underlying fs, we need to annotate the iint | |
40 | * mutex to avoid lockdep false positives related to IMA + overlayfs. | |
41 | * See ovl_lockdep_annotate_inode_mutex_key() for more details. | |
42 | */ | |
43 | static inline void ima_iint_lockdep_annotate(struct ima_iint_cache *iint, | |
44 | struct inode *inode) | |
45 | { | |
46 | #ifdef CONFIG_LOCKDEP | |
47 | static struct lock_class_key ima_iint_mutex_key[IMA_MAX_NESTING]; | |
48 | ||
49 | int depth = inode->i_sb->s_stack_depth; | |
50 | ||
51 | if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING)) | |
52 | depth = 0; | |
53 | ||
54 | lockdep_set_class(&iint->mutex, &ima_iint_mutex_key[depth]); | |
55 | #endif | |
56 | } | |
57 | ||
58 | static void ima_iint_init_always(struct ima_iint_cache *iint, | |
59 | struct inode *inode) | |
60 | { | |
61 | iint->ima_hash = NULL; | |
62 | iint->version = 0; | |
63 | iint->flags = 0UL; | |
64 | iint->atomic_flags = 0UL; | |
65 | iint->ima_file_status = INTEGRITY_UNKNOWN; | |
66 | iint->ima_mmap_status = INTEGRITY_UNKNOWN; | |
67 | iint->ima_bprm_status = INTEGRITY_UNKNOWN; | |
68 | iint->ima_read_status = INTEGRITY_UNKNOWN; | |
69 | iint->ima_creds_status = INTEGRITY_UNKNOWN; | |
70 | iint->measured_pcrs = 0; | |
71 | mutex_init(&iint->mutex); | |
72 | ima_iint_lockdep_annotate(iint, inode); | |
73 | } | |
74 | ||
75 | static void ima_iint_free(struct ima_iint_cache *iint) | |
76 | { | |
77 | kfree(iint->ima_hash); | |
78 | mutex_destroy(&iint->mutex); | |
79 | kmem_cache_free(ima_iint_cache, iint); | |
80 | } | |
81 | ||
82 | /** | |
83 | * ima_inode_get - Find or allocate an iint associated with an inode | |
84 | * @inode: Pointer to the inode | |
85 | * | |
86 | * Find an iint associated with an inode, and allocate a new one if not found. | |
87 | * Caller must lock i_mutex. | |
88 | * | |
89 | * Return: An iint on success, NULL on error. | |
90 | */ | |
91 | struct ima_iint_cache *ima_inode_get(struct inode *inode) | |
92 | { | |
93 | struct ima_iint_cache *iint; | |
94 | ||
95 | iint = ima_iint_find(inode); | |
96 | if (iint) | |
97 | return iint; | |
98 | ||
99 | iint = kmem_cache_alloc(ima_iint_cache, GFP_NOFS); | |
100 | if (!iint) | |
101 | return NULL; | |
102 | ||
103 | ima_iint_init_always(iint, inode); | |
104 | ||
105 | inode->i_flags |= S_IMA; | |
106 | ima_inode_set_iint(inode, iint); | |
107 | ||
108 | return iint; | |
109 | } | |
110 | ||
111 | /** | |
112 | * ima_inode_free - Called on inode free | |
113 | * @inode: Pointer to the inode | |
114 | * | |
115 | * Free the iint associated with an inode. | |
116 | */ | |
117 | void ima_inode_free(struct inode *inode) | |
118 | { | |
119 | struct ima_iint_cache *iint; | |
120 | ||
121 | if (!IS_IMA(inode)) | |
122 | return; | |
123 | ||
124 | iint = ima_iint_find(inode); | |
125 | ima_inode_set_iint(inode, NULL); | |
126 | ||
127 | ima_iint_free(iint); | |
128 | } | |
129 | ||
130 | static void ima_iint_init_once(void *foo) | |
131 | { | |
132 | struct ima_iint_cache *iint = (struct ima_iint_cache *)foo; | |
133 | ||
134 | memset(iint, 0, sizeof(*iint)); | |
135 | } | |
136 | ||
137 | void __init ima_iintcache_init(void) | |
138 | { | |
139 | ima_iint_cache = | |
140 | kmem_cache_create("ima_iint_cache", sizeof(struct ima_iint_cache), | |
141 | 0, SLAB_PANIC, ima_iint_init_once); | |
142 | } |