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.c156
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
579static 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
579static int dump_one_state(struct xfrm_state *x, int count, void *ptr) 600static 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);
631out: 641out:
632 sp->this_idx++; 642 sp->this_idx++;
633 return 0; 643 return 0;
634 644
635rtattr_failure: 645nla_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
1202rtattr_failure:
1203 return -1;
1204}
1205
1206static 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
1224static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb) 1211static 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
1241static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) 1228static 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
1252rtattr_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), &ltime);
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
1478rtattr_failure: 1450nla_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
1846rtattr_failure:
1847 return -1;
1848} 1816}
1849 1817
1850static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, 1818static 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
2171nlmsg_failure: 2145nla_put_failure:
2172rtattr_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
2416nlmsg_failure: 2395nlmsg_failure:
2417rtattr_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
2490rtattr_failure: 2468nla_put_failure:
2491 nlmsg_cancel(skb, nlh); 2469 nlmsg_cancel(skb, nlh);
2492 return -EMSGSIZE; 2470 return -EMSGSIZE;
2493} 2471}