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.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 41f3d51ffc33..b5f8ab71aa54 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -87,6 +87,22 @@ static int verify_encap_tmpl(struct rtattr **xfrma)
87 return 0; 87 return 0;
88} 88}
89 89
90static int verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
91 xfrm_address_t **addrp)
92{
93 struct rtattr *rt = xfrma[type - 1];
94
95 if (!rt)
96 return 0;
97
98 if ((rt->rta_len - sizeof(*rt)) < sizeof(**addrp))
99 return -EINVAL;
100
101 if (addrp)
102 *addrp = RTA_DATA(rt);
103
104 return 0;
105}
90 106
91static inline int verify_sec_ctx_len(struct rtattr **xfrma) 107static inline int verify_sec_ctx_len(struct rtattr **xfrma)
92{ 108{
@@ -418,16 +434,48 @@ out:
418 return err; 434 return err;
419} 435}
420 436
437static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
438 struct rtattr **xfrma,
439 int *errp)
440{
441 struct xfrm_state *x = NULL;
442 int err;
443
444 if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) {
445 err = -ESRCH;
446 x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
447 } else {
448 xfrm_address_t *saddr = NULL;
449
450 err = verify_one_addr(xfrma, XFRMA_SRCADDR, &saddr);
451 if (err)
452 goto out;
453
454 if (!saddr) {
455 err = -EINVAL;
456 goto out;
457 }
458
459 x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto,
460 p->family);
461 }
462
463 out:
464 if (!x && errp)
465 *errp = err;
466 return x;
467}
468
421static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 469static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
422{ 470{
423 struct xfrm_state *x; 471 struct xfrm_state *x;
424 int err; 472 int err = -ESRCH;
425 struct km_event c; 473 struct km_event c;
426 struct xfrm_usersa_id *p = NLMSG_DATA(nlh); 474 struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
427 475
428 x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); 476 x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err);
429 if (x == NULL) 477 if (x == NULL)
430 return -ESRCH; 478 return err;
431 479
432 if ((err = security_xfrm_state_delete(x)) != 0) 480 if ((err = security_xfrm_state_delete(x)) != 0)
433 goto out; 481 goto out;
@@ -578,10 +626,9 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
578 struct xfrm_usersa_id *p = NLMSG_DATA(nlh); 626 struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
579 struct xfrm_state *x; 627 struct xfrm_state *x;
580 struct sk_buff *resp_skb; 628 struct sk_buff *resp_skb;
581 int err; 629 int err = -ESRCH;
582 630
583 x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); 631 x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err);
584 err = -ESRCH;
585 if (x == NULL) 632 if (x == NULL)
586 goto out_noput; 633 goto out_noput;
587 634