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.c86
1 files changed, 46 insertions, 40 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f4e7266f5aee..6f611874d10e 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -29,20 +29,8 @@ int ima_initialized;
29char *ima_hash = "sha1"; 29char *ima_hash = "sha1";
30static int __init hash_setup(char *str) 30static int __init hash_setup(char *str)
31{ 31{
32 const char *op = "hash_setup"; 32 if (strncmp(str, "md5", 3) == 0)
33 const char *hash = "sha1"; 33 ima_hash = "md5";
34 int result = 0;
35 int audit_info = 0;
36
37 if (strncmp(str, "md5", 3) == 0) {
38 hash = "md5";
39 ima_hash = str;
40 } else if (strncmp(str, "sha1", 4) != 0) {
41 hash = "invalid_hash_type";
42 result = 1;
43 }
44 integrity_audit_msg(AUDIT_INTEGRITY_HASH, NULL, NULL, op, hash,
45 result, audit_info);
46 return 1; 34 return 1;
47} 35}
48__setup("ima_hash=", hash_setup); 36__setup("ima_hash=", hash_setup);
@@ -128,10 +116,6 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
128{ 116{
129 int rc = 0; 117 int rc = 0;
130 118
131 if (IS_ERR(file)) {
132 pr_info("%s dentry_open failed\n", filename);
133 return rc;
134 }
135 iint->opencount++; 119 iint->opencount++;
136 iint->readcount++; 120 iint->readcount++;
137 121
@@ -141,6 +125,15 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
141 return rc; 125 return rc;
142} 126}
143 127
128static void ima_update_counts(struct ima_iint_cache *iint, int mask)
129{
130 iint->opencount++;
131 if ((mask & MAY_WRITE) || (mask == 0))
132 iint->writecount++;
133 else if (mask & (MAY_READ | MAY_EXEC))
134 iint->readcount++;
135}
136
144/** 137/**
145 * ima_path_check - based on policy, collect/store measurement. 138 * ima_path_check - based on policy, collect/store measurement.
146 * @path: contains a pointer to the path to be measured 139 * @path: contains a pointer to the path to be measured
@@ -156,10 +149,10 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
156 * - Opening a file for read when already open for write, 149 * - Opening a file for read when already open for write,
157 * could result in a file measurement error. 150 * could result in a file measurement error.
158 * 151 *
159 * Return 0 on success, an error code on failure. 152 * Always return 0 and audit dentry_open failures.
160 * (Based on the results of appraise_measurement().) 153 * (Return code will be based upon measurement appraisal.)
161 */ 154 */
162int ima_path_check(struct path *path, int mask) 155int ima_path_check(struct path *path, int mask, int update_counts)
163{ 156{
164 struct inode *inode = path->dentry->d_inode; 157 struct inode *inode = path->dentry->d_inode;
165 struct ima_iint_cache *iint; 158 struct ima_iint_cache *iint;
@@ -173,11 +166,8 @@ int ima_path_check(struct path *path, int mask)
173 return 0; 166 return 0;
174 167
175 mutex_lock(&iint->mutex); 168 mutex_lock(&iint->mutex);
176 iint->opencount++; 169 if (update_counts)
177 if ((mask & MAY_WRITE) || (mask == 0)) 170 ima_update_counts(iint, mask);
178 iint->writecount++;
179 else if (mask & (MAY_READ | MAY_EXEC))
180 iint->readcount++;
181 171
182 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK); 172 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
183 if (rc < 0) 173 if (rc < 0)
@@ -196,7 +186,19 @@ int ima_path_check(struct path *path, int mask)
196 struct dentry *dentry = dget(path->dentry); 186 struct dentry *dentry = dget(path->dentry);
197 struct vfsmount *mnt = mntget(path->mnt); 187 struct vfsmount *mnt = mntget(path->mnt);
198 188
199 file = dentry_open(dentry, mnt, O_RDONLY, current->cred); 189 file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
190 current_cred());
191 if (IS_ERR(file)) {
192 int audit_info = 0;
193
194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
195 dentry->d_name.name,
196 "add_measurement",
197 "dentry_open failed",
198 1, audit_info);
199 file = NULL;
200 goto out;
201 }
200 rc = get_path_measurement(iint, file, dentry->d_name.name); 202 rc = get_path_measurement(iint, file, dentry->d_name.name);
201 } 203 }
202out: 204out:
@@ -206,6 +208,7 @@ out:
206 kref_put(&iint->refcount, iint_free); 208 kref_put(&iint->refcount, iint_free);
207 return 0; 209 return 0;
208} 210}
211EXPORT_SYMBOL_GPL(ima_path_check);
209 212
210static int process_measurement(struct file *file, const unsigned char *filename, 213static int process_measurement(struct file *file, const unsigned char *filename,
211 int mask, int function) 214 int mask, int function)
@@ -234,7 +237,16 @@ out:
234 return rc; 237 return rc;
235} 238}
236 239
237static void opencount_get(struct file *file) 240/*
241 * ima_opens_get - increment file counts
242 *
243 * - for IPC shm and shmat file.
244 * - for nfsd exported files.
245 *
246 * Increment the counts for these files to prevent unnecessary
247 * imbalance messages.
248 */
249void ima_counts_get(struct file *file)
238{ 250{
239 struct inode *inode = file->f_dentry->d_inode; 251 struct inode *inode = file->f_dentry->d_inode;
240 struct ima_iint_cache *iint; 252 struct ima_iint_cache *iint;
@@ -246,8 +258,14 @@ static void opencount_get(struct file *file)
246 return; 258 return;
247 mutex_lock(&iint->mutex); 259 mutex_lock(&iint->mutex);
248 iint->opencount++; 260 iint->opencount++;
261 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
262 iint->readcount++;
263
264 if (file->f_mode & FMODE_WRITE)
265 iint->writecount++;
249 mutex_unlock(&iint->mutex); 266 mutex_unlock(&iint->mutex);
250} 267}
268EXPORT_SYMBOL_GPL(ima_counts_get);
251 269
252/** 270/**
253 * ima_file_mmap - based on policy, collect/store measurement. 271 * ima_file_mmap - based on policy, collect/store measurement.
@@ -272,18 +290,6 @@ int ima_file_mmap(struct file *file, unsigned long prot)
272 return 0; 290 return 0;
273} 291}
274 292
275/*
276 * ima_shm_check - IPC shm and shmat create/fput a file
277 *
278 * Maintain the opencount for these files to prevent unnecessary
279 * imbalance messages.
280 */
281void ima_shm_check(struct file *file)
282{
283 opencount_get(file);
284 return;
285}
286
287/** 293/**
288 * ima_bprm_check - based on policy, collect/store measurement. 294 * ima_bprm_check - based on policy, collect/store measurement.
289 * @bprm: contains the linux_binprm structure 295 * @bprm: contains the linux_binprm structure