diff options
| -rw-r--r-- | security/integrity/ima/ima_iint.c | 4 | ||||
| -rw-r--r-- | security/integrity/ima/ima_main.c | 104 |
2 files changed, 4 insertions, 104 deletions
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index 68efe3b8d99..4ae73040ab7 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
| @@ -137,10 +137,6 @@ void ima_inode_free(struct inode *inode) | |||
| 137 | { | 137 | { |
| 138 | struct ima_iint_cache *iint; | 138 | struct ima_iint_cache *iint; |
| 139 | 139 | ||
| 140 | if (atomic_read(&inode->i_readcount)) | ||
| 141 | printk(KERN_INFO "%s: readcount: %u\n", __func__, | ||
| 142 | atomic_read(&inode->i_readcount)); | ||
| 143 | |||
| 144 | if (!IS_IMA(inode)) | 140 | if (!IS_IMA(inode)) |
| 145 | return; | 141 | return; |
| 146 | 142 | ||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 69b4856af4d..2df90215119 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
| @@ -36,55 +36,6 @@ static int __init hash_setup(char *str) | |||
| 36 | } | 36 | } |
| 37 | __setup("ima_hash=", hash_setup); | 37 | __setup("ima_hash=", hash_setup); |
| 38 | 38 | ||
| 39 | struct ima_imbalance { | ||
| 40 | struct hlist_node node; | ||
| 41 | unsigned long fsmagic; | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * ima_limit_imbalance - emit one imbalance message per filesystem type | ||
| 46 | * | ||
| 47 | * Maintain list of filesystem types that do not measure files properly. | ||
| 48 | * Return false if unknown, true if known. | ||
| 49 | */ | ||
| 50 | static bool ima_limit_imbalance(struct file *file) | ||
| 51 | { | ||
| 52 | static DEFINE_SPINLOCK(ima_imbalance_lock); | ||
| 53 | static HLIST_HEAD(ima_imbalance_list); | ||
| 54 | |||
| 55 | struct super_block *sb = file->f_dentry->d_sb; | ||
| 56 | struct ima_imbalance *entry; | ||
| 57 | struct hlist_node *node; | ||
| 58 | bool found = false; | ||
| 59 | |||
| 60 | rcu_read_lock(); | ||
| 61 | hlist_for_each_entry_rcu(entry, node, &ima_imbalance_list, node) { | ||
| 62 | if (entry->fsmagic == sb->s_magic) { | ||
| 63 | found = true; | ||
| 64 | break; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | rcu_read_unlock(); | ||
| 68 | if (found) | ||
| 69 | goto out; | ||
| 70 | |||
| 71 | entry = kmalloc(sizeof(*entry), GFP_NOFS); | ||
| 72 | if (!entry) | ||
| 73 | goto out; | ||
| 74 | entry->fsmagic = sb->s_magic; | ||
| 75 | spin_lock(&ima_imbalance_lock); | ||
| 76 | /* | ||
| 77 | * we could have raced and something else might have added this fs | ||
| 78 | * to the list, but we don't really care | ||
| 79 | */ | ||
| 80 | hlist_add_head_rcu(&entry->node, &ima_imbalance_list); | ||
| 81 | spin_unlock(&ima_imbalance_lock); | ||
| 82 | printk(KERN_INFO "IMA: unmeasured files on fsmagic: %lX\n", | ||
| 83 | entry->fsmagic); | ||
| 84 | out: | ||
| 85 | return found; | ||
| 86 | } | ||
| 87 | |||
| 88 | /* | 39 | /* |
| 89 | * ima_rdwr_violation_check | 40 | * ima_rdwr_violation_check |
| 90 | * | 41 | * |
| @@ -131,65 +82,20 @@ out: | |||
| 131 | "open_writers"); | 82 | "open_writers"); |
| 132 | } | 83 | } |
| 133 | 84 | ||
| 134 | /* | ||
| 135 | * Decrement ima counts | ||
| 136 | */ | ||
| 137 | static void ima_dec_counts(struct inode *inode, struct file *file) | ||
| 138 | { | ||
| 139 | mode_t mode = file->f_mode; | ||
| 140 | |||
| 141 | assert_spin_locked(&inode->i_lock); | ||
| 142 | |||
| 143 | if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { | ||
| 144 | if (unlikely(atomic_read(&inode->i_readcount) == 0)) { | ||
| 145 | if (!ima_limit_imbalance(file)) { | ||
| 146 | printk(KERN_INFO "%s: open/free imbalance (r:%u)\n", | ||
| 147 | __func__, | ||
| 148 | atomic_read(&inode->i_readcount)); | ||
| 149 | dump_stack(); | ||
| 150 | } | ||
| 151 | return; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | static void ima_check_last_writer(struct ima_iint_cache *iint, | 85 | static void ima_check_last_writer(struct ima_iint_cache *iint, |
| 157 | struct inode *inode, | 86 | struct inode *inode, |
| 158 | struct file *file) | 87 | struct file *file) |
| 159 | { | 88 | { |
| 160 | mode_t mode = file->f_mode; | 89 | mode_t mode = file->f_mode; |
| 161 | 90 | ||
| 162 | BUG_ON(!mutex_is_locked(&iint->mutex)); | 91 | mutex_lock(&iint->mutex); |
| 163 | assert_spin_locked(&inode->i_lock); | ||
| 164 | |||
| 165 | if (mode & FMODE_WRITE && | 92 | if (mode & FMODE_WRITE && |
| 166 | atomic_read(&inode->i_writecount) == 1 && | 93 | atomic_read(&inode->i_writecount) == 1 && |
| 167 | iint->version != inode->i_version) | 94 | iint->version != inode->i_version) |
| 168 | iint->flags &= ~IMA_MEASURED; | 95 | iint->flags &= ~IMA_MEASURED; |
| 169 | } | ||
| 170 | |||
| 171 | static void ima_file_free_iint(struct ima_iint_cache *iint, struct inode *inode, | ||
| 172 | struct file *file) | ||
| 173 | { | ||
| 174 | mutex_lock(&iint->mutex); | ||
| 175 | spin_lock(&inode->i_lock); | ||
| 176 | |||
| 177 | ima_dec_counts(inode, file); | ||
| 178 | ima_check_last_writer(iint, inode, file); | ||
| 179 | |||
| 180 | spin_unlock(&inode->i_lock); | ||
| 181 | mutex_unlock(&iint->mutex); | 96 | mutex_unlock(&iint->mutex); |
| 182 | } | 97 | } |
| 183 | 98 | ||
| 184 | static void ima_file_free_noiint(struct inode *inode, struct file *file) | ||
| 185 | { | ||
| 186 | spin_lock(&inode->i_lock); | ||
| 187 | |||
| 188 | ima_dec_counts(inode, file); | ||
| 189 | |||
| 190 | spin_unlock(&inode->i_lock); | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | 99 | /** |
| 194 | * ima_file_free - called on __fput() | 100 | * ima_file_free - called on __fput() |
| 195 | * @file: pointer to file structure being freed | 101 | * @file: pointer to file structure being freed |
| @@ -205,12 +111,10 @@ void ima_file_free(struct file *file) | |||
| 205 | return; | 111 | return; |
| 206 | 112 | ||
| 207 | iint = ima_iint_find(inode); | 113 | iint = ima_iint_find(inode); |
| 114 | if (!iint) | ||
| 115 | return; | ||
| 208 | 116 | ||
| 209 | if (iint) | 117 | ima_check_last_writer(iint, inode, file); |
| 210 | ima_file_free_iint(iint, inode, file); | ||
| 211 | else | ||
| 212 | ima_file_free_noiint(inode, file); | ||
| 213 | |||
| 214 | } | 118 | } |
| 215 | 119 | ||
| 216 | static int process_measurement(struct file *file, const unsigned char *filename, | 120 | static int process_measurement(struct file *file, const unsigned char *filename, |
