summaryrefslogtreecommitdiff
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6ef4af47dac4..973e00e34fa9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1359,26 +1359,35 @@ out:
}
static void filename_compute_type(struct policydb *p, struct context *newcontext,
- u32 scon, u32 tcon, u16 tclass,
- const struct qstr *qstr)
-{
- struct filename_trans *ft;
- for (ft = p->filename_trans; ft; ft = ft->next) {
- if (ft->stype == scon &&
- ft->ttype == tcon &&
- ft->tclass == tclass &&
- !strcmp(ft->name, qstr->name)) {
- newcontext->type = ft->otype;
- return;
- }
- }
+ u32 stype, u32 ttype, u16 tclass,
+ const char *objname)
+{
+ struct filename_trans ft;
+ struct filename_trans_datum *otype;
+
+ /*
+ * Most filename trans rules are going to live in specific directories
+ * like /dev or /var/run. This bitmap will quickly skip rule searches
+ * if the ttype does not contain any rules.
+ */
+ if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
+ return;
+
+ ft.stype = stype;
+ ft.ttype = ttype;
+ ft.tclass = tclass;
+ ft.name = objname;
+
+ otype = hashtab_search(p->filename_trans, &ft);
+ if (otype)
+ newcontext->type = otype->otype;
}
static int security_compute_sid(u32 ssid,
u32 tsid,
u16 orig_tclass,
u32 specified,
- const struct qstr *qstr,
+ const char *objname,
u32 *out_sid,
bool kern)
{
@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid,
newcontext.type = avdatum->data;
}
- /* if we have a qstr this is a file trans check so check those rules */
- if (qstr)
+ /* if we have a objname this is a file trans check so check those rules */
+ if (objname)
filename_compute_type(&policydb, &newcontext, scontext->type,
- tcontext->type, tclass, qstr);
+ tcontext->type, tclass, objname);
/* Check for class-specific changes. */
- if (tclass == policydb.process_class) {
- if (specified & AVTAB_TRANSITION) {
- /* Look for a role transition rule. */
- for (roletr = policydb.role_tr; roletr;
- roletr = roletr->next) {
- if (roletr->role == scontext->role &&
- roletr->type == tcontext->type) {
- /* Use the role transition rule. */
- newcontext.role = roletr->new_role;
- break;
- }
+ if (specified & AVTAB_TRANSITION) {
+ /* Look for a role transition rule. */
+ for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
+ if ((roletr->role == scontext->role) &&
+ (roletr->type == tcontext->type) &&
+ (roletr->tclass == tclass)) {
+ /* Use the role transition rule. */
+ newcontext.role = roletr->new_role;
+ break;
}
}
}
@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid)
{
return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
- qstr, out_sid, true);
+ qstr ? qstr->name : NULL, out_sid, true);
}
-int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
+ const char *objname, u32 *out_sid)
{
return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
- NULL, out_sid, false);
+ objname, out_sid, false);
}
/**
@@ -2209,10 +2217,11 @@ out_unlock:
goto out;
}
for (i = 0, j = 0; i < mynel; i++) {
+ struct av_decision dummy_avd;
rc = avc_has_perm_noaudit(fromsid, mysids[i],
SECCLASS_PROCESS, /* kernel value */
PROCESS__TRANSITION, AVC_STRICT,
- NULL);
+ &dummy_avd);
if (!rc)
mysids2[j++] = mysids[i];
cond_resched();
@@ -3190,7 +3199,7 @@ out:
* @len: length of data in bytes
*
*/
-int security_read_policy(void **data, ssize_t *len)
+int security_read_policy(void **data, size_t *len)
{
int rc;
struct policy_file fp;