diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 146 |
1 files changed, 86 insertions, 60 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e75d8e47f35c..421f98444335 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -123,9 +123,21 @@ static inline int verify_replay(struct xfrm_usersa_info *p, | |||
123 | struct nlattr **attrs) | 123 | struct nlattr **attrs) |
124 | { | 124 | { |
125 | struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; | 125 | struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; |
126 | struct xfrm_replay_state_esn *rs; | ||
126 | 127 | ||
127 | if ((p->flags & XFRM_STATE_ESN) && !rt) | 128 | if (p->flags & XFRM_STATE_ESN) { |
128 | return -EINVAL; | 129 | if (!rt) |
130 | return -EINVAL; | ||
131 | |||
132 | rs = nla_data(rt); | ||
133 | |||
134 | if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) | ||
135 | return -EINVAL; | ||
136 | |||
137 | if (nla_len(rt) < xfrm_replay_state_esn_len(rs) && | ||
138 | nla_len(rt) != sizeof(*rs)) | ||
139 | return -EINVAL; | ||
140 | } | ||
129 | 141 | ||
130 | if (!rt) | 142 | if (!rt) |
131 | return 0; | 143 | return 0; |
@@ -370,14 +382,15 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es | |||
370 | struct nlattr *rp) | 382 | struct nlattr *rp) |
371 | { | 383 | { |
372 | struct xfrm_replay_state_esn *up; | 384 | struct xfrm_replay_state_esn *up; |
385 | int ulen; | ||
373 | 386 | ||
374 | if (!replay_esn || !rp) | 387 | if (!replay_esn || !rp) |
375 | return 0; | 388 | return 0; |
376 | 389 | ||
377 | up = nla_data(rp); | 390 | up = nla_data(rp); |
391 | ulen = xfrm_replay_state_esn_len(up); | ||
378 | 392 | ||
379 | if (xfrm_replay_state_esn_len(replay_esn) != | 393 | if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen) |
380 | xfrm_replay_state_esn_len(up)) | ||
381 | return -EINVAL; | 394 | return -EINVAL; |
382 | 395 | ||
383 | return 0; | 396 | return 0; |
@@ -388,22 +401,28 @@ static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn | |||
388 | struct nlattr *rta) | 401 | struct nlattr *rta) |
389 | { | 402 | { |
390 | struct xfrm_replay_state_esn *p, *pp, *up; | 403 | struct xfrm_replay_state_esn *p, *pp, *up; |
404 | int klen, ulen; | ||
391 | 405 | ||
392 | if (!rta) | 406 | if (!rta) |
393 | return 0; | 407 | return 0; |
394 | 408 | ||
395 | up = nla_data(rta); | 409 | up = nla_data(rta); |
410 | klen = xfrm_replay_state_esn_len(up); | ||
411 | ulen = nla_len(rta) >= klen ? klen : sizeof(*up); | ||
396 | 412 | ||
397 | p = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL); | 413 | p = kzalloc(klen, GFP_KERNEL); |
398 | if (!p) | 414 | if (!p) |
399 | return -ENOMEM; | 415 | return -ENOMEM; |
400 | 416 | ||
401 | pp = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL); | 417 | pp = kzalloc(klen, GFP_KERNEL); |
402 | if (!pp) { | 418 | if (!pp) { |
403 | kfree(p); | 419 | kfree(p); |
404 | return -ENOMEM; | 420 | return -ENOMEM; |
405 | } | 421 | } |
406 | 422 | ||
423 | memcpy(p, up, ulen); | ||
424 | memcpy(pp, up, ulen); | ||
425 | |||
407 | *replay_esn = p; | 426 | *replay_esn = p; |
408 | *preplay_esn = pp; | 427 | *preplay_esn = pp; |
409 | 428 | ||
@@ -442,10 +461,11 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * | |||
442 | * somehow made shareable and move it to xfrm_state.c - JHS | 461 | * somehow made shareable and move it to xfrm_state.c - JHS |
443 | * | 462 | * |
444 | */ | 463 | */ |
445 | static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs) | 464 | static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs, |
465 | int update_esn) | ||
446 | { | 466 | { |
447 | struct nlattr *rp = attrs[XFRMA_REPLAY_VAL]; | 467 | struct nlattr *rp = attrs[XFRMA_REPLAY_VAL]; |
448 | struct nlattr *re = attrs[XFRMA_REPLAY_ESN_VAL]; | 468 | struct nlattr *re = update_esn ? attrs[XFRMA_REPLAY_ESN_VAL] : NULL; |
449 | struct nlattr *lt = attrs[XFRMA_LTIME_VAL]; | 469 | struct nlattr *lt = attrs[XFRMA_LTIME_VAL]; |
450 | struct nlattr *et = attrs[XFRMA_ETIMER_THRESH]; | 470 | struct nlattr *et = attrs[XFRMA_ETIMER_THRESH]; |
451 | struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH]; | 471 | struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH]; |
@@ -555,7 +575,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
555 | goto error; | 575 | goto error; |
556 | 576 | ||
557 | /* override default values from above */ | 577 | /* override default values from above */ |
558 | xfrm_update_ae_params(x, attrs); | 578 | xfrm_update_ae_params(x, attrs, 0); |
559 | 579 | ||
560 | return x; | 580 | return x; |
561 | 581 | ||
@@ -575,7 +595,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
575 | struct xfrm_state *x; | 595 | struct xfrm_state *x; |
576 | int err; | 596 | int err; |
577 | struct km_event c; | 597 | struct km_event c; |
578 | uid_t loginuid = audit_get_loginuid(current); | 598 | kuid_t loginuid = audit_get_loginuid(current); |
579 | u32 sessionid = audit_get_sessionid(current); | 599 | u32 sessionid = audit_get_sessionid(current); |
580 | u32 sid; | 600 | u32 sid; |
581 | 601 | ||
@@ -603,7 +623,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
603 | } | 623 | } |
604 | 624 | ||
605 | c.seq = nlh->nlmsg_seq; | 625 | c.seq = nlh->nlmsg_seq; |
606 | c.pid = nlh->nlmsg_pid; | 626 | c.portid = nlh->nlmsg_pid; |
607 | c.event = nlh->nlmsg_type; | 627 | c.event = nlh->nlmsg_type; |
608 | 628 | ||
609 | km_state_notify(x, &c); | 629 | km_state_notify(x, &c); |
@@ -654,7 +674,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
654 | int err = -ESRCH; | 674 | int err = -ESRCH; |
655 | struct km_event c; | 675 | struct km_event c; |
656 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 676 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
657 | uid_t loginuid = audit_get_loginuid(current); | 677 | kuid_t loginuid = audit_get_loginuid(current); |
658 | u32 sessionid = audit_get_sessionid(current); | 678 | u32 sessionid = audit_get_sessionid(current); |
659 | u32 sid; | 679 | u32 sid; |
660 | 680 | ||
@@ -676,7 +696,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
676 | goto out; | 696 | goto out; |
677 | 697 | ||
678 | c.seq = nlh->nlmsg_seq; | 698 | c.seq = nlh->nlmsg_seq; |
679 | c.pid = nlh->nlmsg_pid; | 699 | c.portid = nlh->nlmsg_pid; |
680 | c.event = nlh->nlmsg_type; | 700 | c.event = nlh->nlmsg_type; |
681 | km_state_notify(x, &c); | 701 | km_state_notify(x, &c); |
682 | 702 | ||
@@ -689,6 +709,7 @@ out: | |||
689 | 709 | ||
690 | static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) | 710 | static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) |
691 | { | 711 | { |
712 | memset(p, 0, sizeof(*p)); | ||
692 | memcpy(&p->id, &x->id, sizeof(p->id)); | 713 | memcpy(&p->id, &x->id, sizeof(p->id)); |
693 | memcpy(&p->sel, &x->sel, sizeof(p->sel)); | 714 | memcpy(&p->sel, &x->sel, sizeof(p->sel)); |
694 | memcpy(&p->lft, &x->lft, sizeof(p->lft)); | 715 | memcpy(&p->lft, &x->lft, sizeof(p->lft)); |
@@ -742,7 +763,7 @@ static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb) | |||
742 | return -EMSGSIZE; | 763 | return -EMSGSIZE; |
743 | 764 | ||
744 | algo = nla_data(nla); | 765 | algo = nla_data(nla); |
745 | strcpy(algo->alg_name, auth->alg_name); | 766 | strncpy(algo->alg_name, auth->alg_name, sizeof(algo->alg_name)); |
746 | memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8); | 767 | memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8); |
747 | algo->alg_key_len = auth->alg_key_len; | 768 | algo->alg_key_len = auth->alg_key_len; |
748 | 769 | ||
@@ -826,7 +847,7 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr) | |||
826 | struct nlmsghdr *nlh; | 847 | struct nlmsghdr *nlh; |
827 | int err; | 848 | int err; |
828 | 849 | ||
829 | nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, | 850 | nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, sp->nlmsg_seq, |
830 | XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags); | 851 | XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags); |
831 | if (nlh == NULL) | 852 | if (nlh == NULL) |
832 | return -EMSGSIZE; | 853 | return -EMSGSIZE; |
@@ -878,6 +899,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, | |||
878 | { | 899 | { |
879 | struct xfrm_dump_info info; | 900 | struct xfrm_dump_info info; |
880 | struct sk_buff *skb; | 901 | struct sk_buff *skb; |
902 | int err; | ||
881 | 903 | ||
882 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); | 904 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); |
883 | if (!skb) | 905 | if (!skb) |
@@ -888,9 +910,10 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, | |||
888 | info.nlmsg_seq = seq; | 910 | info.nlmsg_seq = seq; |
889 | info.nlmsg_flags = 0; | 911 | info.nlmsg_flags = 0; |
890 | 912 | ||
891 | if (dump_one_state(x, 0, &info)) { | 913 | err = dump_one_state(x, 0, &info); |
914 | if (err) { | ||
892 | kfree_skb(skb); | 915 | kfree_skb(skb); |
893 | return NULL; | 916 | return ERR_PTR(err); |
894 | } | 917 | } |
895 | 918 | ||
896 | return skb; | 919 | return skb; |
@@ -904,7 +927,7 @@ static inline size_t xfrm_spdinfo_msgsize(void) | |||
904 | } | 927 | } |
905 | 928 | ||
906 | static int build_spdinfo(struct sk_buff *skb, struct net *net, | 929 | static int build_spdinfo(struct sk_buff *skb, struct net *net, |
907 | u32 pid, u32 seq, u32 flags) | 930 | u32 portid, u32 seq, u32 flags) |
908 | { | 931 | { |
909 | struct xfrmk_spdinfo si; | 932 | struct xfrmk_spdinfo si; |
910 | struct xfrmu_spdinfo spc; | 933 | struct xfrmu_spdinfo spc; |
@@ -913,7 +936,7 @@ static int build_spdinfo(struct sk_buff *skb, struct net *net, | |||
913 | int err; | 936 | int err; |
914 | u32 *f; | 937 | u32 *f; |
915 | 938 | ||
916 | nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0); | 939 | nlh = nlmsg_put(skb, portid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0); |
917 | if (nlh == NULL) /* shouldn't really happen ... */ | 940 | if (nlh == NULL) /* shouldn't really happen ... */ |
918 | return -EMSGSIZE; | 941 | return -EMSGSIZE; |
919 | 942 | ||
@@ -946,17 +969,17 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
946 | struct net *net = sock_net(skb->sk); | 969 | struct net *net = sock_net(skb->sk); |
947 | struct sk_buff *r_skb; | 970 | struct sk_buff *r_skb; |
948 | u32 *flags = nlmsg_data(nlh); | 971 | u32 *flags = nlmsg_data(nlh); |
949 | u32 spid = NETLINK_CB(skb).pid; | 972 | u32 sportid = NETLINK_CB(skb).portid; |
950 | u32 seq = nlh->nlmsg_seq; | 973 | u32 seq = nlh->nlmsg_seq; |
951 | 974 | ||
952 | r_skb = nlmsg_new(xfrm_spdinfo_msgsize(), GFP_ATOMIC); | 975 | r_skb = nlmsg_new(xfrm_spdinfo_msgsize(), GFP_ATOMIC); |
953 | if (r_skb == NULL) | 976 | if (r_skb == NULL) |
954 | return -ENOMEM; | 977 | return -ENOMEM; |
955 | 978 | ||
956 | if (build_spdinfo(r_skb, net, spid, seq, *flags) < 0) | 979 | if (build_spdinfo(r_skb, net, sportid, seq, *flags) < 0) |
957 | BUG(); | 980 | BUG(); |
958 | 981 | ||
959 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); | 982 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid); |
960 | } | 983 | } |
961 | 984 | ||
962 | static inline size_t xfrm_sadinfo_msgsize(void) | 985 | static inline size_t xfrm_sadinfo_msgsize(void) |
@@ -967,7 +990,7 @@ static inline size_t xfrm_sadinfo_msgsize(void) | |||
967 | } | 990 | } |
968 | 991 | ||
969 | static int build_sadinfo(struct sk_buff *skb, struct net *net, | 992 | static int build_sadinfo(struct sk_buff *skb, struct net *net, |
970 | u32 pid, u32 seq, u32 flags) | 993 | u32 portid, u32 seq, u32 flags) |
971 | { | 994 | { |
972 | struct xfrmk_sadinfo si; | 995 | struct xfrmk_sadinfo si; |
973 | struct xfrmu_sadhinfo sh; | 996 | struct xfrmu_sadhinfo sh; |
@@ -975,7 +998,7 @@ static int build_sadinfo(struct sk_buff *skb, struct net *net, | |||
975 | int err; | 998 | int err; |
976 | u32 *f; | 999 | u32 *f; |
977 | 1000 | ||
978 | nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSADINFO, sizeof(u32), 0); | 1001 | nlh = nlmsg_put(skb, portid, seq, XFRM_MSG_NEWSADINFO, sizeof(u32), 0); |
979 | if (nlh == NULL) /* shouldn't really happen ... */ | 1002 | if (nlh == NULL) /* shouldn't really happen ... */ |
980 | return -EMSGSIZE; | 1003 | return -EMSGSIZE; |
981 | 1004 | ||
@@ -1003,17 +1026,17 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1003 | struct net *net = sock_net(skb->sk); | 1026 | struct net *net = sock_net(skb->sk); |
1004 | struct sk_buff *r_skb; | 1027 | struct sk_buff *r_skb; |
1005 | u32 *flags = nlmsg_data(nlh); | 1028 | u32 *flags = nlmsg_data(nlh); |
1006 | u32 spid = NETLINK_CB(skb).pid; | 1029 | u32 sportid = NETLINK_CB(skb).portid; |
1007 | u32 seq = nlh->nlmsg_seq; | 1030 | u32 seq = nlh->nlmsg_seq; |
1008 | 1031 | ||
1009 | r_skb = nlmsg_new(xfrm_sadinfo_msgsize(), GFP_ATOMIC); | 1032 | r_skb = nlmsg_new(xfrm_sadinfo_msgsize(), GFP_ATOMIC); |
1010 | if (r_skb == NULL) | 1033 | if (r_skb == NULL) |
1011 | return -ENOMEM; | 1034 | return -ENOMEM; |
1012 | 1035 | ||
1013 | if (build_sadinfo(r_skb, net, spid, seq, *flags) < 0) | 1036 | if (build_sadinfo(r_skb, net, sportid, seq, *flags) < 0) |
1014 | BUG(); | 1037 | BUG(); |
1015 | 1038 | ||
1016 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); | 1039 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid); |
1017 | } | 1040 | } |
1018 | 1041 | ||
1019 | static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | 1042 | static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, |
@@ -1033,7 +1056,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1033 | if (IS_ERR(resp_skb)) { | 1056 | if (IS_ERR(resp_skb)) { |
1034 | err = PTR_ERR(resp_skb); | 1057 | err = PTR_ERR(resp_skb); |
1035 | } else { | 1058 | } else { |
1036 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid); | 1059 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid); |
1037 | } | 1060 | } |
1038 | xfrm_state_put(x); | 1061 | xfrm_state_put(x); |
1039 | out_noput: | 1062 | out_noput: |
@@ -1114,7 +1137,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1114 | goto out; | 1137 | goto out; |
1115 | } | 1138 | } |
1116 | 1139 | ||
1117 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid); | 1140 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid); |
1118 | 1141 | ||
1119 | out: | 1142 | out: |
1120 | xfrm_state_put(x); | 1143 | xfrm_state_put(x); |
@@ -1317,6 +1340,7 @@ static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy | |||
1317 | 1340 | ||
1318 | static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p, int dir) | 1341 | static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p, int dir) |
1319 | { | 1342 | { |
1343 | memset(p, 0, sizeof(*p)); | ||
1320 | memcpy(&p->sel, &xp->selector, sizeof(p->sel)); | 1344 | memcpy(&p->sel, &xp->selector, sizeof(p->sel)); |
1321 | memcpy(&p->lft, &xp->lft, sizeof(p->lft)); | 1345 | memcpy(&p->lft, &xp->lft, sizeof(p->lft)); |
1322 | memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft)); | 1346 | memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft)); |
@@ -1369,7 +1393,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1369 | struct km_event c; | 1393 | struct km_event c; |
1370 | int err; | 1394 | int err; |
1371 | int excl; | 1395 | int excl; |
1372 | uid_t loginuid = audit_get_loginuid(current); | 1396 | kuid_t loginuid = audit_get_loginuid(current); |
1373 | u32 sessionid = audit_get_sessionid(current); | 1397 | u32 sessionid = audit_get_sessionid(current); |
1374 | u32 sid; | 1398 | u32 sid; |
1375 | 1399 | ||
@@ -1401,7 +1425,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1401 | 1425 | ||
1402 | c.event = nlh->nlmsg_type; | 1426 | c.event = nlh->nlmsg_type; |
1403 | c.seq = nlh->nlmsg_seq; | 1427 | c.seq = nlh->nlmsg_seq; |
1404 | c.pid = nlh->nlmsg_pid; | 1428 | c.portid = nlh->nlmsg_pid; |
1405 | km_policy_notify(xp, p->dir, &c); | 1429 | km_policy_notify(xp, p->dir, &c); |
1406 | 1430 | ||
1407 | xfrm_pol_put(xp); | 1431 | xfrm_pol_put(xp); |
@@ -1421,6 +1445,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) | |||
1421 | struct xfrm_user_tmpl *up = &vec[i]; | 1445 | struct xfrm_user_tmpl *up = &vec[i]; |
1422 | struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; | 1446 | struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; |
1423 | 1447 | ||
1448 | memset(up, 0, sizeof(*up)); | ||
1424 | memcpy(&up->id, &kp->id, sizeof(up->id)); | 1449 | memcpy(&up->id, &kp->id, sizeof(up->id)); |
1425 | up->family = kp->encap_family; | 1450 | up->family = kp->encap_family; |
1426 | memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); | 1451 | memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); |
@@ -1486,7 +1511,7 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr | |||
1486 | struct nlmsghdr *nlh; | 1511 | struct nlmsghdr *nlh; |
1487 | int err; | 1512 | int err; |
1488 | 1513 | ||
1489 | nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, | 1514 | nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, sp->nlmsg_seq, |
1490 | XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags); | 1515 | XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags); |
1491 | if (nlh == NULL) | 1516 | if (nlh == NULL) |
1492 | return -EMSGSIZE; | 1517 | return -EMSGSIZE; |
@@ -1546,6 +1571,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, | |||
1546 | { | 1571 | { |
1547 | struct xfrm_dump_info info; | 1572 | struct xfrm_dump_info info; |
1548 | struct sk_buff *skb; | 1573 | struct sk_buff *skb; |
1574 | int err; | ||
1549 | 1575 | ||
1550 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1576 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
1551 | if (!skb) | 1577 | if (!skb) |
@@ -1556,9 +1582,10 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, | |||
1556 | info.nlmsg_seq = seq; | 1582 | info.nlmsg_seq = seq; |
1557 | info.nlmsg_flags = 0; | 1583 | info.nlmsg_flags = 0; |
1558 | 1584 | ||
1559 | if (dump_one_policy(xp, dir, 0, &info) < 0) { | 1585 | err = dump_one_policy(xp, dir, 0, &info); |
1586 | if (err) { | ||
1560 | kfree_skb(skb); | 1587 | kfree_skb(skb); |
1561 | return NULL; | 1588 | return ERR_PTR(err); |
1562 | } | 1589 | } |
1563 | 1590 | ||
1564 | return skb; | 1591 | return skb; |
@@ -1621,10 +1648,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1621 | err = PTR_ERR(resp_skb); | 1648 | err = PTR_ERR(resp_skb); |
1622 | } else { | 1649 | } else { |
1623 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, | 1650 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, |
1624 | NETLINK_CB(skb).pid); | 1651 | NETLINK_CB(skb).portid); |
1625 | } | 1652 | } |
1626 | } else { | 1653 | } else { |
1627 | uid_t loginuid = audit_get_loginuid(current); | 1654 | kuid_t loginuid = audit_get_loginuid(current); |
1628 | u32 sessionid = audit_get_sessionid(current); | 1655 | u32 sessionid = audit_get_sessionid(current); |
1629 | u32 sid; | 1656 | u32 sid; |
1630 | 1657 | ||
@@ -1638,7 +1665,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1638 | c.data.byid = p->index; | 1665 | c.data.byid = p->index; |
1639 | c.event = nlh->nlmsg_type; | 1666 | c.event = nlh->nlmsg_type; |
1640 | c.seq = nlh->nlmsg_seq; | 1667 | c.seq = nlh->nlmsg_seq; |
1641 | c.pid = nlh->nlmsg_pid; | 1668 | c.portid = nlh->nlmsg_pid; |
1642 | km_policy_notify(xp, p->dir, &c); | 1669 | km_policy_notify(xp, p->dir, &c); |
1643 | } | 1670 | } |
1644 | 1671 | ||
@@ -1668,7 +1695,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1668 | c.data.proto = p->proto; | 1695 | c.data.proto = p->proto; |
1669 | c.event = nlh->nlmsg_type; | 1696 | c.event = nlh->nlmsg_type; |
1670 | c.seq = nlh->nlmsg_seq; | 1697 | c.seq = nlh->nlmsg_seq; |
1671 | c.pid = nlh->nlmsg_pid; | 1698 | c.portid = nlh->nlmsg_pid; |
1672 | c.net = net; | 1699 | c.net = net; |
1673 | km_state_notify(NULL, &c); | 1700 | km_state_notify(NULL, &c); |
1674 | 1701 | ||
@@ -1695,7 +1722,7 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct | |||
1695 | struct nlmsghdr *nlh; | 1722 | struct nlmsghdr *nlh; |
1696 | int err; | 1723 | int err; |
1697 | 1724 | ||
1698 | nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0); | 1725 | nlh = nlmsg_put(skb, c->portid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0); |
1699 | if (nlh == NULL) | 1726 | if (nlh == NULL) |
1700 | return -EMSGSIZE; | 1727 | return -EMSGSIZE; |
1701 | 1728 | ||
@@ -1777,11 +1804,11 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1777 | spin_lock_bh(&x->lock); | 1804 | spin_lock_bh(&x->lock); |
1778 | c.data.aevent = p->flags; | 1805 | c.data.aevent = p->flags; |
1779 | c.seq = nlh->nlmsg_seq; | 1806 | c.seq = nlh->nlmsg_seq; |
1780 | c.pid = nlh->nlmsg_pid; | 1807 | c.portid = nlh->nlmsg_pid; |
1781 | 1808 | ||
1782 | if (build_aevent(r_skb, x, &c) < 0) | 1809 | if (build_aevent(r_skb, x, &c) < 0) |
1783 | BUG(); | 1810 | BUG(); |
1784 | err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).pid); | 1811 | err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid); |
1785 | spin_unlock_bh(&x->lock); | 1812 | spin_unlock_bh(&x->lock); |
1786 | xfrm_state_put(x); | 1813 | xfrm_state_put(x); |
1787 | return err; | 1814 | return err; |
@@ -1822,12 +1849,12 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1822 | goto out; | 1849 | goto out; |
1823 | 1850 | ||
1824 | spin_lock_bh(&x->lock); | 1851 | spin_lock_bh(&x->lock); |
1825 | xfrm_update_ae_params(x, attrs); | 1852 | xfrm_update_ae_params(x, attrs, 1); |
1826 | spin_unlock_bh(&x->lock); | 1853 | spin_unlock_bh(&x->lock); |
1827 | 1854 | ||
1828 | c.event = nlh->nlmsg_type; | 1855 | c.event = nlh->nlmsg_type; |
1829 | c.seq = nlh->nlmsg_seq; | 1856 | c.seq = nlh->nlmsg_seq; |
1830 | c.pid = nlh->nlmsg_pid; | 1857 | c.portid = nlh->nlmsg_pid; |
1831 | c.data.aevent = XFRM_AE_CU; | 1858 | c.data.aevent = XFRM_AE_CU; |
1832 | km_state_notify(x, &c); | 1859 | km_state_notify(x, &c); |
1833 | err = 0; | 1860 | err = 0; |
@@ -1862,7 +1889,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1862 | c.data.type = type; | 1889 | c.data.type = type; |
1863 | c.event = nlh->nlmsg_type; | 1890 | c.event = nlh->nlmsg_type; |
1864 | c.seq = nlh->nlmsg_seq; | 1891 | c.seq = nlh->nlmsg_seq; |
1865 | c.pid = nlh->nlmsg_pid; | 1892 | c.portid = nlh->nlmsg_pid; |
1866 | c.net = net; | 1893 | c.net = net; |
1867 | km_policy_notify(NULL, 0, &c); | 1894 | km_policy_notify(NULL, 0, &c); |
1868 | return 0; | 1895 | return 0; |
@@ -1918,7 +1945,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1918 | 1945 | ||
1919 | err = 0; | 1946 | err = 0; |
1920 | if (up->hard) { | 1947 | if (up->hard) { |
1921 | uid_t loginuid = audit_get_loginuid(current); | 1948 | kuid_t loginuid = audit_get_loginuid(current); |
1922 | u32 sessionid = audit_get_sessionid(current); | 1949 | u32 sessionid = audit_get_sessionid(current); |
1923 | u32 sid; | 1950 | u32 sid; |
1924 | 1951 | ||
@@ -1930,7 +1957,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1930 | // reset the timers here? | 1957 | // reset the timers here? |
1931 | WARN(1, "Dont know what to do with soft policy expire\n"); | 1958 | WARN(1, "Dont know what to do with soft policy expire\n"); |
1932 | } | 1959 | } |
1933 | km_policy_expired(xp, p->dir, up->hard, current->pid); | 1960 | km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); |
1934 | 1961 | ||
1935 | out: | 1962 | out: |
1936 | xfrm_pol_put(xp); | 1963 | xfrm_pol_put(xp); |
@@ -1958,10 +1985,10 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1958 | err = -EINVAL; | 1985 | err = -EINVAL; |
1959 | if (x->km.state != XFRM_STATE_VALID) | 1986 | if (x->km.state != XFRM_STATE_VALID) |
1960 | goto out; | 1987 | goto out; |
1961 | km_state_expired(x, ue->hard, current->pid); | 1988 | km_state_expired(x, ue->hard, nlh->nlmsg_pid); |
1962 | 1989 | ||
1963 | if (ue->hard) { | 1990 | if (ue->hard) { |
1964 | uid_t loginuid = audit_get_loginuid(current); | 1991 | kuid_t loginuid = audit_get_loginuid(current); |
1965 | u32 sessionid = audit_get_sessionid(current); | 1992 | u32 sessionid = audit_get_sessionid(current); |
1966 | u32 sid; | 1993 | u32 sid; |
1967 | 1994 | ||
@@ -2370,7 +2397,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct | |||
2370 | struct nlmsghdr *nlh; | 2397 | struct nlmsghdr *nlh; |
2371 | int err; | 2398 | int err; |
2372 | 2399 | ||
2373 | nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0); | 2400 | nlh = nlmsg_put(skb, c->portid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0); |
2374 | if (nlh == NULL) | 2401 | if (nlh == NULL) |
2375 | return -EMSGSIZE; | 2402 | return -EMSGSIZE; |
2376 | 2403 | ||
@@ -2429,7 +2456,7 @@ static int xfrm_notify_sa_flush(const struct km_event *c) | |||
2429 | if (skb == NULL) | 2456 | if (skb == NULL) |
2430 | return -ENOMEM; | 2457 | return -ENOMEM; |
2431 | 2458 | ||
2432 | nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHSA, sizeof(*p), 0); | 2459 | nlh = nlmsg_put(skb, c->portid, c->seq, XFRM_MSG_FLUSHSA, sizeof(*p), 0); |
2433 | if (nlh == NULL) { | 2460 | if (nlh == NULL) { |
2434 | kfree_skb(skb); | 2461 | kfree_skb(skb); |
2435 | return -EMSGSIZE; | 2462 | return -EMSGSIZE; |
@@ -2497,7 +2524,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c) | |||
2497 | if (skb == NULL) | 2524 | if (skb == NULL) |
2498 | return -ENOMEM; | 2525 | return -ENOMEM; |
2499 | 2526 | ||
2500 | nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); | 2527 | nlh = nlmsg_put(skb, c->portid, c->seq, c->event, headlen, 0); |
2501 | err = -EMSGSIZE; | 2528 | err = -EMSGSIZE; |
2502 | if (nlh == NULL) | 2529 | if (nlh == NULL) |
2503 | goto out_free_skb; | 2530 | goto out_free_skb; |
@@ -2567,8 +2594,7 @@ static inline size_t xfrm_acquire_msgsize(struct xfrm_state *x, | |||
2567 | } | 2594 | } |
2568 | 2595 | ||
2569 | static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | 2596 | static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, |
2570 | struct xfrm_tmpl *xt, struct xfrm_policy *xp, | 2597 | struct xfrm_tmpl *xt, struct xfrm_policy *xp) |
2571 | int dir) | ||
2572 | { | 2598 | { |
2573 | __u32 seq = xfrm_get_acqseq(); | 2599 | __u32 seq = xfrm_get_acqseq(); |
2574 | struct xfrm_user_acquire *ua; | 2600 | struct xfrm_user_acquire *ua; |
@@ -2583,7 +2609,7 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | |||
2583 | memcpy(&ua->id, &x->id, sizeof(ua->id)); | 2609 | memcpy(&ua->id, &x->id, sizeof(ua->id)); |
2584 | memcpy(&ua->saddr, &x->props.saddr, sizeof(ua->saddr)); | 2610 | memcpy(&ua->saddr, &x->props.saddr, sizeof(ua->saddr)); |
2585 | memcpy(&ua->sel, &x->sel, sizeof(ua->sel)); | 2611 | memcpy(&ua->sel, &x->sel, sizeof(ua->sel)); |
2586 | copy_to_user_policy(xp, &ua->policy, dir); | 2612 | copy_to_user_policy(xp, &ua->policy, XFRM_POLICY_OUT); |
2587 | ua->aalgos = xt->aalgos; | 2613 | ua->aalgos = xt->aalgos; |
2588 | ua->ealgos = xt->ealgos; | 2614 | ua->ealgos = xt->ealgos; |
2589 | ua->calgos = xt->calgos; | 2615 | ua->calgos = xt->calgos; |
@@ -2605,7 +2631,7 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | |||
2605 | } | 2631 | } |
2606 | 2632 | ||
2607 | static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | 2633 | static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, |
2608 | struct xfrm_policy *xp, int dir) | 2634 | struct xfrm_policy *xp) |
2609 | { | 2635 | { |
2610 | struct net *net = xs_net(x); | 2636 | struct net *net = xs_net(x); |
2611 | struct sk_buff *skb; | 2637 | struct sk_buff *skb; |
@@ -2614,7 +2640,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
2614 | if (skb == NULL) | 2640 | if (skb == NULL) |
2615 | return -ENOMEM; | 2641 | return -ENOMEM; |
2616 | 2642 | ||
2617 | if (build_acquire(skb, x, xt, xp, dir) < 0) | 2643 | if (build_acquire(skb, x, xt, xp) < 0) |
2618 | BUG(); | 2644 | BUG(); |
2619 | 2645 | ||
2620 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC); | 2646 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC); |
@@ -2697,7 +2723,7 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, | |||
2697 | struct nlmsghdr *nlh; | 2723 | struct nlmsghdr *nlh; |
2698 | int err; | 2724 | int err; |
2699 | 2725 | ||
2700 | nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0); | 2726 | nlh = nlmsg_put(skb, c->portid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0); |
2701 | if (nlh == NULL) | 2727 | if (nlh == NULL) |
2702 | return -EMSGSIZE; | 2728 | return -EMSGSIZE; |
2703 | 2729 | ||
@@ -2757,7 +2783,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_e | |||
2757 | if (skb == NULL) | 2783 | if (skb == NULL) |
2758 | return -ENOMEM; | 2784 | return -ENOMEM; |
2759 | 2785 | ||
2760 | nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0); | 2786 | nlh = nlmsg_put(skb, c->portid, c->seq, c->event, headlen, 0); |
2761 | err = -EMSGSIZE; | 2787 | err = -EMSGSIZE; |
2762 | if (nlh == NULL) | 2788 | if (nlh == NULL) |
2763 | goto out_free_skb; | 2789 | goto out_free_skb; |
@@ -2811,7 +2837,7 @@ static int xfrm_notify_policy_flush(const struct km_event *c) | |||
2811 | if (skb == NULL) | 2837 | if (skb == NULL) |
2812 | return -ENOMEM; | 2838 | return -ENOMEM; |
2813 | 2839 | ||
2814 | nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0); | 2840 | nlh = nlmsg_put(skb, c->portid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0); |
2815 | err = -EMSGSIZE; | 2841 | err = -EMSGSIZE; |
2816 | if (nlh == NULL) | 2842 | if (nlh == NULL) |
2817 | goto out_free_skb; | 2843 | goto out_free_skb; |
@@ -2964,7 +2990,7 @@ static int __net_init xfrm_user_net_init(struct net *net) | |||
2964 | .input = xfrm_netlink_rcv, | 2990 | .input = xfrm_netlink_rcv, |
2965 | }; | 2991 | }; |
2966 | 2992 | ||
2967 | nlsk = netlink_kernel_create(net, NETLINK_XFRM, THIS_MODULE, &cfg); | 2993 | nlsk = netlink_kernel_create(net, NETLINK_XFRM, &cfg); |
2968 | if (nlsk == NULL) | 2994 | if (nlsk == NULL) |
2969 | return -ENOMEM; | 2995 | return -ENOMEM; |
2970 | net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */ | 2996 | net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */ |