diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2014-01-06 07:28:15 -0500 |
---|---|---|
committer | Paul Moore <pmoore@redhat.com> | 2014-01-07 10:21:44 -0500 |
commit | 8ed814602876bec9bad2649ca17f34b499357a1c (patch) | |
tree | 2ee1bfcb40e7ecfa61064a2c6c254fa575af9db6 | |
parent | 465954cd649a7d8cd331695bd24a16bcb5c4c716 (diff) |
SELinux: Fix memory leak upon loading policy
Hello.
I got below leak with linux-3.10.0-54.0.1.el7.x86_64 .
[ 681.903890] kmemleak: 5538 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
Below is a patch, but I don't know whether we need special handing for undoing
ebitmap_set_bit() call.
----------
>>From fe97527a90fe95e2239dfbaa7558f0ed559c0992 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Mon, 6 Jan 2014 16:30:21 +0900
Subject: [PATCH] SELinux: Fix memory leak upon loading policy
Commit 2463c26d "SELinux: put name based create rules in a hashtable" did not
check return value from hashtab_insert() in filename_trans_read(). It leaks
memory if hashtab_insert() returns error.
unreferenced object 0xffff88005c9160d0 (size 8):
comm "systemd", pid 1, jiffies 4294688674 (age 235.265s)
hex dump (first 8 bytes):
57 0b 00 00 6b 6b 6b a5 W...kkk.
backtrace:
[<ffffffff816604ae>] kmemleak_alloc+0x4e/0xb0
[<ffffffff811cba5e>] kmem_cache_alloc_trace+0x12e/0x360
[<ffffffff812aec5d>] policydb_read+0xd1d/0xf70
[<ffffffff812b345c>] security_load_policy+0x6c/0x500
[<ffffffff812a623c>] sel_write_load+0xac/0x750
[<ffffffff811eb680>] vfs_write+0xc0/0x1f0
[<ffffffff811ec08c>] SyS_write+0x4c/0xa0
[<ffffffff81690419>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
However, we should not return EEXIST error to the caller, or the systemd will
show below message and the boot sequence freezes.
systemd[1]: Failed to load SELinux policy. Freezing.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Eric Paris <eparis@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r-- | security/selinux/ss/policydb.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index dc4011643b55..c0f498842129 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -1995,7 +1995,19 @@ static int filename_trans_read(struct policydb *p, void *fp) | |||
1995 | if (rc) | 1995 | if (rc) |
1996 | goto out; | 1996 | goto out; |
1997 | 1997 | ||
1998 | hashtab_insert(p->filename_trans, ft, otype); | 1998 | rc = hashtab_insert(p->filename_trans, ft, otype); |
1999 | if (rc) { | ||
2000 | /* | ||
2001 | * Do not return -EEXIST to the caller, or the system | ||
2002 | * will not boot. | ||
2003 | */ | ||
2004 | if (rc != -EEXIST) | ||
2005 | goto out; | ||
2006 | /* But free memory to avoid memory leak. */ | ||
2007 | kfree(ft); | ||
2008 | kfree(name); | ||
2009 | kfree(otype); | ||
2010 | } | ||
1999 | } | 2011 | } |
2000 | hash_eval(p->filename_trans, "filenametr"); | 2012 | hash_eval(p->filename_trans, "filenametr"); |
2001 | return 0; | 2013 | return 0; |