diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
| -rw-r--r-- | security/smack/smack_lsm.c | 43 |
1 files changed, 8 insertions, 35 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 0278bc083044..e7ded1326b0f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -1498,58 +1498,31 @@ static int smack_socket_post_create(struct socket *sock, int family, | |||
| 1498 | * looks for host based access restrictions | 1498 | * looks for host based access restrictions |
| 1499 | * | 1499 | * |
| 1500 | * This version will only be appropriate for really small | 1500 | * This version will only be appropriate for really small |
| 1501 | * sets of single label hosts. Because of the masking | 1501 | * sets of single label hosts. |
| 1502 | * it cannot shortcut out on the first match. There are | ||
| 1503 | * numerious ways to address the problem, but none of them | ||
| 1504 | * have been applied here. | ||
| 1505 | * | 1502 | * |
| 1506 | * Returns the label of the far end or NULL if it's not special. | 1503 | * Returns the label of the far end or NULL if it's not special. |
| 1507 | */ | 1504 | */ |
| 1508 | static char *smack_host_label(struct sockaddr_in *sip) | 1505 | static char *smack_host_label(struct sockaddr_in *sip) |
| 1509 | { | 1506 | { |
| 1510 | struct smk_netlbladdr *snp; | 1507 | struct smk_netlbladdr *snp; |
| 1511 | char *bestlabel = NULL; | ||
| 1512 | struct in_addr *siap = &sip->sin_addr; | 1508 | struct in_addr *siap = &sip->sin_addr; |
| 1513 | struct in_addr *liap; | ||
| 1514 | struct in_addr *miap; | ||
| 1515 | struct in_addr bestmask; | ||
| 1516 | 1509 | ||
| 1517 | if (siap->s_addr == 0) | 1510 | if (siap->s_addr == 0) |
| 1518 | return NULL; | 1511 | return NULL; |
| 1519 | 1512 | ||
| 1520 | bestmask.s_addr = 0; | ||
| 1521 | |||
| 1522 | for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) { | 1513 | for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) { |
| 1523 | liap = &snp->smk_host.sin_addr; | ||
| 1524 | miap = &snp->smk_mask; | ||
| 1525 | /* | ||
| 1526 | * If the addresses match after applying the list entry mask | ||
| 1527 | * the entry matches the address. If it doesn't move along to | ||
| 1528 | * the next entry. | ||
| 1529 | */ | ||
| 1530 | if ((liap->s_addr & miap->s_addr) != | ||
| 1531 | (siap->s_addr & miap->s_addr)) | ||
| 1532 | continue; | ||
| 1533 | /* | 1514 | /* |
| 1534 | * If the list entry mask identifies a single address | 1515 | * we break after finding the first match because |
| 1535 | * it can't get any more specific. | 1516 | * the list is sorted from longest to shortest mask |
| 1517 | * so we have found the most specific match | ||
| 1536 | */ | 1518 | */ |
| 1537 | if (miap->s_addr == 0xffffffff) | 1519 | if ((&snp->smk_host.sin_addr)->s_addr == |
| 1520 | (siap->s_addr & (&snp->smk_mask)->s_addr)) { | ||
| 1538 | return snp->smk_label; | 1521 | return snp->smk_label; |
| 1539 | /* | 1522 | } |
| 1540 | * If the list entry mask is less specific than the best | ||
| 1541 | * already found this entry is uninteresting. | ||
| 1542 | */ | ||
| 1543 | if ((miap->s_addr | bestmask.s_addr) == bestmask.s_addr) | ||
| 1544 | continue; | ||
| 1545 | /* | ||
| 1546 | * This is better than any entry found so far. | ||
| 1547 | */ | ||
| 1548 | bestmask.s_addr = miap->s_addr; | ||
| 1549 | bestlabel = snp->smk_label; | ||
| 1550 | } | 1523 | } |
| 1551 | 1524 | ||
| 1552 | return bestlabel; | 1525 | return NULL; |
| 1553 | } | 1526 | } |
| 1554 | 1527 | ||
| 1555 | /** | 1528 | /** |
