]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - security/integrity/ima/ima_appraise.c
ima: pass full xattr with the signature
[mirror_ubuntu-bionic-kernel.git] / security / integrity / ima / ima_appraise.c
CommitLineData
2fe5d6de
MZ
1/*
2 * Copyright (C) 2011 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 */
11#include <linux/module.h>
12#include <linux/file.h>
13#include <linux/fs.h>
14#include <linux/xattr.h>
15#include <linux/magic.h>
16#include <linux/ima.h>
17#include <linux/evm.h>
18
19#include "ima.h"
20
21static int __init default_appraise_setup(char *str)
22{
23 if (strncmp(str, "off", 3) == 0)
24 ima_appraise = 0;
25 else if (strncmp(str, "fix", 3) == 0)
26 ima_appraise = IMA_APPRAISE_FIX;
27 return 1;
28}
29
30__setup("ima_appraise=", default_appraise_setup);
31
32/*
33 * ima_must_appraise - set appraise flag
34 *
35 * Return 1 to appraise
36 */
d26e1936 37int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
2fe5d6de 38{
07f6a794
MZ
39 if (!ima_appraise)
40 return 0;
41
42 return ima_match_policy(inode, func, mask, IMA_APPRAISE);
2fe5d6de
MZ
43}
44
def3e8b9 45static int ima_fix_xattr(struct dentry *dentry,
c7c8bb23 46 struct integrity_iint_cache *iint)
2fe5d6de 47{
c7c8bb23 48 iint->ima_hash.type = IMA_XATTR_DIGEST;
def3e8b9 49 return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
c7c8bb23
DK
50 &iint->ima_hash.type,
51 1 + iint->ima_hash.length, 0);
2fe5d6de
MZ
52}
53
d79d72e0
MZ
54/* Return specific func appraised cached result */
55enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
56 int func)
57{
089bc8e9 58 switch (func) {
d79d72e0
MZ
59 case MMAP_CHECK:
60 return iint->ima_mmap_status;
61 case BPRM_CHECK:
62 return iint->ima_bprm_status;
63 case MODULE_CHECK:
64 return iint->ima_module_status;
65 case FILE_CHECK:
66 default:
67 return iint->ima_file_status;
68 }
69}
70
71static void ima_set_cache_status(struct integrity_iint_cache *iint,
72 int func, enum integrity_status status)
73{
089bc8e9 74 switch (func) {
d79d72e0
MZ
75 case MMAP_CHECK:
76 iint->ima_mmap_status = status;
77 break;
78 case BPRM_CHECK:
79 iint->ima_bprm_status = status;
80 break;
81 case MODULE_CHECK:
82 iint->ima_module_status = status;
83 break;
84 case FILE_CHECK:
85 default:
86 iint->ima_file_status = status;
87 break;
88 }
89}
90
91static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
92{
089bc8e9 93 switch (func) {
d79d72e0
MZ
94 case MMAP_CHECK:
95 iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED);
96 break;
97 case BPRM_CHECK:
98 iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
99 break;
100 case MODULE_CHECK:
101 iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
102 break;
103 case FILE_CHECK:
104 default:
105 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
106 break;
107 }
108}
109
d3634d0f
DK
110void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
111 struct ima_digest_data *hash)
112{
113 struct signature_v2_hdr *sig;
114
115 if (!xattr_value || xattr_len < 0 || xattr_len <= 1 + sizeof(*sig))
116 return;
117
118 sig = (typeof(sig)) xattr_value->digest;
119
120 if (xattr_value->type != EVM_IMA_XATTR_DIGSIG || sig->version != 2)
121 return;
122
123 hash->algo = sig->hash_algo;
124}
125
126int ima_read_xattr(struct dentry *dentry,
127 struct evm_ima_xattr_data **xattr_value)
128{
129 struct inode *inode = dentry->d_inode;
130
131 if (!inode->i_op->getxattr)
132 return 0;
133
134 return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
135 0, GFP_NOFS);
136}
137
2fe5d6de
MZ
138/*
139 * ima_appraise_measurement - appraise file measurement
140 *
141 * Call evm_verifyxattr() to verify the integrity of 'security.ima'.
142 * Assuming success, compare the xattr hash with the collected measurement.
143 *
144 * Return 0 on success, error code otherwise
145 */
d79d72e0 146int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
d3634d0f
DK
147 struct file *file, const unsigned char *filename,
148 struct evm_ima_xattr_data *xattr_value,
149 int xattr_len)
2fe5d6de
MZ
150{
151 struct dentry *dentry = file->f_dentry;
152 struct inode *inode = dentry->d_inode;
2fe5d6de
MZ
153 enum integrity_status status = INTEGRITY_UNKNOWN;
154 const char *op = "appraise_data";
155 char *cause = "unknown";
d3634d0f 156 int rc = xattr_len;
2fe5d6de
MZ
157
158 if (!ima_appraise)
159 return 0;
160 if (!inode->i_op->getxattr)
161 return INTEGRITY_UNKNOWN;
162
2fe5d6de
MZ
163 if (rc <= 0) {
164 if (rc && rc != -ENODATA)
165 goto out;
166
167 cause = "missing-hash";
168 status =
169 (inode->i_size == 0) ? INTEGRITY_PASS : INTEGRITY_NOLABEL;
170 goto out;
171 }
172
8606404f 173 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
2fe5d6de
MZ
174 if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) {
175 if ((status == INTEGRITY_NOLABEL)
176 || (status == INTEGRITY_NOXATTRS))
177 cause = "missing-HMAC";
178 else if (status == INTEGRITY_FAIL)
179 cause = "invalid-HMAC";
180 goto out;
181 }
8606404f
DK
182 switch (xattr_value->type) {
183 case IMA_XATTR_DIGEST:
0e5a247c
DK
184 if (iint->flags & IMA_DIGSIG_REQUIRED) {
185 cause = "IMA signature required";
186 status = INTEGRITY_FAIL;
187 break;
188 }
d3634d0f
DK
189 if (xattr_len - 1 >= iint->ima_hash.length)
190 /* xattr length may be longer. md5 hash in previous
191 version occupied 20 bytes in xattr, instead of 16
192 */
c7c8bb23
DK
193 rc = memcmp(xattr_value->digest,
194 iint->ima_hash.digest,
195 iint->ima_hash.length);
196 else
197 rc = -EINVAL;
8606404f
DK
198 if (rc) {
199 cause = "invalid-hash";
200 status = INTEGRITY_FAIL;
8606404f
DK
201 break;
202 }
203 status = INTEGRITY_PASS;
204 break;
205 case EVM_IMA_XATTR_DIGSIG:
206 iint->flags |= IMA_DIGSIG;
207 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
b1aaab22 208 (const char *)xattr_value, rc,
c7c8bb23
DK
209 iint->ima_hash.digest,
210 iint->ima_hash.length);
8606404f
DK
211 if (rc == -EOPNOTSUPP) {
212 status = INTEGRITY_UNKNOWN;
213 } else if (rc) {
214 cause = "invalid-signature";
215 status = INTEGRITY_FAIL;
216 } else {
217 status = INTEGRITY_PASS;
218 }
219 break;
220 default:
221 status = INTEGRITY_UNKNOWN;
222 cause = "unknown-ima-data";
223 break;
2fe5d6de 224 }
8606404f 225
2fe5d6de
MZ
226out:
227 if (status != INTEGRITY_PASS) {
8606404f
DK
228 if ((ima_appraise & IMA_APPRAISE_FIX) &&
229 (!xattr_value ||
230 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
def3e8b9
DK
231 if (!ima_fix_xattr(dentry, iint))
232 status = INTEGRITY_PASS;
2fe5d6de
MZ
233 }
234 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
235 op, cause, rc, 0);
8606404f 236 } else {
d79d72e0 237 ima_cache_flags(iint, func);
2fe5d6de 238 }
d79d72e0 239 ima_set_cache_status(iint, func, status);
2fe5d6de
MZ
240 return status;
241}
242
243/*
244 * ima_update_xattr - update 'security.ima' hash value
245 */
246void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
247{
248 struct dentry *dentry = file->f_dentry;
249 int rc = 0;
250
8606404f
DK
251 /* do not collect and update hash for digital signatures */
252 if (iint->flags & IMA_DIGSIG)
253 return;
254
d3634d0f 255 rc = ima_collect_measurement(iint, file, NULL, NULL);
2fe5d6de
MZ
256 if (rc < 0)
257 return;
8606404f 258
2fe5d6de
MZ
259 ima_fix_xattr(dentry, iint);
260}
261
262/**
263 * ima_inode_post_setattr - reflect file metadata changes
264 * @dentry: pointer to the affected dentry
265 *
266 * Changes to a dentry's metadata might result in needing to appraise.
267 *
268 * This function is called from notify_change(), which expects the caller
269 * to lock the inode's i_mutex.
270 */
271void ima_inode_post_setattr(struct dentry *dentry)
272{
273 struct inode *inode = dentry->d_inode;
274 struct integrity_iint_cache *iint;
275 int must_appraise, rc;
276
277 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)
278 || !inode->i_op->removexattr)
279 return;
280
281 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
282 iint = integrity_iint_find(inode);
283 if (iint) {
d79d72e0
MZ
284 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
285 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
286 IMA_ACTION_FLAGS);
2fe5d6de
MZ
287 if (must_appraise)
288 iint->flags |= IMA_APPRAISE;
2fe5d6de
MZ
289 }
290 if (!must_appraise)
291 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
292 return;
293}
42c63330
MZ
294
295/*
296 * ima_protect_xattr - protect 'security.ima'
297 *
298 * Ensure that not just anyone can modify or remove 'security.ima'.
299 */
300static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
301 const void *xattr_value, size_t xattr_value_len)
302{
303 if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) {
304 if (!capable(CAP_SYS_ADMIN))
305 return -EPERM;
306 return 1;
307 }
308 return 0;
309}
310
311static void ima_reset_appraise_flags(struct inode *inode)
312{
313 struct integrity_iint_cache *iint;
314
315 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode))
316 return;
317
318 iint = integrity_iint_find(inode);
319 if (!iint)
320 return;
321
45e2472e 322 iint->flags &= ~IMA_DONE_MASK;
42c63330
MZ
323 return;
324}
325
326int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
327 const void *xattr_value, size_t xattr_value_len)
328{
329 int result;
330
331 result = ima_protect_xattr(dentry, xattr_name, xattr_value,
332 xattr_value_len);
333 if (result == 1) {
334 ima_reset_appraise_flags(dentry->d_inode);
335 result = 0;
336 }
337 return result;
338}
339
340int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
341{
342 int result;
343
344 result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
345 if (result == 1) {
346 ima_reset_appraise_flags(dentry->d_inode);
347 result = 0;
348 }
349 return result;
350}