selinux: add support for querying object classes and permissions from the running policy
Add support to the SELinux security server for obtaining a list of classes, and for obtaining a list of permissions for a specified class. Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
4eb6bf6bfb
commit
55fcf09b3f
2 changed files with 98 additions and 0 deletions
|
@ -87,6 +87,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
|
|||
|
||||
int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
|
||||
|
||||
int security_get_classes(char ***classes, int *nclasses);
|
||||
int security_get_permissions(char *class, char ***perms, int *nperms);
|
||||
|
||||
#define SECURITY_FS_USE_XATTR 1 /* use xattr */
|
||||
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
|
||||
#define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */
|
||||
|
|
|
@ -1996,6 +1996,101 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int get_classes_callback(void *k, void *d, void *args)
|
||||
{
|
||||
struct class_datum *datum = d;
|
||||
char *name = k, **classes = args;
|
||||
int value = datum->value - 1;
|
||||
|
||||
classes[value] = kstrdup(name, GFP_ATOMIC);
|
||||
if (!classes[value])
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int security_get_classes(char ***classes, int *nclasses)
|
||||
{
|
||||
int rc = -ENOMEM;
|
||||
|
||||
POLICY_RDLOCK;
|
||||
|
||||
*nclasses = policydb.p_classes.nprim;
|
||||
*classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
|
||||
if (!*classes)
|
||||
goto out;
|
||||
|
||||
rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
|
||||
*classes);
|
||||
if (rc < 0) {
|
||||
int i;
|
||||
for (i = 0; i < *nclasses; i++)
|
||||
kfree((*classes)[i]);
|
||||
kfree(*classes);
|
||||
}
|
||||
|
||||
out:
|
||||
POLICY_RDUNLOCK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int get_permissions_callback(void *k, void *d, void *args)
|
||||
{
|
||||
struct perm_datum *datum = d;
|
||||
char *name = k, **perms = args;
|
||||
int value = datum->value - 1;
|
||||
|
||||
perms[value] = kstrdup(name, GFP_ATOMIC);
|
||||
if (!perms[value])
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int security_get_permissions(char *class, char ***perms, int *nperms)
|
||||
{
|
||||
int rc = -ENOMEM, i;
|
||||
struct class_datum *match;
|
||||
|
||||
POLICY_RDLOCK;
|
||||
|
||||
match = hashtab_search(policydb.p_classes.table, class);
|
||||
if (!match) {
|
||||
printk(KERN_ERR "%s: unrecognized class %s\n",
|
||||
__FUNCTION__, class);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*nperms = match->permissions.nprim;
|
||||
*perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
|
||||
if (!*perms)
|
||||
goto out;
|
||||
|
||||
if (match->comdatum) {
|
||||
rc = hashtab_map(match->comdatum->permissions.table,
|
||||
get_permissions_callback, *perms);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = hashtab_map(match->permissions.table, get_permissions_callback,
|
||||
*perms);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
|
||||
out:
|
||||
POLICY_RDUNLOCK;
|
||||
return rc;
|
||||
|
||||
err:
|
||||
POLICY_RDUNLOCK;
|
||||
for (i = 0; i < *nperms; i++)
|
||||
kfree((*perms)[i]);
|
||||
kfree(*perms);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct selinux_audit_rule {
|
||||
u32 au_seqno;
|
||||
struct context au_ctxt;
|
||||
|
|
Loading…
Reference in a new issue