diff options
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r-- | security/selinux/ss/services.c | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 6ef4af47dac4..c3e4b52699f4 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1359,26 +1359,35 @@ out: | |||
1359 | } | 1359 | } |
1360 | 1360 | ||
1361 | static void filename_compute_type(struct policydb *p, struct context *newcontext, | 1361 | static void filename_compute_type(struct policydb *p, struct context *newcontext, |
1362 | u32 scon, u32 tcon, u16 tclass, | 1362 | u32 stype, u32 ttype, u16 tclass, |
1363 | const struct qstr *qstr) | 1363 | const char *objname) |
1364 | { | 1364 | { |
1365 | struct filename_trans *ft; | 1365 | struct filename_trans ft; |
1366 | for (ft = p->filename_trans; ft; ft = ft->next) { | 1366 | struct filename_trans_datum *otype; |
1367 | if (ft->stype == scon && | 1367 | |
1368 | ft->ttype == tcon && | 1368 | /* |
1369 | ft->tclass == tclass && | 1369 | * Most filename trans rules are going to live in specific directories |
1370 | !strcmp(ft->name, qstr->name)) { | 1370 | * like /dev or /var/run. This bitmap will quickly skip rule searches |
1371 | newcontext->type = ft->otype; | 1371 | * if the ttype does not contain any rules. |
1372 | return; | 1372 | */ |
1373 | } | 1373 | if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype)) |
1374 | } | 1374 | return; |
1375 | |||
1376 | ft.stype = stype; | ||
1377 | ft.ttype = ttype; | ||
1378 | ft.tclass = tclass; | ||
1379 | ft.name = objname; | ||
1380 | |||
1381 | otype = hashtab_search(p->filename_trans, &ft); | ||
1382 | if (otype) | ||
1383 | newcontext->type = otype->otype; | ||
1375 | } | 1384 | } |
1376 | 1385 | ||
1377 | static int security_compute_sid(u32 ssid, | 1386 | static int security_compute_sid(u32 ssid, |
1378 | u32 tsid, | 1387 | u32 tsid, |
1379 | u16 orig_tclass, | 1388 | u16 orig_tclass, |
1380 | u32 specified, | 1389 | u32 specified, |
1381 | const struct qstr *qstr, | 1390 | const char *objname, |
1382 | u32 *out_sid, | 1391 | u32 *out_sid, |
1383 | bool kern) | 1392 | bool kern) |
1384 | { | 1393 | { |
@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid, | |||
1478 | newcontext.type = avdatum->data; | 1487 | newcontext.type = avdatum->data; |
1479 | } | 1488 | } |
1480 | 1489 | ||
1481 | /* if we have a qstr this is a file trans check so check those rules */ | 1490 | /* if we have a objname this is a file trans check so check those rules */ |
1482 | if (qstr) | 1491 | if (objname) |
1483 | filename_compute_type(&policydb, &newcontext, scontext->type, | 1492 | filename_compute_type(&policydb, &newcontext, scontext->type, |
1484 | tcontext->type, tclass, qstr); | 1493 | tcontext->type, tclass, objname); |
1485 | 1494 | ||
1486 | /* Check for class-specific changes. */ | 1495 | /* Check for class-specific changes. */ |
1487 | if (tclass == policydb.process_class) { | 1496 | if (specified & AVTAB_TRANSITION) { |
1488 | if (specified & AVTAB_TRANSITION) { | 1497 | /* Look for a role transition rule. */ |
1489 | /* Look for a role transition rule. */ | 1498 | for (roletr = policydb.role_tr; roletr; roletr = roletr->next) { |
1490 | for (roletr = policydb.role_tr; roletr; | 1499 | if ((roletr->role == scontext->role) && |
1491 | roletr = roletr->next) { | 1500 | (roletr->type == tcontext->type) && |
1492 | if (roletr->role == scontext->role && | 1501 | (roletr->tclass == tclass)) { |
1493 | roletr->type == tcontext->type) { | 1502 | /* Use the role transition rule. */ |
1494 | /* Use the role transition rule. */ | 1503 | newcontext.role = roletr->new_role; |
1495 | newcontext.role = roletr->new_role; | 1504 | break; |
1496 | break; | ||
1497 | } | ||
1498 | } | 1505 | } |
1499 | } | 1506 | } |
1500 | } | 1507 | } |
@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, | |||
1541 | const struct qstr *qstr, u32 *out_sid) | 1548 | const struct qstr *qstr, u32 *out_sid) |
1542 | { | 1549 | { |
1543 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1550 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
1544 | qstr, out_sid, true); | 1551 | qstr ? qstr->name : NULL, out_sid, true); |
1545 | } | 1552 | } |
1546 | 1553 | ||
1547 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) | 1554 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, |
1555 | const char *objname, u32 *out_sid) | ||
1548 | { | 1556 | { |
1549 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1557 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
1550 | NULL, out_sid, false); | 1558 | objname, out_sid, false); |
1551 | } | 1559 | } |
1552 | 1560 | ||
1553 | /** | 1561 | /** |
@@ -3190,7 +3198,7 @@ out: | |||
3190 | * @len: length of data in bytes | 3198 | * @len: length of data in bytes |
3191 | * | 3199 | * |
3192 | */ | 3200 | */ |
3193 | int security_read_policy(void **data, ssize_t *len) | 3201 | int security_read_policy(void **data, size_t *len) |
3194 | { | 3202 | { |
3195 | int rc; | 3203 | int rc; |
3196 | struct policy_file fp; | 3204 | struct policy_file fp; |