diff options
| -rw-r--r-- | fs/namei.c | 7 | ||||
| -rw-r--r-- | include/linux/ima.h | 6 | ||||
| -rw-r--r-- | ipc/mqueue.c | 2 | ||||
| -rw-r--r-- | security/integrity/ima/ima_main.c | 29 | ||||
| -rw-r--r-- | security/integrity/ima/ima_queue.c | 3 |
5 files changed, 45 insertions, 2 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/ipc/mqueue.c b/ipc/mqueue.c index e35ba2c3a8d7..c5e68adc6732 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/nsproxy.h> | 32 | #include <linux/nsproxy.h> |
| 33 | #include <linux/pid.h> | 33 | #include <linux/pid.h> |
| 34 | #include <linux/ipc_namespace.h> | 34 | #include <linux/ipc_namespace.h> |
| 35 | #include <linux/ima.h> | ||
| 35 | 36 | ||
| 36 | #include <net/sock.h> | 37 | #include <net/sock.h> |
| 37 | #include "util.h" | 38 | #include "util.h" |
| @@ -733,6 +734,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, | |||
| 733 | error = PTR_ERR(filp); | 734 | error = PTR_ERR(filp); |
| 734 | goto out_putfd; | 735 | goto out_putfd; |
| 735 | } | 736 | } |
| 737 | ima_counts_get(filp); | ||
| 736 | 738 | ||
| 737 | fd_install(fd, filp); | 739 | fd_install(fd, filp); |
| 738 | goto out_upsem; | 740 | goto out_upsem; |
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. |
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 7ec94314ac0c..a0880e9c8e05 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c | |||
| @@ -134,7 +134,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, | |||
| 134 | } | 134 | } |
| 135 | out: | 135 | out: |
| 136 | mutex_unlock(&ima_extend_list_mutex); | 136 | mutex_unlock(&ima_extend_list_mutex); |
| 137 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, entry->template_name, | 137 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, |
| 138 | entry->template.file_name, | ||
| 138 | op, audit_cause, result, audit_info); | 139 | op, audit_cause, result, audit_info); |
| 139 | return result; | 140 | return result; |
| 140 | } | 141 | } |
