This patch cleans up a couple of crashes caused by libselinux

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

If you fail to load_policy in the init or SELinux is disabled, you need
to free the selinux_mnt variable and clear the memory.

systemd was calling load_polcy on a DISABLED system then later on it
would call is_selinux_enabled() and get incorrect response, since
selinux_mnt still had valid data.

The second bug in libselinux, resolves around calling the
selinux_key_delete(destructor_key) if the selinux_key_create call had
never been called.  This was causing data to be freed in other
applications that loaded an unloaded the libselinux library but never
setup setrans or matchpathcon.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk2c0/UACgkQrlYvE4MpobMP1QCfXAFD3pfWFLd1lylU/vjsZmpM
mcUAnA2l3/GKGC3hT8XB9E+2pTfpy+uj
=jpyr
-----END PGP SIGNATURE-----

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
This commit is contained in:
Daniel J Walsh 2011-04-06 16:58:29 -04:00 committed by Steve Lawrence
parent 5c6729b4d2
commit 1629d2f89a
6 changed files with 20 additions and 9 deletions

View File

@ -514,6 +514,9 @@ extern int selinux_check_securetty_context(const security_context_t tty_context)
which performs the initial mount of selinuxfs. */
void set_selinuxmnt(char *mnt);
/* clear selinuxmnt variable and free allocated memory */
void fini_selinuxmnt(void);
/* Execute a helper for rpm in an appropriate security context. */
extern int rpm_execcon(unsigned int verified,
const char *filename,

View File

@ -96,12 +96,14 @@ static void init_selinuxmnt(void)
return;
}
static void fini_selinuxmnt(void)
void fini_selinuxmnt(void)
{
free(selinux_mnt);
selinux_mnt = NULL;
}
hidden_def(fini_selinuxmnt)
void set_selinuxmnt(char *mnt)
{
selinux_mnt = strdup(mnt);

View File

@ -398,6 +398,7 @@ int selinux_init_load_policy(int *enforce)
if (rc == 0) {
/* Successfully disabled, so umount selinuxfs too. */
umount(SELINUXMNT);
fini_selinuxmnt();
}
/*
* If we failed to disable, SELinux will still be

View File

@ -17,6 +17,7 @@ static __thread int con_array_used;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t destructor_key;
static int destructor_key_initialized = 0;
static int add_array_elt(char *con)
{
@ -292,12 +293,14 @@ static void matchpathcon_thread_destructor(void __attribute__((unused)) *ptr)
void __attribute__((destructor)) matchpathcon_lib_destructor(void)
{
__selinux_key_delete(destructor_key);
if (destructor_key_initialized)
__selinux_key_delete(destructor_key);
}
static void matchpathcon_init_once(void)
{
__selinux_key_create(&destructor_key, matchpathcon_thread_destructor);
if (__selinux_key_create(&destructor_key, matchpathcon_thread_destructor) == 0)
destructor_key_initialized = 1;
}
int matchpathcon_init_prefix(const char *path, const char *subset)

View File

@ -3,6 +3,7 @@
#include "dso.h"
hidden_proto(selinux_mkload_policy)
hidden_proto(fini_selinuxmnt)
hidden_proto(set_selinuxmnt)
hidden_proto(security_disable)
hidden_proto(security_policyvers)
@ -114,10 +115,7 @@ extern int selinux_page_size hidden;
/* Pthread key macros */
#define __selinux_key_create(KEY, DESTRUCTOR) \
do { \
if (pthread_key_create != NULL) \
pthread_key_create(KEY, DESTRUCTOR); \
} while (0)
(pthread_key_create != NULL ? pthread_key_create(KEY, DESTRUCTOR) : -1)
#define __selinux_key_delete(KEY) \
do { \

View File

@ -35,6 +35,7 @@ static __thread security_context_t prev_r2c_raw = NULL;
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t destructor_key;
static int destructor_key_initialized = 0;
static __thread char destructor_initialized;
/*
@ -254,7 +255,8 @@ static void setrans_thread_destructor(void __attribute__((unused)) *unused)
void __attribute__((destructor)) setrans_lib_destructor(void)
{
__selinux_key_delete(destructor_key);
if (destructor_key_initialized)
__selinux_key_delete(destructor_key);
}
static inline void init_thread_destructor(void)
@ -267,7 +269,9 @@ static inline void init_thread_destructor(void)
static void init_context_translations(void)
{
__selinux_key_create(&destructor_key, setrans_thread_destructor);
if (__selinux_key_create(&destructor_key, setrans_thread_destructor) == 0)
destructor_key_initialized = 1;
mls_enabled = is_selinux_mls_enabled();
}