diff options
author | Christopher J. PeBenito <cpebenito@tresys.com> | 2007-05-23 09:12:06 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2007-07-11 22:52:15 -0400 |
commit | 55fcf09b3fe4325c9395ebbb0322a547a157ebc7 (patch) | |
tree | 36415abc8ad7e917909a1fbfbdcc8ad84f0cebd2 | |
parent | 4eb6bf6bfb580afaf1e1a1d30cba17a078530cf4 (diff) |
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>
-rw-r--r-- | security/selinux/include/security.h | 3 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 95 |
2 files changed, 98 insertions, 0 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index b94378afea25..731a173f5a5f 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -87,6 +87,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | |||
87 | 87 | ||
88 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); | 88 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); |
89 | 89 | ||
90 | int security_get_classes(char ***classes, int *nclasses); | ||
91 | int security_get_permissions(char *class, char ***perms, int *nperms); | ||
92 | |||
90 | #define SECURITY_FS_USE_XATTR 1 /* use xattr */ | 93 | #define SECURITY_FS_USE_XATTR 1 /* use xattr */ |
91 | #define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ | 94 | #define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ |
92 | #define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */ | 95 | #define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */ |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 40660ffd49b6..e4249adaa880 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1996,6 +1996,101 @@ out: | |||
1996 | return rc; | 1996 | return rc; |
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | static int get_classes_callback(void *k, void *d, void *args) | ||
2000 | { | ||
2001 | struct class_datum *datum = d; | ||
2002 | char *name = k, **classes = args; | ||
2003 | int value = datum->value - 1; | ||
2004 | |||
2005 | classes[value] = kstrdup(name, GFP_ATOMIC); | ||
2006 | if (!classes[value]) | ||
2007 | return -ENOMEM; | ||
2008 | |||
2009 | return 0; | ||
2010 | } | ||
2011 | |||
2012 | int security_get_classes(char ***classes, int *nclasses) | ||
2013 | { | ||
2014 | int rc = -ENOMEM; | ||
2015 | |||
2016 | POLICY_RDLOCK; | ||
2017 | |||
2018 | *nclasses = policydb.p_classes.nprim; | ||
2019 | *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); | ||
2020 | if (!*classes) | ||
2021 | goto out; | ||
2022 | |||
2023 | rc = hashtab_map(policydb.p_classes.table, get_classes_callback, | ||
2024 | *classes); | ||
2025 | if (rc < 0) { | ||
2026 | int i; | ||
2027 | for (i = 0; i < *nclasses; i++) | ||
2028 | kfree((*classes)[i]); | ||
2029 | kfree(*classes); | ||
2030 | } | ||
2031 | |||
2032 | out: | ||
2033 | POLICY_RDUNLOCK; | ||
2034 | return rc; | ||
2035 | } | ||
2036 | |||
2037 | static int get_permissions_callback(void *k, void *d, void *args) | ||
2038 | { | ||
2039 | struct perm_datum *datum = d; | ||
2040 | char *name = k, **perms = args; | ||
2041 | int value = datum->value - 1; | ||
2042 | |||
2043 | perms[value] = kstrdup(name, GFP_ATOMIC); | ||
2044 | if (!perms[value]) | ||
2045 | return -ENOMEM; | ||
2046 | |||
2047 | return 0; | ||
2048 | } | ||
2049 | |||
2050 | int security_get_permissions(char *class, char ***perms, int *nperms) | ||
2051 | { | ||
2052 | int rc = -ENOMEM, i; | ||
2053 | struct class_datum *match; | ||
2054 | |||
2055 | POLICY_RDLOCK; | ||
2056 | |||
2057 | match = hashtab_search(policydb.p_classes.table, class); | ||
2058 | if (!match) { | ||
2059 | printk(KERN_ERR "%s: unrecognized class %s\n", | ||
2060 | __FUNCTION__, class); | ||
2061 | rc = -EINVAL; | ||
2062 | goto out; | ||
2063 | } | ||
2064 | |||
2065 | *nperms = match->permissions.nprim; | ||
2066 | *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC); | ||
2067 | if (!*perms) | ||
2068 | goto out; | ||
2069 | |||
2070 | if (match->comdatum) { | ||
2071 | rc = hashtab_map(match->comdatum->permissions.table, | ||
2072 | get_permissions_callback, *perms); | ||
2073 | if (rc < 0) | ||
2074 | goto err; | ||
2075 | } | ||
2076 | |||
2077 | rc = hashtab_map(match->permissions.table, get_permissions_callback, | ||
2078 | *perms); | ||
2079 | if (rc < 0) | ||
2080 | goto err; | ||
2081 | |||
2082 | out: | ||
2083 | POLICY_RDUNLOCK; | ||
2084 | return rc; | ||
2085 | |||
2086 | err: | ||
2087 | POLICY_RDUNLOCK; | ||
2088 | for (i = 0; i < *nperms; i++) | ||
2089 | kfree((*perms)[i]); | ||
2090 | kfree(*perms); | ||
2091 | return rc; | ||
2092 | } | ||
2093 | |||
1999 | struct selinux_audit_rule { | 2094 | struct selinux_audit_rule { |
2000 | u32 au_seqno; | 2095 | u32 au_seqno; |
2001 | struct context au_ctxt; | 2096 | struct context au_ctxt; |