aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c191
1 files changed, 183 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 82f36d396fca..256745321611 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -48,7 +48,7 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
48 48
49 algp = RTA_DATA(rt); 49 algp = RTA_DATA(rt);
50 50
51 len -= (algp->alg_key_len + 7U) / 8; 51 len -= (algp->alg_key_len + 7U) / 8;
52 if (len < 0) 52 if (len < 0)
53 return -EINVAL; 53 return -EINVAL;
54 54
@@ -1107,7 +1107,7 @@ static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
1107 uctx->ctx_alg = s->ctx_alg; 1107 uctx->ctx_alg = s->ctx_alg;
1108 uctx->ctx_len = s->ctx_len; 1108 uctx->ctx_len = s->ctx_len;
1109 memcpy(uctx + 1, s->ctx_str, s->ctx_len); 1109 memcpy(uctx + 1, s->ctx_str, s->ctx_len);
1110 return 0; 1110 return 0;
1111 1111
1112 rtattr_failure: 1112 rtattr_failure:
1113 return -1; 1113 return -1;
@@ -1273,10 +1273,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1273 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); 1273 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete);
1274 security_xfrm_policy_free(&tmp); 1274 security_xfrm_policy_free(&tmp);
1275 } 1275 }
1276 if (delete)
1277 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1278 AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
1279
1280 if (xp == NULL) 1276 if (xp == NULL)
1281 return -ENOENT; 1277 return -ENOENT;
1282 1278
@@ -1292,8 +1288,14 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1292 MSG_DONTWAIT); 1288 MSG_DONTWAIT);
1293 } 1289 }
1294 } else { 1290 } else {
1295 if ((err = security_xfrm_policy_delete(xp)) != 0) 1291 err = security_xfrm_policy_delete(xp);
1292
1293 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1294 AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
1295
1296 if (err != 0)
1296 goto out; 1297 goto out;
1298
1297 c.data.byid = p->index; 1299 c.data.byid = p->index;
1298 c.event = nlh->nlmsg_type; 1300 c.event = nlh->nlmsg_type;
1299 c.seq = nlh->nlmsg_seq; 1301 c.seq = nlh->nlmsg_seq;
@@ -1632,6 +1634,176 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
1632 return 0; 1634 return 0;
1633} 1635}
1634 1636
1637#ifdef CONFIG_XFRM_MIGRATE
1638static int verify_user_migrate(struct rtattr **xfrma)
1639{
1640 struct rtattr *rt = xfrma[XFRMA_MIGRATE-1];
1641 struct xfrm_user_migrate *um;
1642
1643 if (!rt)
1644 return -EINVAL;
1645
1646 if ((rt->rta_len - sizeof(*rt)) < sizeof(*um))
1647 return -EINVAL;
1648
1649 return 0;
1650}
1651
1652static int copy_from_user_migrate(struct xfrm_migrate *ma,
1653 struct rtattr **xfrma, int *num)
1654{
1655 struct rtattr *rt = xfrma[XFRMA_MIGRATE-1];
1656 struct xfrm_user_migrate *um;
1657 int i, num_migrate;
1658
1659 um = RTA_DATA(rt);
1660 num_migrate = (rt->rta_len - sizeof(*rt)) / sizeof(*um);
1661
1662 if (num_migrate <= 0 || num_migrate > XFRM_MAX_DEPTH)
1663 return -EINVAL;
1664
1665 for (i = 0; i < num_migrate; i++, um++, ma++) {
1666 memcpy(&ma->old_daddr, &um->old_daddr, sizeof(ma->old_daddr));
1667 memcpy(&ma->old_saddr, &um->old_saddr, sizeof(ma->old_saddr));
1668 memcpy(&ma->new_daddr, &um->new_daddr, sizeof(ma->new_daddr));
1669 memcpy(&ma->new_saddr, &um->new_saddr, sizeof(ma->new_saddr));
1670
1671 ma->proto = um->proto;
1672 ma->mode = um->mode;
1673 ma->reqid = um->reqid;
1674
1675 ma->old_family = um->old_family;
1676 ma->new_family = um->new_family;
1677 }
1678
1679 *num = i;
1680 return 0;
1681}
1682
1683static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
1684 struct rtattr **xfrma)
1685{
1686 struct xfrm_userpolicy_id *pi = NLMSG_DATA(nlh);
1687 struct xfrm_migrate m[XFRM_MAX_DEPTH];
1688 u8 type;
1689 int err;
1690 int n = 0;
1691
1692 err = verify_user_migrate((struct rtattr **)xfrma);
1693 if (err)
1694 return err;
1695
1696 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
1697 if (err)
1698 return err;
1699
1700 err = copy_from_user_migrate((struct xfrm_migrate *)m,
1701 (struct rtattr **)xfrma, &n);
1702 if (err)
1703 return err;
1704
1705 if (!n)
1706 return 0;
1707
1708 xfrm_migrate(&pi->sel, pi->dir, type, m, n);
1709
1710 return 0;
1711}
1712#else
1713static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
1714 struct rtattr **xfrma)
1715{
1716 return -ENOPROTOOPT;
1717}
1718#endif
1719
1720#ifdef CONFIG_XFRM_MIGRATE
1721static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)
1722{
1723 struct xfrm_user_migrate um;
1724
1725 memset(&um, 0, sizeof(um));
1726 um.proto = m->proto;
1727 um.mode = m->mode;
1728 um.reqid = m->reqid;
1729 um.old_family = m->old_family;
1730 memcpy(&um.old_daddr, &m->old_daddr, sizeof(um.old_daddr));
1731 memcpy(&um.old_saddr, &m->old_saddr, sizeof(um.old_saddr));
1732 um.new_family = m->new_family;
1733 memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr));
1734 memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr));
1735
1736 RTA_PUT(skb, XFRMA_MIGRATE, sizeof(um), &um);
1737 return 0;
1738
1739rtattr_failure:
1740 return -1;
1741}
1742
1743static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
1744 int num_migrate, struct xfrm_selector *sel,
1745 u8 dir, u8 type)
1746{
1747 struct xfrm_migrate *mp;
1748 struct xfrm_userpolicy_id *pol_id;
1749 struct nlmsghdr *nlh;
1750 unsigned char *b = skb->tail;
1751 int i;
1752
1753 nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id));
1754 pol_id = NLMSG_DATA(nlh);
1755 nlh->nlmsg_flags = 0;
1756
1757 /* copy data from selector, dir, and type to the pol_id */
1758 memset(pol_id, 0, sizeof(*pol_id));
1759 memcpy(&pol_id->sel, sel, sizeof(pol_id->sel));
1760 pol_id->dir = dir;
1761
1762 if (copy_to_user_policy_type(type, skb) < 0)
1763 goto nlmsg_failure;
1764
1765 for (i = 0, mp = m ; i < num_migrate; i++, mp++) {
1766 if (copy_to_user_migrate(mp, skb) < 0)
1767 goto nlmsg_failure;
1768 }
1769
1770 nlh->nlmsg_len = skb->tail - b;
1771 return skb->len;
1772nlmsg_failure:
1773 skb_trim(skb, b - skb->data);
1774 return -1;
1775}
1776
1777static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1778 struct xfrm_migrate *m, int num_migrate)
1779{
1780 struct sk_buff *skb;
1781 size_t len;
1782
1783 len = RTA_SPACE(sizeof(struct xfrm_user_migrate) * num_migrate);
1784 len += NLMSG_SPACE(sizeof(struct xfrm_userpolicy_id));
1785#ifdef CONFIG_XFRM_SUB_POLICY
1786 len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
1787#endif
1788 skb = alloc_skb(len, GFP_ATOMIC);
1789 if (skb == NULL)
1790 return -ENOMEM;
1791
1792 /* build migrate */
1793 if (build_migrate(skb, m, num_migrate, sel, dir, type) < 0)
1794 BUG();
1795
1796 NETLINK_CB(skb).dst_group = XFRMNLGRP_MIGRATE;
1797 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE,
1798 GFP_ATOMIC);
1799}
1800#else
1801static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1802 struct xfrm_migrate *m, int num_migrate)
1803{
1804 return -ENOPROTOOPT;
1805}
1806#endif
1635 1807
1636#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) 1808#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type))
1637 1809
@@ -1653,6 +1825,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
1653 [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), 1825 [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
1654 [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), 1826 [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
1655 [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), 1827 [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report),
1828 [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
1656}; 1829};
1657 1830
1658#undef XMSGSIZE 1831#undef XMSGSIZE
@@ -1679,6 +1852,7 @@ static struct xfrm_link {
1679 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, 1852 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
1680 [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = { .doit = xfrm_new_ae }, 1853 [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = { .doit = xfrm_new_ae },
1681 [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, 1854 [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae },
1855 [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate },
1682}; 1856};
1683 1857
1684static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 1858static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
@@ -2285,6 +2459,7 @@ static struct xfrm_mgr netlink_mgr = {
2285 .compile_policy = xfrm_compile_policy, 2459 .compile_policy = xfrm_compile_policy,
2286 .notify_policy = xfrm_send_policy_notify, 2460 .notify_policy = xfrm_send_policy_notify,
2287 .report = xfrm_send_report, 2461 .report = xfrm_send_report,
2462 .migrate = xfrm_send_migrate,
2288}; 2463};
2289 2464
2290static int __init xfrm_user_init(void) 2465static int __init xfrm_user_init(void)
@@ -2294,7 +2469,7 @@ static int __init xfrm_user_init(void)
2294 printk(KERN_INFO "Initializing XFRM netlink socket\n"); 2469 printk(KERN_INFO "Initializing XFRM netlink socket\n");
2295 2470
2296 nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, 2471 nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
2297 xfrm_netlink_rcv, THIS_MODULE); 2472 xfrm_netlink_rcv, THIS_MODULE);
2298 if (nlsk == NULL) 2473 if (nlsk == NULL)
2299 return -ENOMEM; 2474 return -ENOMEM;
2300 rcu_assign_pointer(xfrm_nl, nlsk); 2475 rcu_assign_pointer(xfrm_nl, nlsk);