diff options
-rw-r--r-- | fs/namei.c | 4 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 3 | ||||
-rw-r--r-- | include/linux/ima.h | 12 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 52 |
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); | ||
2127 | nfsd_out: | 2126 | nfsd_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> |
14 | struct linux_binprm; | 14 | struct 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 |
20 | extern int ima_bprm_check(struct linux_binprm *bprm); | 17 | extern int ima_bprm_check(struct linux_binprm *bprm); |
21 | extern int ima_inode_alloc(struct inode *inode); | 18 | extern int ima_inode_alloc(struct inode *inode); |
22 | extern void ima_inode_free(struct inode *inode); | 19 | extern void ima_inode_free(struct inode *inode); |
23 | extern int ima_path_check(struct path *path, int mask, int update_counts); | 20 | extern int ima_path_check(struct path *path, int mask); |
24 | extern void ima_file_free(struct file *file); | 21 | extern void ima_file_free(struct file *file); |
25 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 22 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
26 | extern void ima_counts_get(struct file *file); | 23 | extern void ima_counts_get(struct file *file); |
27 | extern void ima_counts_put(struct path *path, int mask); | ||
28 | 24 | ||
29 | #else | 25 | #else |
30 | static inline int ima_bprm_check(struct linux_binprm *bprm) | 26 | static 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 | ||
45 | static inline int ima_path_check(struct path *path, int mask, int update_counts) | 41 | static 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 | ||
65 | static 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 | */ | ||
55 | static 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 | */ |
63 | static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, | 55 | static 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 | ||
95 | static 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 | */ |
186 | int ima_path_check(struct path *path, int mask, int update_counts) | 173 | int 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 | */ | ||
278 | void 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. |