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 | /** |