diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
| -rw-r--r-- | net/xfrm/xfrm_user.c | 135 |
1 files changed, 106 insertions, 29 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d5a712976004..8bae6b22c846 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -446,6 +446,8 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
| 446 | goto error; | 446 | goto error; |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | xfrm_mark_get(attrs, &x->mark); | ||
| 450 | |||
| 449 | err = xfrm_init_state(x); | 451 | err = xfrm_init_state(x); |
| 450 | if (err) | 452 | if (err) |
| 451 | goto error; | 453 | goto error; |
| @@ -526,11 +528,13 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, | |||
| 526 | int *errp) | 528 | int *errp) |
| 527 | { | 529 | { |
| 528 | struct xfrm_state *x = NULL; | 530 | struct xfrm_state *x = NULL; |
| 531 | struct xfrm_mark m; | ||
| 529 | int err; | 532 | int err; |
| 533 | u32 mark = xfrm_mark_get(attrs, &m); | ||
| 530 | 534 | ||
| 531 | if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { | 535 | if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { |
| 532 | err = -ESRCH; | 536 | err = -ESRCH; |
| 533 | x = xfrm_state_lookup(net, &p->daddr, p->spi, p->proto, p->family); | 537 | x = xfrm_state_lookup(net, mark, &p->daddr, p->spi, p->proto, p->family); |
| 534 | } else { | 538 | } else { |
| 535 | xfrm_address_t *saddr = NULL; | 539 | xfrm_address_t *saddr = NULL; |
| 536 | 540 | ||
| @@ -541,7 +545,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net, | |||
| 541 | } | 545 | } |
| 542 | 546 | ||
| 543 | err = -ESRCH; | 547 | err = -ESRCH; |
| 544 | x = xfrm_state_lookup_byaddr(net, &p->daddr, saddr, | 548 | x = xfrm_state_lookup_byaddr(net, mark, |
| 549 | &p->daddr, saddr, | ||
| 545 | p->proto, p->family); | 550 | p->proto, p->family); |
| 546 | } | 551 | } |
| 547 | 552 | ||
| @@ -683,6 +688,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x, | |||
| 683 | if (x->encap) | 688 | if (x->encap) |
| 684 | NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); | 689 | NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); |
| 685 | 690 | ||
| 691 | if (xfrm_mark_put(skb, &x->mark)) | ||
| 692 | goto nla_put_failure; | ||
| 693 | |||
| 686 | if (x->security && copy_sec_ctx(x->security, skb) < 0) | 694 | if (x->security && copy_sec_ctx(x->security, skb) < 0) |
| 687 | goto nla_put_failure; | 695 | goto nla_put_failure; |
| 688 | 696 | ||
| @@ -947,6 +955,8 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 947 | xfrm_address_t *daddr; | 955 | xfrm_address_t *daddr; |
| 948 | int family; | 956 | int family; |
| 949 | int err; | 957 | int err; |
| 958 | u32 mark; | ||
| 959 | struct xfrm_mark m; | ||
| 950 | 960 | ||
| 951 | p = nlmsg_data(nlh); | 961 | p = nlmsg_data(nlh); |
| 952 | err = verify_userspi_info(p); | 962 | err = verify_userspi_info(p); |
| @@ -957,8 +967,10 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 957 | daddr = &p->info.id.daddr; | 967 | daddr = &p->info.id.daddr; |
| 958 | 968 | ||
| 959 | x = NULL; | 969 | x = NULL; |
| 970 | |||
| 971 | mark = xfrm_mark_get(attrs, &m); | ||
| 960 | if (p->info.seq) { | 972 | if (p->info.seq) { |
| 961 | x = xfrm_find_acq_byseq(net, p->info.seq); | 973 | x = xfrm_find_acq_byseq(net, mark, p->info.seq); |
| 962 | if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { | 974 | if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { |
| 963 | xfrm_state_put(x); | 975 | xfrm_state_put(x); |
| 964 | x = NULL; | 976 | x = NULL; |
| @@ -966,7 +978,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 966 | } | 978 | } |
| 967 | 979 | ||
| 968 | if (!x) | 980 | if (!x) |
| 969 | x = xfrm_find_acq(net, p->info.mode, p->info.reqid, | 981 | x = xfrm_find_acq(net, &m, p->info.mode, p->info.reqid, |
| 970 | p->info.id.proto, daddr, | 982 | p->info.id.proto, daddr, |
| 971 | &p->info.saddr, 1, | 983 | &p->info.saddr, 1, |
| 972 | family); | 984 | family); |
| @@ -1220,6 +1232,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us | |||
| 1220 | if (err) | 1232 | if (err) |
| 1221 | goto error; | 1233 | goto error; |
| 1222 | 1234 | ||
| 1235 | xfrm_mark_get(attrs, &xp->mark); | ||
| 1236 | |||
| 1223 | return xp; | 1237 | return xp; |
| 1224 | error: | 1238 | error: |
| 1225 | *errp = err; | 1239 | *errp = err; |
| @@ -1366,10 +1380,13 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr | |||
| 1366 | goto nlmsg_failure; | 1380 | goto nlmsg_failure; |
| 1367 | if (copy_to_user_policy_type(xp->type, skb) < 0) | 1381 | if (copy_to_user_policy_type(xp->type, skb) < 0) |
| 1368 | goto nlmsg_failure; | 1382 | goto nlmsg_failure; |
| 1383 | if (xfrm_mark_put(skb, &xp->mark)) | ||
| 1384 | goto nla_put_failure; | ||
| 1369 | 1385 | ||
| 1370 | nlmsg_end(skb, nlh); | 1386 | nlmsg_end(skb, nlh); |
| 1371 | return 0; | 1387 | return 0; |
| 1372 | 1388 | ||
| 1389 | nla_put_failure: | ||
| 1373 | nlmsg_failure: | 1390 | nlmsg_failure: |
| 1374 | nlmsg_cancel(skb, nlh); | 1391 | nlmsg_cancel(skb, nlh); |
| 1375 | return -EMSGSIZE; | 1392 | return -EMSGSIZE; |
| @@ -1441,6 +1458,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1441 | int err; | 1458 | int err; |
| 1442 | struct km_event c; | 1459 | struct km_event c; |
| 1443 | int delete; | 1460 | int delete; |
| 1461 | struct xfrm_mark m; | ||
| 1462 | u32 mark = xfrm_mark_get(attrs, &m); | ||
| 1444 | 1463 | ||
| 1445 | p = nlmsg_data(nlh); | 1464 | p = nlmsg_data(nlh); |
| 1446 | delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; | 1465 | delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; |
| @@ -1454,7 +1473,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1454 | return err; | 1473 | return err; |
| 1455 | 1474 | ||
| 1456 | if (p->index) | 1475 | if (p->index) |
| 1457 | xp = xfrm_policy_byid(net, type, p->dir, p->index, delete, &err); | 1476 | xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, delete, &err); |
| 1458 | else { | 1477 | else { |
| 1459 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1478 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
| 1460 | struct xfrm_sec_ctx *ctx; | 1479 | struct xfrm_sec_ctx *ctx; |
| @@ -1471,8 +1490,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1471 | if (err) | 1490 | if (err) |
| 1472 | return err; | 1491 | return err; |
| 1473 | } | 1492 | } |
| 1474 | xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, | 1493 | xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, &p->sel, |
| 1475 | delete, &err); | 1494 | ctx, delete, &err); |
| 1476 | security_xfrm_policy_free(ctx); | 1495 | security_xfrm_policy_free(ctx); |
| 1477 | } | 1496 | } |
| 1478 | if (xp == NULL) | 1497 | if (xp == NULL) |
| @@ -1524,8 +1543,11 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1524 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | 1543 | audit_info.sessionid = NETLINK_CB(skb).sessionid; |
| 1525 | audit_info.secid = NETLINK_CB(skb).sid; | 1544 | audit_info.secid = NETLINK_CB(skb).sid; |
| 1526 | err = xfrm_state_flush(net, p->proto, &audit_info); | 1545 | err = xfrm_state_flush(net, p->proto, &audit_info); |
| 1527 | if (err) | 1546 | if (err) { |
| 1547 | if (err == -ESRCH) /* empty table */ | ||
| 1548 | return 0; | ||
| 1528 | return err; | 1549 | return err; |
| 1550 | } | ||
| 1529 | c.data.proto = p->proto; | 1551 | c.data.proto = p->proto; |
| 1530 | c.event = nlh->nlmsg_type; | 1552 | c.event = nlh->nlmsg_type; |
| 1531 | c.seq = nlh->nlmsg_seq; | 1553 | c.seq = nlh->nlmsg_seq; |
| @@ -1541,6 +1563,7 @@ static inline size_t xfrm_aevent_msgsize(void) | |||
| 1541 | return NLMSG_ALIGN(sizeof(struct xfrm_aevent_id)) | 1563 | return NLMSG_ALIGN(sizeof(struct xfrm_aevent_id)) |
| 1542 | + nla_total_size(sizeof(struct xfrm_replay_state)) | 1564 | + nla_total_size(sizeof(struct xfrm_replay_state)) |
| 1543 | + nla_total_size(sizeof(struct xfrm_lifetime_cur)) | 1565 | + nla_total_size(sizeof(struct xfrm_lifetime_cur)) |
| 1566 | + nla_total_size(sizeof(struct xfrm_mark)) | ||
| 1544 | + nla_total_size(4) /* XFRM_AE_RTHR */ | 1567 | + nla_total_size(4) /* XFRM_AE_RTHR */ |
| 1545 | + nla_total_size(4); /* XFRM_AE_ETHR */ | 1568 | + nla_total_size(4); /* XFRM_AE_ETHR */ |
| 1546 | } | 1569 | } |
| @@ -1573,6 +1596,9 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve | |||
| 1573 | NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH, | 1596 | NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH, |
| 1574 | x->replay_maxage * 10 / HZ); | 1597 | x->replay_maxage * 10 / HZ); |
| 1575 | 1598 | ||
| 1599 | if (xfrm_mark_put(skb, &x->mark)) | ||
| 1600 | goto nla_put_failure; | ||
| 1601 | |||
| 1576 | return nlmsg_end(skb, nlh); | 1602 | return nlmsg_end(skb, nlh); |
| 1577 | 1603 | ||
| 1578 | nla_put_failure: | 1604 | nla_put_failure: |
| @@ -1588,6 +1614,8 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1588 | struct sk_buff *r_skb; | 1614 | struct sk_buff *r_skb; |
| 1589 | int err; | 1615 | int err; |
| 1590 | struct km_event c; | 1616 | struct km_event c; |
| 1617 | u32 mark; | ||
| 1618 | struct xfrm_mark m; | ||
| 1591 | struct xfrm_aevent_id *p = nlmsg_data(nlh); | 1619 | struct xfrm_aevent_id *p = nlmsg_data(nlh); |
| 1592 | struct xfrm_usersa_id *id = &p->sa_id; | 1620 | struct xfrm_usersa_id *id = &p->sa_id; |
| 1593 | 1621 | ||
| @@ -1595,7 +1623,9 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1595 | if (r_skb == NULL) | 1623 | if (r_skb == NULL) |
| 1596 | return -ENOMEM; | 1624 | return -ENOMEM; |
| 1597 | 1625 | ||
| 1598 | x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family); | 1626 | mark = xfrm_mark_get(attrs, &m); |
| 1627 | |||
| 1628 | x = xfrm_state_lookup(net, mark, &id->daddr, id->spi, id->proto, id->family); | ||
| 1599 | if (x == NULL) { | 1629 | if (x == NULL) { |
| 1600 | kfree_skb(r_skb); | 1630 | kfree_skb(r_skb); |
| 1601 | return -ESRCH; | 1631 | return -ESRCH; |
| @@ -1626,6 +1656,8 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1626 | struct xfrm_state *x; | 1656 | struct xfrm_state *x; |
| 1627 | struct km_event c; | 1657 | struct km_event c; |
| 1628 | int err = - EINVAL; | 1658 | int err = - EINVAL; |
| 1659 | u32 mark = 0; | ||
| 1660 | struct xfrm_mark m; | ||
| 1629 | struct xfrm_aevent_id *p = nlmsg_data(nlh); | 1661 | struct xfrm_aevent_id *p = nlmsg_data(nlh); |
| 1630 | struct nlattr *rp = attrs[XFRMA_REPLAY_VAL]; | 1662 | struct nlattr *rp = attrs[XFRMA_REPLAY_VAL]; |
| 1631 | struct nlattr *lt = attrs[XFRMA_LTIME_VAL]; | 1663 | struct nlattr *lt = attrs[XFRMA_LTIME_VAL]; |
| @@ -1637,7 +1669,9 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1637 | if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) | 1669 | if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) |
| 1638 | return err; | 1670 | return err; |
| 1639 | 1671 | ||
| 1640 | x = xfrm_state_lookup(net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); | 1672 | mark = xfrm_mark_get(attrs, &m); |
| 1673 | |||
| 1674 | x = xfrm_state_lookup(net, mark, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); | ||
| 1641 | if (x == NULL) | 1675 | if (x == NULL) |
| 1642 | return -ESRCH; | 1676 | return -ESRCH; |
| 1643 | 1677 | ||
| @@ -1676,8 +1710,12 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1676 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | 1710 | audit_info.sessionid = NETLINK_CB(skb).sessionid; |
| 1677 | audit_info.secid = NETLINK_CB(skb).sid; | 1711 | audit_info.secid = NETLINK_CB(skb).sid; |
| 1678 | err = xfrm_policy_flush(net, type, &audit_info); | 1712 | err = xfrm_policy_flush(net, type, &audit_info); |
| 1679 | if (err) | 1713 | if (err) { |
| 1714 | if (err == -ESRCH) /* empty table */ | ||
| 1715 | return 0; | ||
| 1680 | return err; | 1716 | return err; |
| 1717 | } | ||
| 1718 | |||
| 1681 | c.data.type = type; | 1719 | c.data.type = type; |
| 1682 | c.event = nlh->nlmsg_type; | 1720 | c.event = nlh->nlmsg_type; |
| 1683 | c.seq = nlh->nlmsg_seq; | 1721 | c.seq = nlh->nlmsg_seq; |
| @@ -1696,13 +1734,19 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1696 | struct xfrm_userpolicy_info *p = &up->pol; | 1734 | struct xfrm_userpolicy_info *p = &up->pol; |
| 1697 | u8 type = XFRM_POLICY_TYPE_MAIN; | 1735 | u8 type = XFRM_POLICY_TYPE_MAIN; |
| 1698 | int err = -ENOENT; | 1736 | int err = -ENOENT; |
| 1737 | struct xfrm_mark m; | ||
| 1738 | u32 mark = xfrm_mark_get(attrs, &m); | ||
| 1699 | 1739 | ||
| 1700 | err = copy_from_user_policy_type(&type, attrs); | 1740 | err = copy_from_user_policy_type(&type, attrs); |
| 1701 | if (err) | 1741 | if (err) |
| 1702 | return err; | 1742 | return err; |
| 1703 | 1743 | ||
| 1744 | err = verify_policy_dir(p->dir); | ||
| 1745 | if (err) | ||
| 1746 | return err; | ||
| 1747 | |||
| 1704 | if (p->index) | 1748 | if (p->index) |
| 1705 | xp = xfrm_policy_byid(net, type, p->dir, p->index, 0, &err); | 1749 | xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, 0, &err); |
| 1706 | else { | 1750 | else { |
| 1707 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1751 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
| 1708 | struct xfrm_sec_ctx *ctx; | 1752 | struct xfrm_sec_ctx *ctx; |
| @@ -1719,19 +1763,16 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1719 | if (err) | 1763 | if (err) |
| 1720 | return err; | 1764 | return err; |
| 1721 | } | 1765 | } |
| 1722 | xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, 0, &err); | 1766 | xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, |
| 1767 | &p->sel, ctx, 0, &err); | ||
| 1723 | security_xfrm_policy_free(ctx); | 1768 | security_xfrm_policy_free(ctx); |
| 1724 | } | 1769 | } |
| 1725 | if (xp == NULL) | 1770 | if (xp == NULL) |
| 1726 | return -ENOENT; | 1771 | return -ENOENT; |
| 1727 | 1772 | ||
| 1728 | read_lock(&xp->lock); | 1773 | if (unlikely(xp->walk.dead)) |
| 1729 | if (xp->walk.dead) { | ||
| 1730 | read_unlock(&xp->lock); | ||
| 1731 | goto out; | 1774 | goto out; |
| 1732 | } | ||
| 1733 | 1775 | ||
| 1734 | read_unlock(&xp->lock); | ||
| 1735 | err = 0; | 1776 | err = 0; |
| 1736 | if (up->hard) { | 1777 | if (up->hard) { |
| 1737 | uid_t loginuid = NETLINK_CB(skb).loginuid; | 1778 | uid_t loginuid = NETLINK_CB(skb).loginuid; |
| @@ -1742,7 +1783,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1742 | 1783 | ||
| 1743 | } else { | 1784 | } else { |
| 1744 | // reset the timers here? | 1785 | // reset the timers here? |
| 1745 | printk("Dont know what to do with soft policy expire\n"); | 1786 | WARN(1, "Dont know what to do with soft policy expire\n"); |
| 1746 | } | 1787 | } |
| 1747 | km_policy_expired(xp, p->dir, up->hard, current->pid); | 1788 | km_policy_expired(xp, p->dir, up->hard, current->pid); |
| 1748 | 1789 | ||
| @@ -1759,8 +1800,10 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1759 | int err; | 1800 | int err; |
| 1760 | struct xfrm_user_expire *ue = nlmsg_data(nlh); | 1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); |
| 1761 | struct xfrm_usersa_info *p = &ue->state; | 1802 | struct xfrm_usersa_info *p = &ue->state; |
| 1803 | struct xfrm_mark m; | ||
| 1804 | u32 mark = xfrm_mark_get(attrs, &m); | ||
| 1762 | 1805 | ||
| 1763 | x = xfrm_state_lookup(net, &p->id.daddr, p->id.spi, p->id.proto, p->family); | 1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); |
| 1764 | 1807 | ||
| 1765 | err = -ENOENT; | 1808 | err = -ENOENT; |
| 1766 | if (x == NULL) | 1809 | if (x == NULL) |
| @@ -1794,6 +1837,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1794 | struct xfrm_user_tmpl *ut; | 1837 | struct xfrm_user_tmpl *ut; |
| 1795 | int i; | 1838 | int i; |
| 1796 | struct nlattr *rt = attrs[XFRMA_TMPL]; | 1839 | struct nlattr *rt = attrs[XFRMA_TMPL]; |
| 1840 | struct xfrm_mark mark; | ||
| 1797 | 1841 | ||
| 1798 | struct xfrm_user_acquire *ua = nlmsg_data(nlh); | 1842 | struct xfrm_user_acquire *ua = nlmsg_data(nlh); |
| 1799 | struct xfrm_state *x = xfrm_state_alloc(net); | 1843 | struct xfrm_state *x = xfrm_state_alloc(net); |
| @@ -1802,6 +1846,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1802 | if (!x) | 1846 | if (!x) |
| 1803 | goto nomem; | 1847 | goto nomem; |
| 1804 | 1848 | ||
| 1849 | xfrm_mark_get(attrs, &mark); | ||
| 1850 | |||
| 1805 | err = verify_newpolicy_info(&ua->policy); | 1851 | err = verify_newpolicy_info(&ua->policy); |
| 1806 | if (err) | 1852 | if (err) |
| 1807 | goto bad_policy; | 1853 | goto bad_policy; |
| @@ -1814,7 +1860,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1814 | memcpy(&x->id, &ua->id, sizeof(ua->id)); | 1860 | memcpy(&x->id, &ua->id, sizeof(ua->id)); |
| 1815 | memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); | 1861 | memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); |
| 1816 | memcpy(&x->sel, &ua->sel, sizeof(ua->sel)); | 1862 | memcpy(&x->sel, &ua->sel, sizeof(ua->sel)); |
| 1817 | 1863 | xp->mark.m = x->mark.m = mark.m; | |
| 1864 | xp->mark.v = x->mark.v = mark.v; | ||
| 1818 | ut = nla_data(rt); | 1865 | ut = nla_data(rt); |
| 1819 | /* extract the templates and for each call km_key */ | 1866 | /* extract the templates and for each call km_key */ |
| 1820 | for (i = 0; i < xp->xfrm_nr; i++, ut++) { | 1867 | for (i = 0; i < xp->xfrm_nr; i++, ut++) { |
| @@ -1836,7 +1883,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1836 | return 0; | 1883 | return 0; |
| 1837 | 1884 | ||
| 1838 | bad_policy: | 1885 | bad_policy: |
| 1839 | printk("BAD policy passed\n"); | 1886 | WARN(1, "BAD policy passed\n"); |
| 1840 | free_state: | 1887 | free_state: |
| 1841 | kfree(x); | 1888 | kfree(x); |
| 1842 | nomem: | 1889 | nomem: |
| @@ -2054,6 +2101,10 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { | |||
| 2054 | #undef XMSGSIZE | 2101 | #undef XMSGSIZE |
| 2055 | 2102 | ||
| 2056 | static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { | 2103 | static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { |
| 2104 | [XFRMA_SA] = { .len = sizeof(struct xfrm_usersa_info)}, | ||
| 2105 | [XFRMA_POLICY] = { .len = sizeof(struct xfrm_userpolicy_info)}, | ||
| 2106 | [XFRMA_LASTUSED] = { .type = NLA_U64}, | ||
| 2107 | [XFRMA_ALG_AUTH_TRUNC] = { .len = sizeof(struct xfrm_algo_auth)}, | ||
| 2057 | [XFRMA_ALG_AEAD] = { .len = sizeof(struct xfrm_algo_aead) }, | 2108 | [XFRMA_ALG_AEAD] = { .len = sizeof(struct xfrm_algo_aead) }, |
| 2058 | [XFRMA_ALG_AUTH] = { .len = sizeof(struct xfrm_algo) }, | 2109 | [XFRMA_ALG_AUTH] = { .len = sizeof(struct xfrm_algo) }, |
| 2059 | [XFRMA_ALG_CRYPT] = { .len = sizeof(struct xfrm_algo) }, | 2110 | [XFRMA_ALG_CRYPT] = { .len = sizeof(struct xfrm_algo) }, |
| @@ -2070,6 +2121,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { | |||
| 2070 | [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)}, | 2121 | [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)}, |
| 2071 | [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, | 2122 | [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, |
| 2072 | [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) }, | 2123 | [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) }, |
| 2124 | [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) }, | ||
| 2073 | }; | 2125 | }; |
| 2074 | 2126 | ||
| 2075 | static struct xfrm_link { | 2127 | static struct xfrm_link { |
| @@ -2149,7 +2201,8 @@ static void xfrm_netlink_rcv(struct sk_buff *skb) | |||
| 2149 | 2201 | ||
| 2150 | static inline size_t xfrm_expire_msgsize(void) | 2202 | static inline size_t xfrm_expire_msgsize(void) |
| 2151 | { | 2203 | { |
| 2152 | return NLMSG_ALIGN(sizeof(struct xfrm_user_expire)); | 2204 | return NLMSG_ALIGN(sizeof(struct xfrm_user_expire)) |
| 2205 | + nla_total_size(sizeof(struct xfrm_mark)); | ||
| 2153 | } | 2206 | } |
| 2154 | 2207 | ||
| 2155 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) | 2208 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c) |
| @@ -2165,7 +2218,13 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve | |||
| 2165 | copy_to_user_state(x, &ue->state); | 2218 | copy_to_user_state(x, &ue->state); |
| 2166 | ue->hard = (c->data.hard != 0) ? 1 : 0; | 2219 | ue->hard = (c->data.hard != 0) ? 1 : 0; |
| 2167 | 2220 | ||
| 2221 | if (xfrm_mark_put(skb, &x->mark)) | ||
| 2222 | goto nla_put_failure; | ||
| 2223 | |||
| 2168 | return nlmsg_end(skb, nlh); | 2224 | return nlmsg_end(skb, nlh); |
| 2225 | |||
| 2226 | nla_put_failure: | ||
| 2227 | return -EMSGSIZE; | ||
| 2169 | } | 2228 | } |
| 2170 | 2229 | ||
| 2171 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) | 2230 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) |
| @@ -2177,8 +2236,10 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) | |||
| 2177 | if (skb == NULL) | 2236 | if (skb == NULL) |
| 2178 | return -ENOMEM; | 2237 | return -ENOMEM; |
| 2179 | 2238 | ||
| 2180 | if (build_expire(skb, x, c) < 0) | 2239 | if (build_expire(skb, x, c) < 0) { |
| 2181 | BUG(); | 2240 | kfree_skb(skb); |
| 2241 | return -EMSGSIZE; | ||
| 2242 | } | ||
| 2182 | 2243 | ||
| 2183 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); | 2244 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); |
| 2184 | } | 2245 | } |
| @@ -2266,6 +2327,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | |||
| 2266 | if (c->event == XFRM_MSG_DELSA) { | 2327 | if (c->event == XFRM_MSG_DELSA) { |
| 2267 | len += nla_total_size(headlen); | 2328 | len += nla_total_size(headlen); |
| 2268 | headlen = sizeof(*id); | 2329 | headlen = sizeof(*id); |
| 2330 | len += nla_total_size(sizeof(struct xfrm_mark)); | ||
| 2269 | } | 2331 | } |
| 2270 | len += NLMSG_ALIGN(headlen); | 2332 | len += NLMSG_ALIGN(headlen); |
| 2271 | 2333 | ||
| @@ -2323,8 +2385,9 @@ static int xfrm_send_state_notify(struct xfrm_state *x, struct km_event *c) | |||
| 2323 | case XFRM_MSG_FLUSHSA: | 2385 | case XFRM_MSG_FLUSHSA: |
| 2324 | return xfrm_notify_sa_flush(c); | 2386 | return xfrm_notify_sa_flush(c); |
| 2325 | default: | 2387 | default: |
| 2326 | printk("xfrm_user: Unknown SA event %d\n", c->event); | 2388 | printk(KERN_NOTICE "xfrm_user: Unknown SA event %d\n", |
| 2327 | break; | 2389 | c->event); |
| 2390 | break; | ||
| 2328 | } | 2391 | } |
| 2329 | 2392 | ||
| 2330 | return 0; | 2393 | return 0; |
| @@ -2336,6 +2399,7 @@ static inline size_t xfrm_acquire_msgsize(struct xfrm_state *x, | |||
| 2336 | { | 2399 | { |
| 2337 | return NLMSG_ALIGN(sizeof(struct xfrm_user_acquire)) | 2400 | return NLMSG_ALIGN(sizeof(struct xfrm_user_acquire)) |
| 2338 | + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) | 2401 | + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) |
| 2402 | + nla_total_size(sizeof(struct xfrm_mark)) | ||
| 2339 | + nla_total_size(xfrm_user_sec_ctx_size(x->security)) | 2403 | + nla_total_size(xfrm_user_sec_ctx_size(x->security)) |
| 2340 | + userpolicy_type_attrsize(); | 2404 | + userpolicy_type_attrsize(); |
| 2341 | } | 2405 | } |
| @@ -2368,9 +2432,12 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | |||
| 2368 | goto nlmsg_failure; | 2432 | goto nlmsg_failure; |
| 2369 | if (copy_to_user_policy_type(xp->type, skb) < 0) | 2433 | if (copy_to_user_policy_type(xp->type, skb) < 0) |
| 2370 | goto nlmsg_failure; | 2434 | goto nlmsg_failure; |
| 2435 | if (xfrm_mark_put(skb, &xp->mark)) | ||
| 2436 | goto nla_put_failure; | ||
| 2371 | 2437 | ||
| 2372 | return nlmsg_end(skb, nlh); | 2438 | return nlmsg_end(skb, nlh); |
| 2373 | 2439 | ||
| 2440 | nla_put_failure: | ||
| 2374 | nlmsg_failure: | 2441 | nlmsg_failure: |
| 2375 | nlmsg_cancel(skb, nlh); | 2442 | nlmsg_cancel(skb, nlh); |
| 2376 | return -EMSGSIZE; | 2443 | return -EMSGSIZE; |
| @@ -2437,7 +2504,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, | |||
| 2437 | if (p->dir > XFRM_POLICY_OUT) | 2504 | if (p->dir > XFRM_POLICY_OUT) |
| 2438 | return NULL; | 2505 | return NULL; |
| 2439 | 2506 | ||
| 2440 | xp = xfrm_policy_alloc(net, GFP_KERNEL); | 2507 | xp = xfrm_policy_alloc(net, GFP_ATOMIC); |
| 2441 | if (xp == NULL) { | 2508 | if (xp == NULL) { |
| 2442 | *dir = -ENOBUFS; | 2509 | *dir = -ENOBUFS; |
| 2443 | return NULL; | 2510 | return NULL; |
| @@ -2457,6 +2524,7 @@ static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp) | |||
| 2457 | return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire)) | 2524 | return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire)) |
| 2458 | + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) | 2525 | + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) |
| 2459 | + nla_total_size(xfrm_user_sec_ctx_size(xp->security)) | 2526 | + nla_total_size(xfrm_user_sec_ctx_size(xp->security)) |
| 2527 | + nla_total_size(sizeof(struct xfrm_mark)) | ||
| 2460 | + userpolicy_type_attrsize(); | 2528 | + userpolicy_type_attrsize(); |
| 2461 | } | 2529 | } |
| 2462 | 2530 | ||
| @@ -2479,10 +2547,13 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, | |||
| 2479 | goto nlmsg_failure; | 2547 | goto nlmsg_failure; |
| 2480 | if (copy_to_user_policy_type(xp->type, skb) < 0) | 2548 | if (copy_to_user_policy_type(xp->type, skb) < 0) |
| 2481 | goto nlmsg_failure; | 2549 | goto nlmsg_failure; |
| 2550 | if (xfrm_mark_put(skb, &xp->mark)) | ||
| 2551 | goto nla_put_failure; | ||
| 2482 | upe->hard = !!hard; | 2552 | upe->hard = !!hard; |
| 2483 | 2553 | ||
| 2484 | return nlmsg_end(skb, nlh); | 2554 | return nlmsg_end(skb, nlh); |
| 2485 | 2555 | ||
| 2556 | nla_put_failure: | ||
| 2486 | nlmsg_failure: | 2557 | nlmsg_failure: |
| 2487 | nlmsg_cancel(skb, nlh); | 2558 | nlmsg_cancel(skb, nlh); |
| 2488 | return -EMSGSIZE; | 2559 | return -EMSGSIZE; |
| @@ -2519,6 +2590,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
| 2519 | headlen = sizeof(*id); | 2590 | headlen = sizeof(*id); |
| 2520 | } | 2591 | } |
| 2521 | len += userpolicy_type_attrsize(); | 2592 | len += userpolicy_type_attrsize(); |
| 2593 | len += nla_total_size(sizeof(struct xfrm_mark)); | ||
| 2522 | len += NLMSG_ALIGN(headlen); | 2594 | len += NLMSG_ALIGN(headlen); |
| 2523 | 2595 | ||
| 2524 | skb = nlmsg_new(len, GFP_ATOMIC); | 2596 | skb = nlmsg_new(len, GFP_ATOMIC); |
| @@ -2554,10 +2626,14 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
| 2554 | if (copy_to_user_policy_type(xp->type, skb) < 0) | 2626 | if (copy_to_user_policy_type(xp->type, skb) < 0) |
| 2555 | goto nlmsg_failure; | 2627 | goto nlmsg_failure; |
| 2556 | 2628 | ||
| 2629 | if (xfrm_mark_put(skb, &xp->mark)) | ||
| 2630 | goto nla_put_failure; | ||
| 2631 | |||
| 2557 | nlmsg_end(skb, nlh); | 2632 | nlmsg_end(skb, nlh); |
| 2558 | 2633 | ||
| 2559 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2634 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
| 2560 | 2635 | ||
| 2636 | nla_put_failure: | ||
| 2561 | nlmsg_failure: | 2637 | nlmsg_failure: |
| 2562 | kfree_skb(skb); | 2638 | kfree_skb(skb); |
| 2563 | return -1; | 2639 | return -1; |
| @@ -2601,7 +2677,8 @@ static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_ev | |||
| 2601 | case XFRM_MSG_POLEXPIRE: | 2677 | case XFRM_MSG_POLEXPIRE: |
| 2602 | return xfrm_exp_policy_notify(xp, dir, c); | 2678 | return xfrm_exp_policy_notify(xp, dir, c); |
| 2603 | default: | 2679 | default: |
| 2604 | printk("xfrm_user: Unknown Policy event %d\n", c->event); | 2680 | printk(KERN_NOTICE "xfrm_user: Unknown Policy event %d\n", |
| 2681 | c->event); | ||
| 2605 | } | 2682 | } |
| 2606 | 2683 | ||
| 2607 | return 0; | 2684 | return 0; |
