Untangling ima mess, part 3: kill dead code in ima
[safe/jmp/linux-2.6] / security / integrity / ima / ima_main.c
1 /*
2  * Copyright (C) 2005,2006,2007,2008 IBM Corporation
3  *
4  * Authors:
5  * Reiner Sailer <sailer@watson.ibm.com>
6  * Serge Hallyn <serue@us.ibm.com>
7  * Kylene Hall <kylene@us.ibm.com>
8  * Mimi Zohar <zohar@us.ibm.com>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation, version 2 of the
13  * License.
14  *
15  * File: ima_main.c
16  *      implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17  *      and ima_path_check.
18  */
19 #include <linux/module.h>
20 #include <linux/file.h>
21 #include <linux/binfmts.h>
22 #include <linux/mount.h>
23 #include <linux/mman.h>
24
25 #include "ima.h"
26
27 int ima_initialized;
28
29 char *ima_hash = "sha1";
30 static int __init hash_setup(char *str)
31 {
32         if (strncmp(str, "md5", 3) == 0)
33                 ima_hash = "md5";
34         return 1;
35 }
36 __setup("ima_hash=", hash_setup);
37
38 /*
39  * Update the counts given an fmode_t
40  */
41 static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
42 {
43         BUG_ON(!mutex_is_locked(&iint->mutex));
44
45         iint->opencount++;
46         if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
47                 iint->readcount++;
48         if (mode & FMODE_WRITE)
49                 iint->writecount++;
50 }
51
52 /*
53  * Decrement ima counts
54  */
55 static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
56                            struct file *file)
57 {
58         mode_t mode = file->f_mode;
59         BUG_ON(!mutex_is_locked(&iint->mutex));
60
61         iint->opencount--;
62         if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
63                 iint->readcount--;
64         if (mode & FMODE_WRITE) {
65                 iint->writecount--;
66                 if (iint->writecount == 0) {
67                         if (iint->version != inode->i_version)
68                                 iint->flags &= ~IMA_MEASURED;
69                 }
70         }
71
72         if ((iint->opencount < 0) ||
73             (iint->readcount < 0) ||
74             (iint->writecount < 0)) {
75                 static int dumped;
76
77                 if (dumped)
78                         return;
79                 dumped = 1;
80
81                 printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
82                        __FUNCTION__, iint->readcount, iint->writecount,
83                        iint->opencount);
84                 dump_stack();
85         }
86 }
87
88 /**
89  * ima_file_free - called on __fput()
90  * @file: pointer to file structure being freed
91  *
92  * Flag files that changed, based on i_version;
93  * and decrement the iint readcount/writecount.
94  */
95 void ima_file_free(struct file *file)
96 {
97         struct inode *inode = file->f_dentry->d_inode;
98         struct ima_iint_cache *iint;
99
100         if (!ima_initialized || !S_ISREG(inode->i_mode))
101                 return;
102         iint = ima_iint_find_get(inode);
103         if (!iint)
104                 return;
105
106         mutex_lock(&iint->mutex);
107         ima_dec_counts(iint, inode, file);
108         mutex_unlock(&iint->mutex);
109         kref_put(&iint->refcount, iint_free);
110 }
111
112 /* ima_read_write_check - reflect possible reading/writing errors in the PCR.
113  *
114  * When opening a file for read, if the file is already open for write,
115  * the file could change, resulting in a file measurement error.
116  *
117  * Opening a file for write, if the file is already open for read, results
118  * in a time of measure, time of use (ToMToU) error.
119  *
120  * In either case invalidate the PCR.
121  */
122 enum iint_pcr_error { TOMTOU, OPEN_WRITERS };
123 static void ima_read_write_check(enum iint_pcr_error error,
124                                  struct ima_iint_cache *iint,
125                                  struct inode *inode,
126                                  const unsigned char *filename)
127 {
128         switch (error) {
129         case TOMTOU:
130                 if (iint->readcount > 0)
131                         ima_add_violation(inode, filename, "invalid_pcr",
132                                           "ToMToU");
133                 break;
134         case OPEN_WRITERS:
135                 if (iint->writecount > 0)
136                         ima_add_violation(inode, filename, "invalid_pcr",
137                                           "open_writers");
138                 break;
139         }
140 }
141
142 static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
143                                 const unsigned char *filename)
144 {
145         int rc = 0;
146
147         ima_inc_counts(iint, file->f_mode);
148
149         rc = ima_collect_measurement(iint, file);
150         if (!rc)
151                 ima_store_measurement(iint, file, filename);
152         return rc;
153 }
154
155 /**
156  * ima_path_check - based on policy, collect/store measurement.
157  * @path: contains a pointer to the path to be measured
158  * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
159  *
160  * Measure the file being open for readonly, based on the
161  * ima_must_measure() policy decision.
162  *
163  * Keep read/write counters for all files, but only
164  * invalidate the PCR for measured files:
165  *      - Opening a file for write when already open for read,
166  *        results in a time of measure, time of use (ToMToU) error.
167  *      - Opening a file for read when already open for write,
168  *        could result in a file measurement error.
169  *
170  * Always return 0 and audit dentry_open failures.
171  * (Return code will be based upon measurement appraisal.)
172  */
173 int ima_path_check(struct path *path, int mask)
174 {
175         struct inode *inode = path->dentry->d_inode;
176         struct ima_iint_cache *iint;
177         struct file *file = NULL;
178         int rc;
179
180         if (!ima_initialized || !S_ISREG(inode->i_mode))
181                 return 0;
182         iint = ima_iint_find_get(inode);
183         if (!iint)
184                 return 0;
185
186         mutex_lock(&iint->mutex);
187
188         rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
189         if (rc < 0)
190                 goto out;
191
192         if ((mask & MAY_WRITE) || (mask == 0))
193                 ima_read_write_check(TOMTOU, iint, inode,
194                                      path->dentry->d_name.name);
195
196         if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ)
197                 goto out;
198
199         ima_read_write_check(OPEN_WRITERS, iint, inode,
200                              path->dentry->d_name.name);
201         if (!(iint->flags & IMA_MEASURED)) {
202                 struct dentry *dentry = dget(path->dentry);
203                 struct vfsmount *mnt = mntget(path->mnt);
204
205                 file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
206                                    current_cred());
207                 if (IS_ERR(file)) {
208                         int audit_info = 0;
209
210                         integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
211                                             dentry->d_name.name,
212                                             "add_measurement",
213                                             "dentry_open failed",
214                                             1, audit_info);
215                         file = NULL;
216                         goto out;
217                 }
218                 rc = get_path_measurement(iint, file, dentry->d_name.name);
219         }
220 out:
221         mutex_unlock(&iint->mutex);
222         if (file)
223                 fput(file);
224         kref_put(&iint->refcount, iint_free);
225         return 0;
226 }
227 EXPORT_SYMBOL_GPL(ima_path_check);
228
229 static int process_measurement(struct file *file, const unsigned char *filename,
230                                int mask, int function)
231 {
232         struct inode *inode = file->f_dentry->d_inode;
233         struct ima_iint_cache *iint;
234         int rc;
235
236         if (!ima_initialized || !S_ISREG(inode->i_mode))
237                 return 0;
238         iint = ima_iint_find_get(inode);
239         if (!iint)
240                 return -ENOMEM;
241
242         mutex_lock(&iint->mutex);
243         rc = ima_must_measure(iint, inode, mask, function);
244         if (rc != 0)
245                 goto out;
246
247         rc = ima_collect_measurement(iint, file);
248         if (!rc)
249                 ima_store_measurement(iint, file, filename);
250 out:
251         mutex_unlock(&iint->mutex);
252         kref_put(&iint->refcount, iint_free);
253         return rc;
254 }
255
256 /*
257  * ima_counts_get - increment file counts
258  *
259  * - for IPC shm and shmat file.
260  * - for nfsd exported files.
261  *
262  * Increment the counts for these files to prevent unnecessary
263  * imbalance messages.
264  */
265 void ima_counts_get(struct file *file)
266 {
267         struct inode *inode = file->f_dentry->d_inode;
268         struct ima_iint_cache *iint;
269
270         if (!ima_initialized || !S_ISREG(inode->i_mode))
271                 return;
272         iint = ima_iint_find_get(inode);
273         if (!iint)
274                 return;
275         mutex_lock(&iint->mutex);
276         ima_inc_counts(iint, file->f_mode);
277         mutex_unlock(&iint->mutex);
278
279         kref_put(&iint->refcount, iint_free);
280 }
281 EXPORT_SYMBOL_GPL(ima_counts_get);
282
283 /**
284  * ima_file_mmap - based on policy, collect/store measurement.
285  * @file: pointer to the file to be measured (May be NULL)
286  * @prot: contains the protection that will be applied by the kernel.
287  *
288  * Measure files being mmapped executable based on the ima_must_measure()
289  * policy decision.
290  *
291  * Return 0 on success, an error code on failure.
292  * (Based on the results of appraise_measurement().)
293  */
294 int ima_file_mmap(struct file *file, unsigned long prot)
295 {
296         int rc;
297
298         if (!file)
299                 return 0;
300         if (prot & PROT_EXEC)
301                 rc = process_measurement(file, file->f_dentry->d_name.name,
302                                          MAY_EXEC, FILE_MMAP);
303         return 0;
304 }
305
306 /**
307  * ima_bprm_check - based on policy, collect/store measurement.
308  * @bprm: contains the linux_binprm structure
309  *
310  * The OS protects against an executable file, already open for write,
311  * from being executed in deny_write_access() and an executable file,
312  * already open for execute, from being modified in get_write_access().
313  * So we can be certain that what we verify and measure here is actually
314  * what is being executed.
315  *
316  * Return 0 on success, an error code on failure.
317  * (Based on the results of appraise_measurement().)
318  */
319 int ima_bprm_check(struct linux_binprm *bprm)
320 {
321         int rc;
322
323         rc = process_measurement(bprm->file, bprm->filename,
324                                  MAY_EXEC, BPRM_CHECK);
325         return 0;
326 }
327
328 static int __init init_ima(void)
329 {
330         int error;
331
332         ima_iintcache_init();
333         error = ima_init();
334         ima_initialized = 1;
335         return error;
336 }
337
338 static void __exit cleanup_ima(void)
339 {
340         ima_cleanup();
341 }
342
343 late_initcall(init_ima);        /* Start IMA after the TPM is available */
344
345 MODULE_DESCRIPTION("Integrity Measurement Architecture");
346 MODULE_LICENSE("GPL");