diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2009-06-26 14:05:27 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-06-28 18:59:10 -0400 |
commit | 94e5d714f604d4cb4cb13163f01ede278e69258b (patch) | |
tree | 1f7f50f5eddf74e6930eaf0384538549f263b8fe | |
parent | 79b854c549c62c54fa27f87e04465c01db889f8d (diff) |
integrity: add ima_counts_put (updated)
This patch fixes an imbalance message as reported by J.R. Okajima.
The IMA file counters are incremented in ima_path_check. If the
actual open fails, such as ETXTBSY, decrement the counters to
prevent unnecessary imbalance messages.
Reported-by: J.R. Okajima <hooanon05@yahoo.co.jp>
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | fs/namei.c | 7 | ||||
-rw-r--r-- | include/linux/ima.h | 6 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 29 |
3 files changed, 41 insertions, 1 deletions
diff --git a/fs/namei.c b/fs/namei.c index 5b961eb71cbf..f3c5b278895a 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1761,6 +1761,10 @@ do_last: | |||
1761 | goto exit; | 1761 | goto exit; |
1762 | } | 1762 | } |
1763 | filp = nameidata_to_filp(&nd, open_flag); | 1763 | filp = nameidata_to_filp(&nd, open_flag); |
1764 | if (IS_ERR(filp)) | ||
1765 | ima_counts_put(&nd.path, | ||
1766 | acc_mode & (MAY_READ | MAY_WRITE | | ||
1767 | MAY_EXEC)); | ||
1764 | mnt_drop_write(nd.path.mnt); | 1768 | mnt_drop_write(nd.path.mnt); |
1765 | if (nd.root.mnt) | 1769 | if (nd.root.mnt) |
1766 | path_put(&nd.root); | 1770 | path_put(&nd.root); |
@@ -1817,6 +1821,9 @@ ok: | |||
1817 | goto exit; | 1821 | goto exit; |
1818 | } | 1822 | } |
1819 | filp = nameidata_to_filp(&nd, open_flag); | 1823 | filp = nameidata_to_filp(&nd, open_flag); |
1824 | if (IS_ERR(filp)) | ||
1825 | ima_counts_put(&nd.path, | ||
1826 | acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); | ||
1820 | /* | 1827 | /* |
1821 | * It is now safe to drop the mnt write | 1828 | * It is now safe to drop the mnt write |
1822 | * because the filp has had a write taken | 1829 | * because the filp has had a write taken |
diff --git a/include/linux/ima.h b/include/linux/ima.h index b1b827d091a9..0e3f2a4c25f6 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h | |||
@@ -24,6 +24,7 @@ extern int ima_path_check(struct path *path, int mask, int update_counts); | |||
24 | extern void ima_file_free(struct file *file); | 24 | extern void ima_file_free(struct file *file); |
25 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 25 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
26 | extern void ima_counts_get(struct file *file); | 26 | extern void ima_counts_get(struct file *file); |
27 | extern void ima_counts_put(struct path *path, int mask); | ||
27 | 28 | ||
28 | #else | 29 | #else |
29 | static inline int ima_bprm_check(struct linux_binprm *bprm) | 30 | static inline int ima_bprm_check(struct linux_binprm *bprm) |
@@ -60,5 +61,10 @@ static inline void ima_counts_get(struct file *file) | |||
60 | { | 61 | { |
61 | return; | 62 | return; |
62 | } | 63 | } |
64 | |||
65 | static inline void ima_counts_put(struct path *path, int mask) | ||
66 | { | ||
67 | return; | ||
68 | } | ||
63 | #endif /* CONFIG_IMA_H */ | 69 | #endif /* CONFIG_IMA_H */ |
64 | #endif /* _LINUX_IMA_H */ | 70 | #endif /* _LINUX_IMA_H */ |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6f611874d10e..101c512564ec 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -238,7 +238,34 @@ out: | |||
238 | } | 238 | } |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * ima_opens_get - increment file counts | 241 | * ima_counts_put - decrement file counts |
242 | * | ||
243 | * File counts are incremented in ima_path_check. On file open | ||
244 | * error, such as ETXTBSY, decrement the counts to prevent | ||
245 | * unnecessary imbalance messages. | ||
246 | */ | ||
247 | void ima_counts_put(struct path *path, int mask) | ||
248 | { | ||
249 | struct inode *inode = path->dentry->d_inode; | ||
250 | struct ima_iint_cache *iint; | ||
251 | |||
252 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | ||
253 | return; | ||
254 | iint = ima_iint_find_insert_get(inode); | ||
255 | if (!iint) | ||
256 | return; | ||
257 | |||
258 | mutex_lock(&iint->mutex); | ||
259 | iint->opencount--; | ||
260 | if ((mask & MAY_WRITE) || (mask == 0)) | ||
261 | iint->writecount--; | ||
262 | else if (mask & (MAY_READ | MAY_EXEC)) | ||
263 | iint->readcount--; | ||
264 | mutex_unlock(&iint->mutex); | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * ima_counts_get - increment file counts | ||
242 | * | 269 | * |
243 | * - for IPC shm and shmat file. | 270 | * - for IPC shm and shmat file. |
244 | * - for nfsd exported files. | 271 | * - for nfsd exported files. |