diff mbox series

[1/6] selinux: do not leave dangling pointer behind

Message ID 20230420150503.22227-1-cgzones@googlemail.com (mailing list archive)
State Accepted
Delegated to: Paul Moore
Headers show
Series [1/6] selinux: do not leave dangling pointer behind | expand

Commit Message

Christian Göttsche April 20, 2023, 3:04 p.m. UTC
In case mls_context_cpy() fails due to OOM set the free'd pointer in
context_cpy() to NULL to avoid it potentially being dereferenced or
free'd again in future.  Freeing a NULL pointer is well-defined and a
hard NULL dereference crash is at least not exploitable and should give
a workable stack trace.

Fixes: 12b29f34558b ("selinux: support deferred mapping of contexts")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 security/selinux/ss/context.h | 1 +
 1 file changed, 1 insertion(+)

Comments

Paul Moore May 8, 2023, 8:42 p.m. UTC | #1
On Thu, Apr 20, 2023 at 11:05 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> In case mls_context_cpy() fails due to OOM set the free'd pointer in
> context_cpy() to NULL to avoid it potentially being dereferenced or
> free'd again in future.  Freeing a NULL pointer is well-defined and a
> hard NULL dereference crash is at least not exploitable and should give
> a workable stack trace.
>
> Fixes: 12b29f34558b ("selinux: support deferred mapping of contexts")
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  security/selinux/ss/context.h | 1 +
>  1 file changed, 1 insertion(+)

Merged into selinux/next.

Did you actually run into a problem where the system
crashed/panic'd/etc. due to this?  I'll leave the fixes tag on this
since it is pretty minor, but generally I think it is best to reserve
the fixes tag for problems that can be triggered as a fixes tag
generally results in a stable backport, regardless of it is marked for
stable or not.
Christian Göttsche May 9, 2023, 2:44 p.m. UTC | #2
On Mon, 8 May 2023 at 22:42, Paul Moore <paul@paul-moore.com> wrote:
>
> On Thu, Apr 20, 2023 at 11:05 AM Christian Göttsche
> <cgzones@googlemail.com> wrote:
> >
> > In case mls_context_cpy() fails due to OOM set the free'd pointer in
> > context_cpy() to NULL to avoid it potentially being dereferenced or
> > free'd again in future.  Freeing a NULL pointer is well-defined and a
> > hard NULL dereference crash is at least not exploitable and should give
> > a workable stack trace.
> >
> > Fixes: 12b29f34558b ("selinux: support deferred mapping of contexts")
> > Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> > ---
> >  security/selinux/ss/context.h | 1 +
> >  1 file changed, 1 insertion(+)
>
> Merged into selinux/next.
>
> Did you actually run into a problem where the system
> crashed/panic'd/etc. due to this?

No, no actual crash, just came to mind while looking over the code.

My understanding of the sidtab code is only superficial, so maybe
Stephen can correct my analysis:

There are two callers of context_cpy(): sidtab_set_initial() and
sidtab_context_to_sid():

sidtab_set_initial() is only called in policydb_load_isids(). If
context_cpy() fails on `&isid->entry.context` `isid->set` is not set
to 1 and thus the cleanup via sidtab_destroy() called in
policydb_load_isids() causes no use-after-free, since sidtab_destroy()
calls sidtab_destroy_entry() only on `if (s->isids[i].set)`.

In sidtab_context_to_sid(), if context_cpy() failed, the sidtab count
remains unchanged, since `smp_store_release(&s->count, count + 1);` is
skipped. So simple lookups via sidtab_lookup() should not access the
zombie context since the count is checked. But I think
sidtab_destroy(), e.g via a policy load on the old policy,
unconditionally calls, via sidtab_destroy_tree(),
sidtab_destroy_entry() on all fixed sized array elements, which leads
to a call of context_destroy() leading to a double-free.


Even if this analysis is wrong the change seems to me a good
defence-in-depth measure, e.g. for future refactorings.
Also the cost of a pointer assigmnment in an OOM error branch seems negligible.

I'll probably send a patch to set `dst->len` to 0 as well, since both
members are coupled.


>  I'll leave the fixes tag on this
> since it is pretty minor, but generally I think it is best to reserve
> the fixes tag for problems that can be triggered as a fixes tag
> generally results in a stable backport, regardless of it is marked for
> stable or not.
>
> --
> paul-moore.com
diff mbox series

Patch

diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index eda32c3d4c0a..44179977f434 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -167,6 +167,7 @@  static inline int context_cpy(struct context *dst, const struct context *src)
 	rc = mls_context_cpy(dst, src);
 	if (rc) {
 		kfree(dst->str);
+		dst->str = NULL;
 		return rc;
 	}
 	return 0;