Commit ad16ad00c34d3f320a5876b3d711ef6bc81362e1
Committed by
Linus Torvalds
1 parent
15aac67677
IMA: use inode->i_lock to protect read and write counters
Currently IMA used the iint->mutex to protect the i_readcount and i_writecount. This patch uses the inode->i_lock since we are going to start using in inode objects and that is the most appropriate lock. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 24 additions and 34 deletions Side-by-side Diff
security/integrity/ima/ima.h
... | ... | @@ -106,6 +106,7 @@ |
106 | 106 | unsigned char flags; |
107 | 107 | u8 digest[IMA_DIGEST_SIZE]; |
108 | 108 | struct mutex mutex; /* protects: version, flags, digest */ |
109 | + /* protected by inode->i_lock */ | |
109 | 110 | unsigned int readcount; /* measured files readcount */ |
110 | 111 | unsigned int writecount;/* measured files writecount */ |
111 | 112 | struct kref refcount; /* ima_iint_cache reference count */ |
security/integrity/ima/ima_main.c
... | ... | @@ -85,42 +85,12 @@ |
85 | 85 | return found; |
86 | 86 | } |
87 | 87 | |
88 | -/* ima_read_write_check - reflect possible reading/writing errors in the PCR. | |
89 | - * | |
90 | - * When opening a file for read, if the file is already open for write, | |
91 | - * the file could change, resulting in a file measurement error. | |
92 | - * | |
93 | - * Opening a file for write, if the file is already open for read, results | |
94 | - * in a time of measure, time of use (ToMToU) error. | |
95 | - * | |
96 | - * In either case invalidate the PCR. | |
97 | - */ | |
98 | -enum iint_pcr_error { TOMTOU, OPEN_WRITERS }; | |
99 | -static void ima_read_write_check(enum iint_pcr_error error, | |
100 | - struct ima_iint_cache *iint, | |
101 | - struct inode *inode, | |
102 | - const unsigned char *filename) | |
103 | -{ | |
104 | - switch (error) { | |
105 | - case TOMTOU: | |
106 | - if (iint->readcount > 0) | |
107 | - ima_add_violation(inode, filename, "invalid_pcr", | |
108 | - "ToMToU"); | |
109 | - break; | |
110 | - case OPEN_WRITERS: | |
111 | - if (iint->writecount > 0) | |
112 | - ima_add_violation(inode, filename, "invalid_pcr", | |
113 | - "open_writers"); | |
114 | - break; | |
115 | - } | |
116 | -} | |
117 | - | |
118 | 88 | /* |
119 | 89 | * Update the counts given an fmode_t |
120 | 90 | */ |
121 | 91 | static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode) |
122 | 92 | { |
123 | - BUG_ON(!mutex_is_locked(&iint->mutex)); | |
93 | + assert_spin_locked(&iint->inode->i_lock); | |
124 | 94 | |
125 | 95 | if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) |
126 | 96 | iint->readcount++; |
... | ... | @@ -146,6 +116,7 @@ |
146 | 116 | fmode_t mode = file->f_mode; |
147 | 117 | struct ima_iint_cache *iint; |
148 | 118 | int rc; |
119 | + bool send_tomtou = false, send_writers = false; | |
149 | 120 | |
150 | 121 | if (!iint_initialized || !S_ISREG(inode->i_mode)) |
151 | 122 | return; |
152 | 123 | |
153 | 124 | |
154 | 125 | |
155 | 126 | |
156 | 127 | |
157 | 128 | |
... | ... | @@ -153,22 +124,35 @@ |
153 | 124 | if (!iint) |
154 | 125 | return; |
155 | 126 | mutex_lock(&iint->mutex); |
127 | + spin_lock(&inode->i_lock); | |
128 | + | |
156 | 129 | if (!ima_initialized) |
157 | 130 | goto out; |
131 | + | |
158 | 132 | rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK); |
159 | 133 | if (rc < 0) |
160 | 134 | goto out; |
161 | 135 | |
162 | 136 | if (mode & FMODE_WRITE) { |
163 | - ima_read_write_check(TOMTOU, iint, inode, dentry->d_name.name); | |
137 | + if (iint->readcount) | |
138 | + send_tomtou = true; | |
164 | 139 | goto out; |
165 | 140 | } |
166 | - ima_read_write_check(OPEN_WRITERS, iint, inode, dentry->d_name.name); | |
141 | + | |
142 | + if (atomic_read(&inode->i_writecount) > 0) | |
143 | + send_writers = true; | |
167 | 144 | out: |
168 | 145 | ima_inc_counts(iint, file->f_mode); |
146 | + spin_unlock(&inode->i_lock); | |
169 | 147 | mutex_unlock(&iint->mutex); |
170 | - | |
171 | 148 | kref_put(&iint->refcount, iint_free); |
149 | + | |
150 | + if (send_tomtou) | |
151 | + ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | |
152 | + "ToMToU"); | |
153 | + if (send_writers) | |
154 | + ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | |
155 | + "open_writers"); | |
172 | 156 | } |
173 | 157 | |
174 | 158 | /* |
... | ... | @@ -181,6 +165,7 @@ |
181 | 165 | bool dump = false; |
182 | 166 | |
183 | 167 | BUG_ON(!mutex_is_locked(&iint->mutex)); |
168 | + assert_spin_locked(&inode->i_lock); | |
184 | 169 | |
185 | 170 | if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { |
186 | 171 | if (unlikely(iint->readcount == 0)) |
187 | 172 | |
... | ... | @@ -223,7 +208,11 @@ |
223 | 208 | return; |
224 | 209 | |
225 | 210 | mutex_lock(&iint->mutex); |
211 | + spin_lock(&inode->i_lock); | |
212 | + | |
226 | 213 | ima_dec_counts(iint, inode, file); |
214 | + | |
215 | + spin_unlock(&inode->i_lock); | |
227 | 216 | mutex_unlock(&iint->mutex); |
228 | 217 | kref_put(&iint->refcount, iint_free); |
229 | 218 | } |