libselinux: mapping fix for invalid class/perms after selinux_set_mapping call

Please find another libselinux patch. I've tested quite extensively with the compute_av and string functions with and without mapping and seems okay.

The patch covers:
When selinux_set_mapping(3) is used to set the class and permissions allowed by an object manager, then an invalid class and/or permissions are selected (e.g. using security_class_to_string), then mapping.c in libselinux forces an assert. This patch removes the asserts and allows the functions to return a class/perm of 0 (unknown) with errno set to EINVAL. A minor patch to set EINVAL in security_av_perm_to_string_compat is also included. All the functions to convert perms & classes to strings and back should now return the correct errno with or without mapping enabled.

Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
Richard Haines 2011-03-30 17:10:05 +01:00 committed by Eric Paris
parent 8faf23de0b
commit 34d9c258da
2 changed files with 31 additions and 14 deletions

View file

@ -6,7 +6,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <selinux/selinux.h>
#include <selinux/avc.h>
#include "mapping.h"
@ -103,8 +102,13 @@ unmap_class(security_class_t tclass)
if (tclass < current_mapping_size)
return current_mapping[tclass].value;
assert(current_mapping_size == 0);
return tclass;
/* If here no mapping set or the class requested is not valid. */
if (current_mapping_size != 0) {
errno = EINVAL;
return 0;
}
else
return tclass;
}
access_vector_t
@ -116,16 +120,19 @@ unmap_perm(security_class_t tclass, access_vector_t tperm)
for (i=0; i<current_mapping[tclass].num_perms; i++)
if (tperm & (1<<i)) {
assert(current_mapping[tclass].perms[i]);
kperm |= current_mapping[tclass].perms[i];
tperm &= ~(1<<i);
}
assert(tperm == 0);
return kperm;
}
assert(current_mapping_size == 0);
return tperm;
/* If here no mapping set or the perm requested is not valid. */
if (current_mapping_size != 0) {
errno = EINVAL;
return 0;
}
else
return tperm;
}
/*
@ -141,8 +148,13 @@ map_class(security_class_t kclass)
if (current_mapping[i].value == kclass)
return i;
assert(current_mapping_size == 0);
return kclass;
/* If here no mapping set or the class requested is not valid. */
if (current_mapping_size != 0) {
errno = EINVAL;
return 0;
}
else
return kclass;
}
access_vector_t
@ -157,11 +169,14 @@ map_perm(security_class_t tclass, access_vector_t kperm)
tperm |= 1<<i;
kperm &= ~current_mapping[tclass].perms[i];
}
assert(kperm == 0);
return tperm;
}
assert(current_mapping_size == 0);
if (tperm == 0) {
errno = EINVAL;
return 0;
}
else
return tperm;
}
return kperm;
}

View file

@ -401,8 +401,10 @@ static const char *security_av_perm_to_string_compat(security_class_t tclass,
access_vector_t common_base = 0;
unsigned int i;
if (!av)
if (!av) {
errno = EINVAL;
return NULL;
}
for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
if (av_inherit[i].tclass == tclass) {