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. |
