aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c4
-rw-r--r--fs/nfsd/vfs.c3
-rw-r--r--include/linux/ima.h12
-rw-r--r--security/integrity/ima/ima_main.c52
4 files changed, 9 insertions, 62 deletions
diff --git a/fs/namei.c b/fs/namei.c
index c530e5d32f12..a765e7a741f4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1686,7 +1686,7 @@ do_last:
1686 path_put(&nd.root); 1686 path_put(&nd.root);
1687 if (!IS_ERR(filp)) { 1687 if (!IS_ERR(filp)) {
1688 error = ima_path_check(&filp->f_path, filp->f_mode & 1688 error = ima_path_check(&filp->f_path, filp->f_mode &
1689 (MAY_READ | MAY_WRITE | MAY_EXEC), 0); 1689 (MAY_READ | MAY_WRITE | MAY_EXEC));
1690 if (error) { 1690 if (error) {
1691 fput(filp); 1691 fput(filp);
1692 filp = ERR_PTR(error); 1692 filp = ERR_PTR(error);
@@ -1747,7 +1747,7 @@ ok:
1747 filp = nameidata_to_filp(&nd, open_flag); 1747 filp = nameidata_to_filp(&nd, open_flag);
1748 if (!IS_ERR(filp)) { 1748 if (!IS_ERR(filp)) {
1749 error = ima_path_check(&filp->f_path, filp->f_mode & 1749 error = ima_path_check(&filp->f_path, filp->f_mode &
1750 (MAY_READ | MAY_WRITE | MAY_EXEC), 0); 1750 (MAY_READ | MAY_WRITE | MAY_EXEC));
1751 if (error) { 1751 if (error) {
1752 fput(filp); 1752 fput(filp);
1753 filp = ERR_PTR(error); 1753 filp = ERR_PTR(error);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c9942b39654e..936f08400db6 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -2122,8 +2122,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
2122 */ 2122 */
2123 path.mnt = exp->ex_path.mnt; 2123 path.mnt = exp->ex_path.mnt;
2124 path.dentry = dentry; 2124 path.dentry = dentry;
2125 err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC), 2125 err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC));
2126 IMA_COUNT_LEAVE);
2127nfsd_out: 2126nfsd_out:
2128 return err? nfserrno(err) : 0; 2127 return err? nfserrno(err) : 0;
2129} 2128}
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 0e3f2a4c25f6..99dc6d5cf7e5 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -13,18 +13,14 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14struct linux_binprm; 14struct linux_binprm;
15 15
16#define IMA_COUNT_UPDATE 1
17#define IMA_COUNT_LEAVE 0
18
19#ifdef CONFIG_IMA 16#ifdef CONFIG_IMA
20extern int ima_bprm_check(struct linux_binprm *bprm); 17extern int ima_bprm_check(struct linux_binprm *bprm);
21extern int ima_inode_alloc(struct inode *inode); 18extern int ima_inode_alloc(struct inode *inode);
22extern void ima_inode_free(struct inode *inode); 19extern void ima_inode_free(struct inode *inode);
23extern int ima_path_check(struct path *path, int mask, int update_counts); 20extern int ima_path_check(struct path *path, int mask);
24extern void ima_file_free(struct file *file); 21extern void ima_file_free(struct file *file);
25extern int ima_file_mmap(struct file *file, unsigned long prot); 22extern int ima_file_mmap(struct file *file, unsigned long prot);
26extern void ima_counts_get(struct file *file); 23extern void ima_counts_get(struct file *file);
27extern void ima_counts_put(struct path *path, int mask);
28 24
29#else 25#else
30static inline int ima_bprm_check(struct linux_binprm *bprm) 26static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -42,7 +38,7 @@ static inline void ima_inode_free(struct inode *inode)
42 return; 38 return;
43} 39}
44 40
45static inline int ima_path_check(struct path *path, int mask, int update_counts) 41static inline int ima_path_check(struct path *path, int mask)
46{ 42{
47 return 0; 43 return 0;
48} 44}
@@ -62,9 +58,5 @@ static inline void ima_counts_get(struct file *file)
62 return; 58 return;
63} 59}
64 60
65static inline void ima_counts_put(struct path *path, int mask)
66{
67 return;
68}
69#endif /* CONFIG_IMA_H */ 61#endif /* CONFIG_IMA_H */
70#endif /* _LINUX_IMA_H */ 62#endif /* _LINUX_IMA_H */
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index e041233b4d2a..16dc57d247d0 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -50,19 +50,12 @@ static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
50} 50}
51 51
52/* 52/*
53 * Update the counts given open flags instead of fmode
54 */
55static void ima_inc_counts_flags(struct ima_iint_cache *iint, int flags)
56{
57 ima_inc_counts(iint, (__force fmode_t)((flags+1) & O_ACCMODE));
58}
59
60/*
61 * Decrement ima counts 53 * Decrement ima counts
62 */ 54 */
63static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, 55static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
64 fmode_t mode) 56 struct file *file)
65{ 57{
58 mode_t mode = file->f_mode;
66 BUG_ON(!mutex_is_locked(&iint->mutex)); 59 BUG_ON(!mutex_is_locked(&iint->mutex));
67 60
68 iint->opencount--; 61 iint->opencount--;
@@ -92,12 +85,6 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
92 } 85 }
93} 86}
94 87
95static void ima_dec_counts_flags(struct ima_iint_cache *iint,
96 struct inode *inode, int flags)
97{
98 ima_dec_counts(iint, inode, (__force fmode_t)((flags+1) & O_ACCMODE));
99}
100
101/** 88/**
102 * ima_file_free - called on __fput() 89 * ima_file_free - called on __fput()
103 * @file: pointer to file structure being freed 90 * @file: pointer to file structure being freed
@@ -117,7 +104,7 @@ void ima_file_free(struct file *file)
117 return; 104 return;
118 105
119 mutex_lock(&iint->mutex); 106 mutex_lock(&iint->mutex);
120 ima_dec_counts(iint, inode, file->f_mode); 107 ima_dec_counts(iint, inode, file);
121 mutex_unlock(&iint->mutex); 108 mutex_unlock(&iint->mutex);
122 kref_put(&iint->refcount, iint_free); 109 kref_put(&iint->refcount, iint_free);
123} 110}
@@ -183,7 +170,7 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
183 * Always return 0 and audit dentry_open failures. 170 * Always return 0 and audit dentry_open failures.
184 * (Return code will be based upon measurement appraisal.) 171 * (Return code will be based upon measurement appraisal.)
185 */ 172 */
186int ima_path_check(struct path *path, int mask, int update_counts) 173int ima_path_check(struct path *path, int mask)
187{ 174{
188 struct inode *inode = path->dentry->d_inode; 175 struct inode *inode = path->dentry->d_inode;
189 struct ima_iint_cache *iint; 176 struct ima_iint_cache *iint;
@@ -197,8 +184,6 @@ int ima_path_check(struct path *path, int mask, int update_counts)
197 return 0; 184 return 0;
198 185
199 mutex_lock(&iint->mutex); 186 mutex_lock(&iint->mutex);
200 if (update_counts)
201 ima_inc_counts_flags(iint, mask);
202 187
203 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK); 188 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
204 if (rc < 0) 189 if (rc < 0)
@@ -269,35 +254,6 @@ out:
269} 254}
270 255
271/* 256/*
272 * ima_counts_put - decrement file counts
273 *
274 * File counts are incremented in ima_path_check. On file open
275 * error, such as ETXTBSY, decrement the counts to prevent
276 * unnecessary imbalance messages.
277 */
278void ima_counts_put(struct path *path, int mask)
279{
280 struct inode *inode = path->dentry->d_inode;
281 struct ima_iint_cache *iint;
282
283 /* The inode may already have been freed, freeing the iint
284 * with it. Verify the inode is not NULL before dereferencing
285 * it.
286 */
287 if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
288 return;
289 iint = ima_iint_find_get(inode);
290 if (!iint)
291 return;
292
293 mutex_lock(&iint->mutex);
294 ima_dec_counts_flags(iint, inode, mask);
295 mutex_unlock(&iint->mutex);
296
297 kref_put(&iint->refcount, iint_free);
298}
299
300/*
301 * ima_counts_get - increment file counts 257 * ima_counts_get - increment file counts
302 * 258 *
303 * - for IPC shm and shmat file. 259 * - for IPC shm and shmat file.