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.c125
1 files changed, 31 insertions, 94 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 9103af02473c..1371a0ae0606 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -42,19 +42,12 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
42{ 42{
43 struct rtattr *rt = xfrma[type - 1]; 43 struct rtattr *rt = xfrma[type - 1];
44 struct xfrm_algo *algp; 44 struct xfrm_algo *algp;
45 int len;
46 45
47 if (!rt) 46 if (!rt)
48 return 0; 47 return 0;
49 48
50 len = (rt->rta_len - sizeof(*rt)) - sizeof(*algp);
51 if (len < 0)
52 return -EINVAL;
53
54 algp = RTA_DATA(rt); 49 algp = RTA_DATA(rt);
55 50 if (RTA_PAYLOAD(rt) < alg_len(algp))
56 len -= (algp->alg_key_len + 7U) / 8;
57 if (len < 0)
58 return -EINVAL; 51 return -EINVAL;
59 52
60 switch (type) { 53 switch (type) {
@@ -82,55 +75,25 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
82 return 0; 75 return 0;
83} 76}
84 77
85static int verify_encap_tmpl(struct rtattr **xfrma) 78static void verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
86{
87 struct rtattr *rt = xfrma[XFRMA_ENCAP - 1];
88 struct xfrm_encap_tmpl *encap;
89
90 if (!rt)
91 return 0;
92
93 if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap))
94 return -EINVAL;
95
96 return 0;
97}
98
99static int verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
100 xfrm_address_t **addrp) 79 xfrm_address_t **addrp)
101{ 80{
102 struct rtattr *rt = xfrma[type - 1]; 81 struct rtattr *rt = xfrma[type - 1];
103 82
104 if (!rt) 83 if (rt && addrp)
105 return 0;
106
107 if ((rt->rta_len - sizeof(*rt)) < sizeof(**addrp))
108 return -EINVAL;
109
110 if (addrp)
111 *addrp = RTA_DATA(rt); 84 *addrp = RTA_DATA(rt);
112
113 return 0;
114} 85}
115 86
116static inline int verify_sec_ctx_len(struct rtattr **xfrma) 87static inline int verify_sec_ctx_len(struct rtattr **xfrma)
117{ 88{
118 struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1]; 89 struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
119 struct xfrm_user_sec_ctx *uctx; 90 struct xfrm_user_sec_ctx *uctx;
120 int len = 0;
121 91
122 if (!rt) 92 if (!rt)
123 return 0; 93 return 0;
124 94
125 if (rt->rta_len < sizeof(*uctx))
126 return -EINVAL;
127
128 uctx = RTA_DATA(rt); 95 uctx = RTA_DATA(rt);
129 96 if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
130 len += sizeof(struct xfrm_user_sec_ctx);
131 len += uctx->ctx_len;
132
133 if (uctx->len != len)
134 return -EINVAL; 97 return -EINVAL;
135 98
136 return 0; 99 return 0;
@@ -205,12 +168,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
205 goto out; 168 goto out;
206 if ((err = verify_one_alg(xfrma, XFRMA_ALG_COMP))) 169 if ((err = verify_one_alg(xfrma, XFRMA_ALG_COMP)))
207 goto out; 170 goto out;
208 if ((err = verify_encap_tmpl(xfrma)))
209 goto out;
210 if ((err = verify_sec_ctx_len(xfrma))) 171 if ((err = verify_sec_ctx_len(xfrma)))
211 goto out; 172 goto out;
212 if ((err = verify_one_addr(xfrma, XFRMA_COADDR, NULL)))
213 goto out;
214 173
215 err = -EINVAL; 174 err = -EINVAL;
216 switch (p->mode) { 175 switch (p->mode) {
@@ -339,9 +298,8 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
339 * somehow made shareable and move it to xfrm_state.c - JHS 298 * somehow made shareable and move it to xfrm_state.c - JHS
340 * 299 *
341*/ 300*/
342static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma) 301static void xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
343{ 302{
344 int err = - EINVAL;
345 struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1]; 303 struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
346 struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1]; 304 struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
347 struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH-1]; 305 struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH-1];
@@ -349,8 +307,6 @@ static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
349 307
350 if (rp) { 308 if (rp) {
351 struct xfrm_replay_state *replay; 309 struct xfrm_replay_state *replay;
352 if (RTA_PAYLOAD(rp) < sizeof(*replay))
353 goto error;
354 replay = RTA_DATA(rp); 310 replay = RTA_DATA(rp);
355 memcpy(&x->replay, replay, sizeof(*replay)); 311 memcpy(&x->replay, replay, sizeof(*replay));
356 memcpy(&x->preplay, replay, sizeof(*replay)); 312 memcpy(&x->preplay, replay, sizeof(*replay));
@@ -358,8 +314,6 @@ static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
358 314
359 if (lt) { 315 if (lt) {
360 struct xfrm_lifetime_cur *ltime; 316 struct xfrm_lifetime_cur *ltime;
361 if (RTA_PAYLOAD(lt) < sizeof(*ltime))
362 goto error;
363 ltime = RTA_DATA(lt); 317 ltime = RTA_DATA(lt);
364 x->curlft.bytes = ltime->bytes; 318 x->curlft.bytes = ltime->bytes;
365 x->curlft.packets = ltime->packets; 319 x->curlft.packets = ltime->packets;
@@ -367,21 +321,11 @@ static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
367 x->curlft.use_time = ltime->use_time; 321 x->curlft.use_time = ltime->use_time;
368 } 322 }
369 323
370 if (et) { 324 if (et)
371 if (RTA_PAYLOAD(et) < sizeof(u32))
372 goto error;
373 x->replay_maxage = *(u32*)RTA_DATA(et); 325 x->replay_maxage = *(u32*)RTA_DATA(et);
374 }
375 326
376 if (rt) { 327 if (rt)
377 if (RTA_PAYLOAD(rt) < sizeof(u32))
378 goto error;
379 x->replay_maxdiff = *(u32*)RTA_DATA(rt); 328 x->replay_maxdiff = *(u32*)RTA_DATA(rt);
380 }
381
382 return 0;
383error:
384 return err;
385} 329}
386 330
387static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, 331static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
@@ -429,9 +373,7 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
429 373
430 /* override default values from above */ 374 /* override default values from above */
431 375
432 err = xfrm_update_ae_params(x, (struct rtattr **)xfrma); 376 xfrm_update_ae_params(x, (struct rtattr **)xfrma);
433 if (err < 0)
434 goto error;
435 377
436 return x; 378 return x;
437 379
@@ -497,10 +439,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
497 } else { 439 } else {
498 xfrm_address_t *saddr = NULL; 440 xfrm_address_t *saddr = NULL;
499 441
500 err = verify_one_addr(xfrma, XFRMA_SRCADDR, &saddr); 442 verify_one_addr(xfrma, XFRMA_SRCADDR, &saddr);
501 if (err)
502 goto out;
503
504 if (!saddr) { 443 if (!saddr) {
505 err = -EINVAL; 444 err = -EINVAL;
506 goto out; 445 goto out;
@@ -1072,9 +1011,6 @@ static int copy_from_user_policy_type(u8 *tp, struct rtattr **xfrma)
1072 int err; 1011 int err;
1073 1012
1074 if (rt) { 1013 if (rt) {
1075 if (rt->rta_len < sizeof(*upt))
1076 return -EINVAL;
1077
1078 upt = RTA_DATA(rt); 1014 upt = RTA_DATA(rt);
1079 type = upt->type; 1015 type = upt->type;
1080 } 1016 }
@@ -1537,10 +1473,8 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
1537 goto out; 1473 goto out;
1538 1474
1539 spin_lock_bh(&x->lock); 1475 spin_lock_bh(&x->lock);
1540 err = xfrm_update_ae_params(x, xfrma); 1476 xfrm_update_ae_params(x, xfrma);
1541 spin_unlock_bh(&x->lock); 1477 spin_unlock_bh(&x->lock);
1542 if (err < 0)
1543 goto out;
1544 1478
1545 c.event = nlh->nlmsg_type; 1479 c.event = nlh->nlmsg_type;
1546 c.seq = nlh->nlmsg_seq; 1480 c.seq = nlh->nlmsg_seq;
@@ -1726,20 +1660,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
1726} 1660}
1727 1661
1728#ifdef CONFIG_XFRM_MIGRATE 1662#ifdef CONFIG_XFRM_MIGRATE
1729static int verify_user_migrate(struct rtattr **xfrma)
1730{
1731 struct rtattr *rt = xfrma[XFRMA_MIGRATE-1];
1732 struct xfrm_user_migrate *um;
1733
1734 if (!rt)
1735 return -EINVAL;
1736
1737 if ((rt->rta_len - sizeof(*rt)) < sizeof(*um))
1738 return -EINVAL;
1739
1740 return 0;
1741}
1742
1743static int copy_from_user_migrate(struct xfrm_migrate *ma, 1663static int copy_from_user_migrate(struct xfrm_migrate *ma,
1744 struct rtattr **xfrma, int *num) 1664 struct rtattr **xfrma, int *num)
1745{ 1665{
@@ -1780,9 +1700,8 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
1780 int err; 1700 int err;
1781 int n = 0; 1701 int n = 0;
1782 1702
1783 err = verify_user_migrate((struct rtattr **)xfrma); 1703 if (xfrma[XFRMA_MIGRATE-1] == NULL)
1784 if (err) 1704 return -EINVAL;
1785 return err;
1786 1705
1787 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); 1706 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
1788 if (err) 1707 if (err)
@@ -1917,6 +1836,23 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
1917 1836
1918#undef XMSGSIZE 1837#undef XMSGSIZE
1919 1838
1839static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
1840 [XFRMA_ALG_AUTH] = { .len = sizeof(struct xfrm_algo) },
1841 [XFRMA_ALG_CRYPT] = { .len = sizeof(struct xfrm_algo) },
1842 [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
1843 [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) },
1844 [XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) },
1845 [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) },
1846 [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) },
1847 [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) },
1848 [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
1849 [XFRMA_ETIMER_THRESH] = { .type = NLA_U32 },
1850 [XFRMA_SRCADDR] = { .len = sizeof(xfrm_address_t) },
1851 [XFRMA_COADDR] = { .len = sizeof(xfrm_address_t) },
1852 [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)},
1853 [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
1854};
1855
1920static struct xfrm_link { 1856static struct xfrm_link {
1921 int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **); 1857 int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **);
1922 int (*dump)(struct sk_buff *, struct netlink_callback *); 1858 int (*dump)(struct sk_buff *, struct netlink_callback *);
@@ -1972,7 +1908,8 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1972 1908
1973 /* FIXME: Temporary hack, nlmsg_parse() starts at xfrma[1], old code 1909 /* FIXME: Temporary hack, nlmsg_parse() starts at xfrma[1], old code
1974 * expects first attribute at xfrma[0] */ 1910 * expects first attribute at xfrma[0] */
1975 err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma-1, XFRMA_MAX, NULL); 1911 err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma-1, XFRMA_MAX,
1912 xfrma_policy);
1976 if (err < 0) 1913 if (err < 0)
1977 return err; 1914 return err;
1978 1915