提交 ba729f30 编写于 作者: K Krzysztof Struczynski 提交者: Zheng Zengkai

ima: Add per namespace view of the measurement list

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1
CVE: NA

--------------------------------

Modify ima securityfs interface, so that only measurement list entries
that belong to the given ima namespace are visible/counted. The initial
ima namespace is an exception, its processes have access to all
measurement list entries.
Signed-off-by: NKrzysztof Struczynski <krzysztof.struczynski@huawei.com>
Reviewed-by: NZhang Tianxing <zhangtianxing3@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 782baa66
......@@ -233,6 +233,7 @@ struct ima_namespace {
struct ima_policy_data *policy_data;
struct integrity_iint_tree *iint_tree;
struct list_head ns_measurements;
atomic_long_t ml_len; /* number of stored measurements in the list */
} __randomize_layout;
extern struct ima_namespace init_ima_ns;
......
......@@ -190,12 +190,14 @@ extern spinlock_t ima_queue_lock;
extern spinlock_t ima_htable_lock;
struct ima_h_table {
atomic_long_t len; /* number of stored measurements in the list */
atomic_long_t len; /* number of stored measurements in the list */
atomic_long_t violations;
struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
};
extern struct ima_h_table ima_htable;
extern atomic_long_t ima_ml_len;
static inline unsigned int ima_hash_key(u8 *digest)
{
/* there is no point in taking a hash of part of a digest */
......
......@@ -58,11 +58,12 @@ static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
atomic_long_t *val = NULL;
char tmpbuf[32]; /* greater than largest 'long' string value */
ssize_t len;
struct ima_namespace *ima_ns = get_current_ns();
if (filp->f_path.dentry == violations)
val = &ima_htable.violations;
else if (filp->f_path.dentry == runtime_measurements_count)
val = &ima_htable.len;
val = (ima_ns == &init_ima_ns) ? &ima_ml_len : &ima_ns->ml_len;
#ifdef CONFIG_IMA_DIGEST_LIST
else if (filp->f_path.dentry == digests_count)
val = &ima_digests_htable.len;
......@@ -82,32 +83,57 @@ static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
{
loff_t l = *pos;
struct ima_queue_entry *qe;
struct ima_namespace *ima_ns = get_current_ns();
/* we need a lock since pos could point beyond last element */
rcu_read_lock();
list_for_each_entry_rcu(qe, &ima_measurements, later) {
if (!l--) {
rcu_read_unlock();
return qe;
if (ima_ns == &init_ima_ns) {
/* we need a lock since pos could point beyond last element */
rcu_read_lock();
list_for_each_entry_rcu(qe, &ima_measurements, later) {
if (!l--) {
rcu_read_unlock();
return qe;
}
}
rcu_read_unlock();
} else {
rcu_read_lock();
list_for_each_entry_rcu(qe, &ima_ns->ns_measurements, ns_later) {
if (!l--) {
rcu_read_unlock();
return qe;
}
}
rcu_read_unlock();
}
rcu_read_unlock();
return NULL;
}
static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
{
struct ima_queue_entry *qe = v;
struct ima_namespace *ima_ns = get_current_ns();
/* lock protects when reading beyond last element
* against concurrent list-extension
*/
rcu_read_lock();
qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
rcu_read_unlock();
(*pos)++;
if (ima_ns == &init_ima_ns) {
rcu_read_lock();
qe = list_entry_rcu(qe->later.next, struct ima_queue_entry,
later);
rcu_read_unlock();
(*pos)++;
return (&qe->later == &ima_measurements) ? NULL : qe;
} else {
rcu_read_lock();
qe = list_entry_rcu(qe->ns_later.next, struct ima_queue_entry,
ns_later);
rcu_read_unlock();
(*pos)++;
return (&qe->later == &ima_measurements) ? NULL : qe;
return (&qe->ns_later == &ima_ns->ns_measurements) ? NULL : qe;
}
}
static void ima_measurements_stop(struct seq_file *m, void *v)
......
......@@ -36,6 +36,7 @@ struct ima_namespace init_ima_ns = {
.policy_data = &init_policy_data,
.iint_tree = &init_iint_tree,
.ns_measurements = LIST_HEAD_INIT(init_ima_ns.ns_measurements),
.ml_len = ATOMIC_LONG_INIT(0),
};
EXPORT_SYMBOL(init_ima_ns);
......
......@@ -127,6 +127,7 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns,
ns->user_ns = get_user_ns(user_ns);
ns->ucounts = ucounts;
ns->frozen = false;
atomic_long_set(&ns->ml_len, 0);
rwlock_init(&ns->iint_tree->lock);
ns->iint_tree->root = RB_ROOT;
......
......@@ -25,6 +25,7 @@
/* pre-allocated array of tpm_digest structures to extend a PCR */
static struct tpm_digest *digests;
atomic_long_t ima_ml_len = ATOMIC_LONG_INIT(0); /* number of stored measurements in the list */
LIST_HEAD(ima_measurements); /* list of all measurements */
#ifdef CONFIG_IMA_KEXEC
static unsigned long binary_runtime_size;
......@@ -113,6 +114,8 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
list_add_tail_rcu(&qe->ns_later, &ima_ns->ns_measurements);
atomic_long_inc(&ima_htable.len);
atomic_long_inc(&ima_ml_len);
atomic_long_inc(&ima_ns->ml_len);
if (update_htable) {
key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
spin_lock(&ima_htable_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册