Commit b9ccf02f authored by John Johansen's avatar John Johansen Committed by Tim Gardner

UBUNTU: SAUCE: apparmor: ensure that repacedby sharing is done correctly

don't put the reference when sharing a replacedby until after all
over references are gotten, otherwise the label might drop to a 0
refcount and start being freed, even though it should be held by
the shared replacedby.
Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
parent b3992f74
...@@ -87,6 +87,14 @@ void __aa_update_replacedby(struct aa_label *orig, struct aa_label *new) ...@@ -87,6 +87,14 @@ void __aa_update_replacedby(struct aa_label *orig, struct aa_label *new)
aa_put_label(tmp); aa_put_label(tmp);
} }
void __share_replacedby(struct aa_label *old, struct aa_label *new)
{
struct aa_replacedby *r = new->replacedby;
new->replacedby = aa_get_replacedby(old->replacedby);
__aa_update_replacedby(old, new);
aa_put_replacedby(r);
}
/* helper fn for label_for_each_confined */ /* helper fn for label_for_each_confined */
int aa_label_next_confined(struct aa_label *l, int i) int aa_label_next_confined(struct aa_label *l, int i)
{ {
...@@ -440,10 +448,9 @@ bool aa_label_replace(struct aa_label *old, struct aa_label *new) ...@@ -440,10 +448,9 @@ bool aa_label_replace(struct aa_label *old, struct aa_label *new)
if (old->hname == new->hname && labels_ns(old) == labels_ns(new)) { if (old->hname == new->hname && labels_ns(old) == labels_ns(new)) {
write_lock_irqsave(&labels_set(old)->lock, flags); write_lock_irqsave(&labels_set(old)->lock, flags);
if (old->replacedby != new->replacedby) { if (old->replacedby != new->replacedby) {
free_replacedby(new->replacedby); __share_replacedby(old, new);
new->replacedby = aa_get_replacedby(old->replacedby); } else
} __aa_update_replacedby(old, new);
__aa_update_replacedby(old, new);
res = __aa_label_replace(labels_set(old), old, new); res = __aa_label_replace(labels_set(old), old, new);
write_unlock_irqrestore(&labels_set(old)->lock, flags); write_unlock_irqrestore(&labels_set(old)->lock, flags);
} else { } else {
...@@ -704,9 +711,7 @@ static struct aa_label *__aa_label_insert(struct aa_labelset *ls, ...@@ -704,9 +711,7 @@ static struct aa_label *__aa_label_insert(struct aa_labelset *ls,
/* queued for destruction, in place replace */ /* queued for destruction, in place replace */
} else { } else {
if (this->replacedby) { if (this->replacedby) {
free_replacedby(l->replacedby); __share_replacedby(this, l);
l->replacedby = aa_get_replacedby(this->replacedby);
__aa_update_replacedby(this, l);
} else } else
this->replacedby = aa_get_replacedby(l->replacedby); this->replacedby = aa_get_replacedby(l->replacedby);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment