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