Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/integrity/ima/ima_iint.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2008 IBM Corporation
4
*
5
* Authors:
6
* Mimi Zohar <[email protected]>
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->real_inode.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_rcu - Called to free an inode via a RCU callback
113
* @inode_security: The inode->i_security pointer
114
*
115
* Free the IMA data associated with an inode.
116
*/
117
void ima_inode_free_rcu(void *inode_security)
118
{
119
struct ima_iint_cache **iint_p = inode_security + ima_blob_sizes.lbs_inode;
120
121
/* *iint_p should be NULL if !IS_IMA(inode) */
122
if (*iint_p)
123
ima_iint_free(*iint_p);
124
}
125
126
static void ima_iint_init_once(void *foo)
127
{
128
struct ima_iint_cache *iint = (struct ima_iint_cache *)foo;
129
130
memset(iint, 0, sizeof(*iint));
131
}
132
133
void __init ima_iintcache_init(void)
134
{
135
ima_iint_cache =
136
kmem_cache_create("ima_iint_cache", sizeof(struct ima_iint_cache),
137
0, SLAB_PANIC, ima_iint_init_once);
138
}
139
140