diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 156 |
1 files changed, 67 insertions, 89 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 249940eaced8..24a97b1179f8 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -576,6 +576,27 @@ struct xfrm_dump_info { | |||
576 | int this_idx; | 576 | int this_idx; |
577 | }; | 577 | }; |
578 | 578 | ||
579 | static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) | ||
580 | { | ||
581 | int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len; | ||
582 | struct xfrm_user_sec_ctx *uctx; | ||
583 | struct nlattr *attr; | ||
584 | |||
585 | attr = nla_reserve(skb, XFRMA_SEC_CTX, ctx_size); | ||
586 | if (attr == NULL) | ||
587 | return -EMSGSIZE; | ||
588 | |||
589 | uctx = nla_data(attr); | ||
590 | uctx->exttype = XFRMA_SEC_CTX; | ||
591 | uctx->len = ctx_size; | ||
592 | uctx->ctx_doi = s->ctx_doi; | ||
593 | uctx->ctx_alg = s->ctx_alg; | ||
594 | uctx->ctx_len = s->ctx_len; | ||
595 | memcpy(uctx + 1, s->ctx_str, s->ctx_len); | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
579 | static int dump_one_state(struct xfrm_state *x, int count, void *ptr) | 600 | static int dump_one_state(struct xfrm_state *x, int count, void *ptr) |
580 | { | 601 | { |
581 | struct xfrm_dump_info *sp = ptr; | 602 | struct xfrm_dump_info *sp = ptr; |
@@ -596,43 +617,32 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr) | |||
596 | copy_to_user_state(x, p); | 617 | copy_to_user_state(x, p); |
597 | 618 | ||
598 | if (x->aalg) | 619 | if (x->aalg) |
599 | RTA_PUT(skb, XFRMA_ALG_AUTH, | 620 | NLA_PUT(skb, XFRMA_ALG_AUTH, |
600 | sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); | 621 | sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); |
601 | if (x->ealg) | 622 | if (x->ealg) |
602 | RTA_PUT(skb, XFRMA_ALG_CRYPT, | 623 | NLA_PUT(skb, XFRMA_ALG_CRYPT, |
603 | sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); | 624 | sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); |
604 | if (x->calg) | 625 | if (x->calg) |
605 | RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); | 626 | NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); |
606 | 627 | ||
607 | if (x->encap) | 628 | if (x->encap) |
608 | RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); | 629 | NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); |
609 | 630 | ||
610 | if (x->security) { | 631 | if (x->security && copy_sec_ctx(x->security, skb) < 0) |
611 | int ctx_size = sizeof(struct xfrm_sec_ctx) + | 632 | goto nla_put_failure; |
612 | x->security->ctx_len; | ||
613 | struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size); | ||
614 | struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt); | ||
615 | |||
616 | uctx->exttype = XFRMA_SEC_CTX; | ||
617 | uctx->len = ctx_size; | ||
618 | uctx->ctx_doi = x->security->ctx_doi; | ||
619 | uctx->ctx_alg = x->security->ctx_alg; | ||
620 | uctx->ctx_len = x->security->ctx_len; | ||
621 | memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len); | ||
622 | } | ||
623 | 633 | ||
624 | if (x->coaddr) | 634 | if (x->coaddr) |
625 | RTA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr); | 635 | NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr); |
626 | 636 | ||
627 | if (x->lastused) | 637 | if (x->lastused) |
628 | RTA_PUT(skb, XFRMA_LASTUSED, sizeof(x->lastused), &x->lastused); | 638 | NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused); |
629 | 639 | ||
630 | nlmsg_end(skb, nlh); | 640 | nlmsg_end(skb, nlh); |
631 | out: | 641 | out: |
632 | sp->this_idx++; | 642 | sp->this_idx++; |
633 | return 0; | 643 | return 0; |
634 | 644 | ||
635 | rtattr_failure: | 645 | nla_put_failure: |
636 | nlmsg_cancel(skb, nlh); | 646 | nlmsg_cancel(skb, nlh); |
637 | return -EMSGSIZE; | 647 | return -EMSGSIZE; |
638 | } | 648 | } |
@@ -1193,32 +1203,9 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) | |||
1193 | up->ealgos = kp->ealgos; | 1203 | up->ealgos = kp->ealgos; |
1194 | up->calgos = kp->calgos; | 1204 | up->calgos = kp->calgos; |
1195 | } | 1205 | } |
1196 | RTA_PUT(skb, XFRMA_TMPL, | ||
1197 | (sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr), | ||
1198 | vec); | ||
1199 | |||
1200 | return 0; | ||
1201 | |||
1202 | rtattr_failure: | ||
1203 | return -1; | ||
1204 | } | ||
1205 | |||
1206 | static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) | ||
1207 | { | ||
1208 | int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len; | ||
1209 | struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size); | ||
1210 | struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt); | ||
1211 | |||
1212 | uctx->exttype = XFRMA_SEC_CTX; | ||
1213 | uctx->len = ctx_size; | ||
1214 | uctx->ctx_doi = s->ctx_doi; | ||
1215 | uctx->ctx_alg = s->ctx_alg; | ||
1216 | uctx->ctx_len = s->ctx_len; | ||
1217 | memcpy(uctx + 1, s->ctx_str, s->ctx_len); | ||
1218 | return 0; | ||
1219 | 1206 | ||
1220 | rtattr_failure: | 1207 | return nla_put(skb, XFRMA_TMPL, |
1221 | return -1; | 1208 | sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr, vec); |
1222 | } | 1209 | } |
1223 | 1210 | ||
1224 | static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb) | 1211 | static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb) |
@@ -1240,17 +1227,11 @@ static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *s | |||
1240 | #ifdef CONFIG_XFRM_SUB_POLICY | 1227 | #ifdef CONFIG_XFRM_SUB_POLICY |
1241 | static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) | 1228 | static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) |
1242 | { | 1229 | { |
1243 | struct xfrm_userpolicy_type upt; | 1230 | struct xfrm_userpolicy_type upt = { |
1231 | .type = type, | ||
1232 | }; | ||
1244 | 1233 | ||
1245 | memset(&upt, 0, sizeof(upt)); | 1234 | return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); |
1246 | upt.type = type; | ||
1247 | |||
1248 | RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); | ||
1249 | |||
1250 | return 0; | ||
1251 | |||
1252 | rtattr_failure: | ||
1253 | return -1; | ||
1254 | } | 1235 | } |
1255 | 1236 | ||
1256 | #else | 1237 | #else |
@@ -1440,7 +1421,6 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve | |||
1440 | { | 1421 | { |
1441 | struct xfrm_aevent_id *id; | 1422 | struct xfrm_aevent_id *id; |
1442 | struct nlmsghdr *nlh; | 1423 | struct nlmsghdr *nlh; |
1443 | struct xfrm_lifetime_cur ltime; | ||
1444 | 1424 | ||
1445 | nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0); | 1425 | nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0); |
1446 | if (nlh == NULL) | 1426 | if (nlh == NULL) |
@@ -1455,27 +1435,19 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve | |||
1455 | id->reqid = x->props.reqid; | 1435 | id->reqid = x->props.reqid; |
1456 | id->flags = c->data.aevent; | 1436 | id->flags = c->data.aevent; |
1457 | 1437 | ||
1458 | RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay); | 1438 | NLA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay); |
1459 | 1439 | NLA_PUT(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft); | |
1460 | ltime.bytes = x->curlft.bytes; | ||
1461 | ltime.packets = x->curlft.packets; | ||
1462 | ltime.add_time = x->curlft.add_time; | ||
1463 | ltime.use_time = x->curlft.use_time; | ||
1464 | |||
1465 | RTA_PUT(skb, XFRMA_LTIME_VAL, sizeof(struct xfrm_lifetime_cur), <ime); | ||
1466 | 1440 | ||
1467 | if (id->flags&XFRM_AE_RTHR) { | 1441 | if (id->flags & XFRM_AE_RTHR) |
1468 | RTA_PUT(skb,XFRMA_REPLAY_THRESH,sizeof(u32),&x->replay_maxdiff); | 1442 | NLA_PUT_U32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff); |
1469 | } | ||
1470 | 1443 | ||
1471 | if (id->flags&XFRM_AE_ETHR) { | 1444 | if (id->flags & XFRM_AE_ETHR) |
1472 | u32 etimer = x->replay_maxage*10/HZ; | 1445 | NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH, |
1473 | RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer); | 1446 | x->replay_maxage * 10 / HZ); |
1474 | } | ||
1475 | 1447 | ||
1476 | return nlmsg_end(skb, nlh); | 1448 | return nlmsg_end(skb, nlh); |
1477 | 1449 | ||
1478 | rtattr_failure: | 1450 | nla_put_failure: |
1479 | nlmsg_cancel(skb, nlh); | 1451 | nlmsg_cancel(skb, nlh); |
1480 | return -EMSGSIZE; | 1452 | return -EMSGSIZE; |
1481 | } | 1453 | } |
@@ -1840,11 +1812,7 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb) | |||
1840 | memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr)); | 1812 | memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr)); |
1841 | memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr)); | 1813 | memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr)); |
1842 | 1814 | ||
1843 | RTA_PUT(skb, XFRMA_MIGRATE, sizeof(um), &um); | 1815 | return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um); |
1844 | return 0; | ||
1845 | |||
1846 | rtattr_failure: | ||
1847 | return -1; | ||
1848 | } | 1816 | } |
1849 | 1817 | ||
1850 | static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, | 1818 | static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, |
@@ -2137,39 +2105,44 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | |||
2137 | 2105 | ||
2138 | nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); | 2106 | nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); |
2139 | if (nlh == NULL) | 2107 | if (nlh == NULL) |
2140 | goto nlmsg_failure; | 2108 | goto nla_put_failure; |
2141 | 2109 | ||
2142 | p = nlmsg_data(nlh); | 2110 | p = nlmsg_data(nlh); |
2143 | if (c->event == XFRM_MSG_DELSA) { | 2111 | if (c->event == XFRM_MSG_DELSA) { |
2112 | struct nlattr *attr; | ||
2113 | |||
2144 | id = nlmsg_data(nlh); | 2114 | id = nlmsg_data(nlh); |
2145 | memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr)); | 2115 | memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr)); |
2146 | id->spi = x->id.spi; | 2116 | id->spi = x->id.spi; |
2147 | id->family = x->props.family; | 2117 | id->family = x->props.family; |
2148 | id->proto = x->id.proto; | 2118 | id->proto = x->id.proto; |
2149 | 2119 | ||
2150 | p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p))); | 2120 | attr = nla_reserve(skb, XFRMA_SA, sizeof(*p)); |
2121 | if (attr == NULL) | ||
2122 | goto nla_put_failure; | ||
2123 | |||
2124 | p = nla_data(attr); | ||
2151 | } | 2125 | } |
2152 | 2126 | ||
2153 | copy_to_user_state(x, p); | 2127 | copy_to_user_state(x, p); |
2154 | 2128 | ||
2155 | if (x->aalg) | 2129 | if (x->aalg) |
2156 | RTA_PUT(skb, XFRMA_ALG_AUTH, | 2130 | NLA_PUT(skb, XFRMA_ALG_AUTH, |
2157 | sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); | 2131 | sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); |
2158 | if (x->ealg) | 2132 | if (x->ealg) |
2159 | RTA_PUT(skb, XFRMA_ALG_CRYPT, | 2133 | NLA_PUT(skb, XFRMA_ALG_CRYPT, |
2160 | sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); | 2134 | sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); |
2161 | if (x->calg) | 2135 | if (x->calg) |
2162 | RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); | 2136 | NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); |
2163 | 2137 | ||
2164 | if (x->encap) | 2138 | if (x->encap) |
2165 | RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); | 2139 | NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); |
2166 | 2140 | ||
2167 | nlmsg_end(skb, nlh); | 2141 | nlmsg_end(skb, nlh); |
2168 | 2142 | ||
2169 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); | 2143 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); |
2170 | 2144 | ||
2171 | nlmsg_failure: | 2145 | nla_put_failure: |
2172 | rtattr_failure: | ||
2173 | kfree_skb(skb); | 2146 | kfree_skb(skb); |
2174 | return -1; | 2147 | return -1; |
2175 | } | 2148 | } |
@@ -2392,6 +2365,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2392 | 2365 | ||
2393 | p = nlmsg_data(nlh); | 2366 | p = nlmsg_data(nlh); |
2394 | if (c->event == XFRM_MSG_DELPOLICY) { | 2367 | if (c->event == XFRM_MSG_DELPOLICY) { |
2368 | struct nlattr *attr; | ||
2369 | |||
2395 | id = nlmsg_data(nlh); | 2370 | id = nlmsg_data(nlh); |
2396 | memset(id, 0, sizeof(*id)); | 2371 | memset(id, 0, sizeof(*id)); |
2397 | id->dir = dir; | 2372 | id->dir = dir; |
@@ -2400,7 +2375,11 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2400 | else | 2375 | else |
2401 | memcpy(&id->sel, &xp->selector, sizeof(id->sel)); | 2376 | memcpy(&id->sel, &xp->selector, sizeof(id->sel)); |
2402 | 2377 | ||
2403 | p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p))); | 2378 | attr = nla_reserve(skb, XFRMA_POLICY, sizeof(*p)); |
2379 | if (attr == NULL) | ||
2380 | goto nlmsg_failure; | ||
2381 | |||
2382 | p = nla_data(attr); | ||
2404 | } | 2383 | } |
2405 | 2384 | ||
2406 | copy_to_user_policy(xp, p, dir); | 2385 | copy_to_user_policy(xp, p, dir); |
@@ -2414,7 +2393,6 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2414 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2393 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
2415 | 2394 | ||
2416 | nlmsg_failure: | 2395 | nlmsg_failure: |
2417 | rtattr_failure: | ||
2418 | kfree_skb(skb); | 2396 | kfree_skb(skb); |
2419 | return -1; | 2397 | return -1; |
2420 | } | 2398 | } |
@@ -2483,11 +2461,11 @@ static int build_report(struct sk_buff *skb, u8 proto, | |||
2483 | memcpy(&ur->sel, sel, sizeof(ur->sel)); | 2461 | memcpy(&ur->sel, sel, sizeof(ur->sel)); |
2484 | 2462 | ||
2485 | if (addr) | 2463 | if (addr) |
2486 | RTA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr); | 2464 | NLA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr); |
2487 | 2465 | ||
2488 | return nlmsg_end(skb, nlh); | 2466 | return nlmsg_end(skb, nlh); |
2489 | 2467 | ||
2490 | rtattr_failure: | 2468 | nla_put_failure: |
2491 | nlmsg_cancel(skb, nlh); | 2469 | nlmsg_cancel(skb, nlh); |
2492 | return -EMSGSIZE; | 2470 | return -EMSGSIZE; |
2493 | } | 2471 | } |