|
@@ -35,6 +35,55 @@ static int __init hash_setup(char *str)
|
|
|
}
|
|
|
__setup("ima_hash=", hash_setup);
|
|
|
|
|
|
+struct ima_imbalance {
|
|
|
+ struct hlist_node node;
|
|
|
+ unsigned long fsmagic;
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * ima_limit_imbalance - emit one imbalance message per filesystem type
|
|
|
+ *
|
|
|
+ * Maintain list of filesystem types that do not measure files properly.
|
|
|
+ * Return false if unknown, true if known.
|
|
|
+ */
|
|
|
+static bool ima_limit_imbalance(struct file *file)
|
|
|
+{
|
|
|
+ static DEFINE_SPINLOCK(ima_imbalance_lock);
|
|
|
+ static HLIST_HEAD(ima_imbalance_list);
|
|
|
+
|
|
|
+ struct super_block *sb = file->f_dentry->d_sb;
|
|
|
+ struct ima_imbalance *entry;
|
|
|
+ struct hlist_node *node;
|
|
|
+ bool found = false;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ hlist_for_each_entry_rcu(entry, node, &ima_imbalance_list, node) {
|
|
|
+ if (entry->fsmagic == sb->s_magic) {
|
|
|
+ found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rcu_read_unlock();
|
|
|
+ if (found)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ entry = kmalloc(sizeof(*entry), GFP_NOFS);
|
|
|
+ if (!entry)
|
|
|
+ goto out;
|
|
|
+ entry->fsmagic = sb->s_magic;
|
|
|
+ spin_lock(&ima_imbalance_lock);
|
|
|
+ /*
|
|
|
+ * we could have raced and something else might have added this fs
|
|
|
+ * to the list, but we don't really care
|
|
|
+ */
|
|
|
+ hlist_add_head_rcu(&entry->node, &ima_imbalance_list);
|
|
|
+ spin_unlock(&ima_imbalance_lock);
|
|
|
+ printk(KERN_INFO "IMA: unmeasured files on fsmagic: %lX\n",
|
|
|
+ entry->fsmagic);
|
|
|
+out:
|
|
|
+ return found;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Update the counts given an fmode_t
|
|
|
*/
|
|
@@ -69,15 +118,10 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ((iint->opencount < 0) ||
|
|
|
- (iint->readcount < 0) ||
|
|
|
- (iint->writecount < 0)) {
|
|
|
- static int dumped;
|
|
|
-
|
|
|
- if (dumped)
|
|
|
- return;
|
|
|
- dumped = 1;
|
|
|
-
|
|
|
+ if (((iint->opencount < 0) ||
|
|
|
+ (iint->readcount < 0) ||
|
|
|
+ (iint->writecount < 0)) &&
|
|
|
+ !ima_limit_imbalance(file)) {
|
|
|
printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
|
|
|
__FUNCTION__, iint->readcount, iint->writecount,
|
|
|
iint->opencount);
|