diff options
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r-- | security/selinux/ss/services.c | 73 |
1 files changed, 55 insertions, 18 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index a03cfaf0ee07..3e7544d2a07b 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -201,6 +201,21 @@ static u16 unmap_class(u16 tclass) | |||
201 | return tclass; | 201 | return tclass; |
202 | } | 202 | } |
203 | 203 | ||
204 | /* | ||
205 | * Get kernel value for class from its policy value | ||
206 | */ | ||
207 | static u16 map_class(u16 pol_value) | ||
208 | { | ||
209 | u16 i; | ||
210 | |||
211 | for (i = 1; i < current_mapping_size; i++) { | ||
212 | if (current_mapping[i].value == pol_value) | ||
213 | return i; | ||
214 | } | ||
215 | |||
216 | return pol_value; | ||
217 | } | ||
218 | |||
204 | static void map_decision(u16 tclass, struct av_decision *avd, | 219 | static void map_decision(u16 tclass, struct av_decision *avd, |
205 | int allow_unknown) | 220 | int allow_unknown) |
206 | { | 221 | { |
@@ -1343,10 +1358,27 @@ out: | |||
1343 | return -EACCES; | 1358 | return -EACCES; |
1344 | } | 1359 | } |
1345 | 1360 | ||
1361 | static void filename_compute_type(struct policydb *p, struct context *newcontext, | ||
1362 | u32 scon, u32 tcon, u16 tclass, | ||
1363 | const struct qstr *qstr) | ||
1364 | { | ||
1365 | struct filename_trans *ft; | ||
1366 | for (ft = p->filename_trans; ft; ft = ft->next) { | ||
1367 | if (ft->stype == scon && | ||
1368 | ft->ttype == tcon && | ||
1369 | ft->tclass == tclass && | ||
1370 | !strcmp(ft->name, qstr->name)) { | ||
1371 | newcontext->type = ft->otype; | ||
1372 | return; | ||
1373 | } | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1346 | static int security_compute_sid(u32 ssid, | 1377 | static int security_compute_sid(u32 ssid, |
1347 | u32 tsid, | 1378 | u32 tsid, |
1348 | u16 orig_tclass, | 1379 | u16 orig_tclass, |
1349 | u32 specified, | 1380 | u32 specified, |
1381 | const struct qstr *qstr, | ||
1350 | u32 *out_sid, | 1382 | u32 *out_sid, |
1351 | bool kern) | 1383 | bool kern) |
1352 | { | 1384 | { |
@@ -1357,6 +1389,7 @@ static int security_compute_sid(u32 ssid, | |||
1357 | struct avtab_node *node; | 1389 | struct avtab_node *node; |
1358 | u16 tclass; | 1390 | u16 tclass; |
1359 | int rc = 0; | 1391 | int rc = 0; |
1392 | bool sock; | ||
1360 | 1393 | ||
1361 | if (!ss_initialized) { | 1394 | if (!ss_initialized) { |
1362 | switch (orig_tclass) { | 1395 | switch (orig_tclass) { |
@@ -1374,10 +1407,13 @@ static int security_compute_sid(u32 ssid, | |||
1374 | 1407 | ||
1375 | read_lock(&policy_rwlock); | 1408 | read_lock(&policy_rwlock); |
1376 | 1409 | ||
1377 | if (kern) | 1410 | if (kern) { |
1378 | tclass = unmap_class(orig_tclass); | 1411 | tclass = unmap_class(orig_tclass); |
1379 | else | 1412 | sock = security_is_socket_class(orig_tclass); |
1413 | } else { | ||
1380 | tclass = orig_tclass; | 1414 | tclass = orig_tclass; |
1415 | sock = security_is_socket_class(map_class(tclass)); | ||
1416 | } | ||
1381 | 1417 | ||
1382 | scontext = sidtab_search(&sidtab, ssid); | 1418 | scontext = sidtab_search(&sidtab, ssid); |
1383 | if (!scontext) { | 1419 | if (!scontext) { |
@@ -1408,7 +1444,7 @@ static int security_compute_sid(u32 ssid, | |||
1408 | } | 1444 | } |
1409 | 1445 | ||
1410 | /* Set the role and type to default values. */ | 1446 | /* Set the role and type to default values. */ |
1411 | if (tclass == policydb.process_class) { | 1447 | if ((tclass == policydb.process_class) || (sock == true)) { |
1412 | /* Use the current role and type of process. */ | 1448 | /* Use the current role and type of process. */ |
1413 | newcontext.role = scontext->role; | 1449 | newcontext.role = scontext->role; |
1414 | newcontext.type = scontext->type; | 1450 | newcontext.type = scontext->type; |
@@ -1442,6 +1478,11 @@ static int security_compute_sid(u32 ssid, | |||
1442 | newcontext.type = avdatum->data; | 1478 | newcontext.type = avdatum->data; |
1443 | } | 1479 | } |
1444 | 1480 | ||
1481 | /* if we have a qstr this is a file trans check so check those rules */ | ||
1482 | if (qstr) | ||
1483 | filename_compute_type(&policydb, &newcontext, scontext->type, | ||
1484 | tcontext->type, tclass, qstr); | ||
1485 | |||
1445 | /* Check for class-specific changes. */ | 1486 | /* Check for class-specific changes. */ |
1446 | if (tclass == policydb.process_class) { | 1487 | if (tclass == policydb.process_class) { |
1447 | if (specified & AVTAB_TRANSITION) { | 1488 | if (specified & AVTAB_TRANSITION) { |
@@ -1460,7 +1501,8 @@ static int security_compute_sid(u32 ssid, | |||
1460 | 1501 | ||
1461 | /* Set the MLS attributes. | 1502 | /* Set the MLS attributes. |
1462 | This is done last because it may allocate memory. */ | 1503 | This is done last because it may allocate memory. */ |
1463 | rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext); | 1504 | rc = mls_compute_sid(scontext, tcontext, tclass, specified, |
1505 | &newcontext, sock); | ||
1464 | if (rc) | 1506 | if (rc) |
1465 | goto out_unlock; | 1507 | goto out_unlock; |
1466 | 1508 | ||
@@ -1495,22 +1537,17 @@ out: | |||
1495 | * if insufficient memory is available, or %0 if the new SID was | 1537 | * if insufficient memory is available, or %0 if the new SID was |
1496 | * computed successfully. | 1538 | * computed successfully. |
1497 | */ | 1539 | */ |
1498 | int security_transition_sid(u32 ssid, | 1540 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, |
1499 | u32 tsid, | 1541 | const struct qstr *qstr, u32 *out_sid) |
1500 | u16 tclass, | ||
1501 | u32 *out_sid) | ||
1502 | { | 1542 | { |
1503 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1543 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
1504 | out_sid, true); | 1544 | qstr, out_sid, true); |
1505 | } | 1545 | } |
1506 | 1546 | ||
1507 | int security_transition_sid_user(u32 ssid, | 1547 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) |
1508 | u32 tsid, | ||
1509 | u16 tclass, | ||
1510 | u32 *out_sid) | ||
1511 | { | 1548 | { |
1512 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1549 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
1513 | out_sid, false); | 1550 | NULL, out_sid, false); |
1514 | } | 1551 | } |
1515 | 1552 | ||
1516 | /** | 1553 | /** |
@@ -1531,8 +1568,8 @@ int security_member_sid(u32 ssid, | |||
1531 | u16 tclass, | 1568 | u16 tclass, |
1532 | u32 *out_sid) | 1569 | u32 *out_sid) |
1533 | { | 1570 | { |
1534 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid, | 1571 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL, |
1535 | false); | 1572 | out_sid, false); |
1536 | } | 1573 | } |
1537 | 1574 | ||
1538 | /** | 1575 | /** |
@@ -1553,8 +1590,8 @@ int security_change_sid(u32 ssid, | |||
1553 | u16 tclass, | 1590 | u16 tclass, |
1554 | u32 *out_sid) | 1591 | u32 *out_sid) |
1555 | { | 1592 | { |
1556 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid, | 1593 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL, |
1557 | false); | 1594 | out_sid, false); |
1558 | } | 1595 | } |
1559 | 1596 | ||
1560 | /* Clone the SID into the new SID table. */ | 1597 | /* Clone the SID into the new SID table. */ |