aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_main.c')
-rw-r--r--security/integrity/ima/ima_main.c138
1 files changed, 63 insertions, 75 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index dba965de90d3..5127afcc4b89 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -61,7 +61,8 @@ static void ima_rdwr_violation_check(struct file *file)
61 fmode_t mode = file->f_mode; 61 fmode_t mode = file->f_mode;
62 int must_measure; 62 int must_measure;
63 bool send_tomtou = false, send_writers = false; 63 bool send_tomtou = false, send_writers = false;
64 unsigned char *pathname = NULL, *pathbuf = NULL; 64 char *pathbuf = NULL;
65 const char *pathname;
65 66
66 if (!S_ISREG(inode->i_mode) || !ima_initialized) 67 if (!S_ISREG(inode->i_mode) || !ima_initialized)
67 return; 68 return;
@@ -86,22 +87,15 @@ out:
86 if (!send_tomtou && !send_writers) 87 if (!send_tomtou && !send_writers)
87 return; 88 return;
88 89
89 /* We will allow 11 spaces for ' (deleted)' to be appended */ 90 pathname = ima_d_path(&file->f_path, &pathbuf);
90 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL); 91 if (!pathname || strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
91 if (pathbuf) { 92 pathname = dentry->d_name.name;
92 pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11); 93
93 if (IS_ERR(pathname))
94 pathname = NULL;
95 else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
96 pathname = NULL;
97 }
98 if (send_tomtou) 94 if (send_tomtou)
99 ima_add_violation(inode, 95 ima_add_violation(inode, pathname,
100 !pathname ? dentry->d_name.name : pathname,
101 "invalid_pcr", "ToMToU"); 96 "invalid_pcr", "ToMToU");
102 if (send_writers) 97 if (send_writers)
103 ima_add_violation(inode, 98 ima_add_violation(inode, pathname,
104 !pathname ? dentry->d_name.name : pathname,
105 "invalid_pcr", "open_writers"); 99 "invalid_pcr", "open_writers");
106 kfree(pathbuf); 100 kfree(pathbuf);
107} 101}
@@ -145,25 +139,31 @@ void ima_file_free(struct file *file)
145 ima_check_last_writer(iint, inode, file); 139 ima_check_last_writer(iint, inode, file);
146} 140}
147 141
148static int process_measurement(struct file *file, const unsigned char *filename, 142static int process_measurement(struct file *file, const char *filename,
149 int mask, int function) 143 int mask, int function)
150{ 144{
151 struct inode *inode = file->f_dentry->d_inode; 145 struct inode *inode = file->f_dentry->d_inode;
152 struct integrity_iint_cache *iint; 146 struct integrity_iint_cache *iint;
153 unsigned char *pathname = NULL, *pathbuf = NULL; 147 char *pathbuf = NULL;
154 int rc = -ENOMEM, action, must_appraise; 148 const char *pathname = NULL;
149 int rc = -ENOMEM, action, must_appraise, _func;
155 150
156 if (!ima_initialized || !S_ISREG(inode->i_mode)) 151 if (!ima_initialized || !S_ISREG(inode->i_mode))
157 return 0; 152 return 0;
158 153
159 /* Determine if in appraise/audit/measurement policy, 154 /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action
160 * returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask. */ 155 * bitmask based on the appraise/audit/measurement policy.
156 * Included is the appraise submask.
157 */
161 action = ima_get_action(inode, mask, function); 158 action = ima_get_action(inode, mask, function);
162 if (!action) 159 if (!action)
163 return 0; 160 return 0;
164 161
165 must_appraise = action & IMA_APPRAISE; 162 must_appraise = action & IMA_APPRAISE;
166 163
164 /* Is the appraise rule hook specific? */
165 _func = (action & IMA_FILE_APPRAISE) ? FILE_CHECK : function;
166
167 mutex_lock(&inode->i_mutex); 167 mutex_lock(&inode->i_mutex);
168 168
169 iint = integrity_inode_get(inode); 169 iint = integrity_inode_get(inode);
@@ -171,44 +171,45 @@ static int process_measurement(struct file *file, const unsigned char *filename,
171 goto out; 171 goto out;
172 172
173 /* Determine if already appraised/measured based on bitmask 173 /* Determine if already appraised/measured based on bitmask
174 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED, 174 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
175 * IMA_AUDIT, IMA_AUDITED) */ 175 * IMA_AUDIT, IMA_AUDITED)
176 */
176 iint->flags |= action; 177 iint->flags |= action;
178 action &= IMA_DO_MASK;
177 action &= ~((iint->flags & IMA_DONE_MASK) >> 1); 179 action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
178 180
179 /* Nothing to do, just return existing appraised status */ 181 /* Nothing to do, just return existing appraised status */
180 if (!action) { 182 if (!action) {
181 if (iint->flags & IMA_APPRAISED) 183 if (must_appraise)
182 rc = iint->ima_status; 184 rc = ima_get_cache_status(iint, _func);
183 goto out; 185 goto out_digsig;
184 } 186 }
185 187
186 rc = ima_collect_measurement(iint, file); 188 rc = ima_collect_measurement(iint, file);
187 if (rc != 0) 189 if (rc != 0)
188 goto out; 190 goto out_digsig;
191
192 if (function != BPRM_CHECK)
193 pathname = ima_d_path(&file->f_path, &pathbuf);
194
195 if (!pathname)
196 pathname = filename;
189 197
190 if (function != BPRM_CHECK) {
191 /* We will allow 11 spaces for ' (deleted)' to be appended */
192 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
193 if (pathbuf) {
194 pathname =
195 d_path(&file->f_path, pathbuf, PATH_MAX + 11);
196 if (IS_ERR(pathname))
197 pathname = NULL;
198 }
199 }
200 if (action & IMA_MEASURE) 198 if (action & IMA_MEASURE)
201 ima_store_measurement(iint, file, 199 ima_store_measurement(iint, file, pathname);
202 !pathname ? filename : pathname); 200 if (action & IMA_APPRAISE_SUBMASK)
203 if (action & IMA_APPRAISE) 201 rc = ima_appraise_measurement(_func, iint, file, pathname);
204 rc = ima_appraise_measurement(iint, file,
205 !pathname ? filename : pathname);
206 if (action & IMA_AUDIT) 202 if (action & IMA_AUDIT)
207 ima_audit_measurement(iint, !pathname ? filename : pathname); 203 ima_audit_measurement(iint, pathname);
208 kfree(pathbuf); 204 kfree(pathbuf);
205out_digsig:
206 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG))
207 rc = -EACCES;
209out: 208out:
210 mutex_unlock(&inode->i_mutex); 209 mutex_unlock(&inode->i_mutex);
211 return (rc && must_appraise) ? -EACCES : 0; 210 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
211 return -EACCES;
212 return 0;
212} 213}
213 214
214/** 215/**
@@ -219,19 +220,15 @@ out:
219 * Measure files being mmapped executable based on the ima_must_measure() 220 * Measure files being mmapped executable based on the ima_must_measure()
220 * policy decision. 221 * policy decision.
221 * 222 *
222 * Return 0 on success, an error code on failure. 223 * On success return 0. On integrity appraisal error, assuming the file
223 * (Based on the results of appraise_measurement().) 224 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
224 */ 225 */
225int ima_file_mmap(struct file *file, unsigned long prot) 226int ima_file_mmap(struct file *file, unsigned long prot)
226{ 227{
227 int rc = 0; 228 if (file && (prot & PROT_EXEC))
228 229 return process_measurement(file, file->f_dentry->d_name.name,
229 if (!file) 230 MAY_EXEC, MMAP_CHECK);
230 return 0; 231 return 0;
231 if (prot & PROT_EXEC)
232 rc = process_measurement(file, file->f_dentry->d_name.name,
233 MAY_EXEC, FILE_MMAP);
234 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
235} 232}
236 233
237/** 234/**
@@ -244,18 +241,15 @@ int ima_file_mmap(struct file *file, unsigned long prot)
244 * So we can be certain that what we verify and measure here is actually 241 * So we can be certain that what we verify and measure here is actually
245 * what is being executed. 242 * what is being executed.
246 * 243 *
247 * Return 0 on success, an error code on failure. 244 * On success return 0. On integrity appraisal error, assuming the file
248 * (Based on the results of appraise_measurement().) 245 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
249 */ 246 */
250int ima_bprm_check(struct linux_binprm *bprm) 247int ima_bprm_check(struct linux_binprm *bprm)
251{ 248{
252 int rc; 249 return process_measurement(bprm->file,
253
254 rc = process_measurement(bprm->file,
255 (strcmp(bprm->filename, bprm->interp) == 0) ? 250 (strcmp(bprm->filename, bprm->interp) == 0) ?
256 bprm->filename : bprm->interp, 251 bprm->filename : bprm->interp,
257 MAY_EXEC, BPRM_CHECK); 252 MAY_EXEC, BPRM_CHECK);
258 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
259} 253}
260 254
261/** 255/**
@@ -265,18 +259,15 @@ int ima_bprm_check(struct linux_binprm *bprm)
265 * 259 *
266 * Measure files based on the ima_must_measure() policy decision. 260 * Measure files based on the ima_must_measure() policy decision.
267 * 261 *
268 * Always return 0 and audit dentry_open failures. 262 * On success return 0. On integrity appraisal error, assuming the file
269 * (Return code will be based upon measurement appraisal.) 263 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
270 */ 264 */
271int ima_file_check(struct file *file, int mask) 265int ima_file_check(struct file *file, int mask)
272{ 266{
273 int rc;
274
275 ima_rdwr_violation_check(file); 267 ima_rdwr_violation_check(file);
276 rc = process_measurement(file, file->f_dentry->d_name.name, 268 return process_measurement(file, file->f_dentry->d_name.name,
277 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 269 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
278 FILE_CHECK); 270 FILE_CHECK);
279 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
280} 271}
281EXPORT_SYMBOL_GPL(ima_file_check); 272EXPORT_SYMBOL_GPL(ima_file_check);
282 273
@@ -286,23 +277,20 @@ EXPORT_SYMBOL_GPL(ima_file_check);
286 * 277 *
287 * Measure/appraise kernel modules based on policy. 278 * Measure/appraise kernel modules based on policy.
288 * 279 *
289 * Always return 0 and audit dentry_open failures. 280 * On success return 0. On integrity appraisal error, assuming the file
290 * Return code is based upon measurement appraisal. 281 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
291 */ 282 */
292int ima_module_check(struct file *file) 283int ima_module_check(struct file *file)
293{ 284{
294 int rc = 0;
295
296 if (!file) { 285 if (!file) {
297 if (ima_appraise & IMA_APPRAISE_MODULES) {
298#ifndef CONFIG_MODULE_SIG_FORCE 286#ifndef CONFIG_MODULE_SIG_FORCE
299 rc = -EACCES; /* INTEGRITY_UNKNOWN */ 287 if (ima_appraise & IMA_APPRAISE_MODULES)
288 return -EACCES; /* INTEGRITY_UNKNOWN */
300#endif 289#endif
301 } 290 return 0; /* We rely on module signature checking */
302 } else 291 }
303 rc = process_measurement(file, file->f_dentry->d_name.name, 292 return process_measurement(file, file->f_dentry->d_name.name,
304 MAY_EXEC, MODULE_CHECK); 293 MAY_EXEC, MODULE_CHECK);
305 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
306} 294}
307 295
308static int __init init_ima(void) 296static int __init init_ima(void)