diff options
| -rw-r--r-- | net/xfrm/xfrm_user.c | 61 | 
1 files changed, 5 insertions, 56 deletions
| diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 6996b7e85665..0cdd9a07e043 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/string.h> | 18 | #include <linux/string.h> | 
| 19 | #include <linux/net.h> | 19 | #include <linux/net.h> | 
| 20 | #include <linux/skbuff.h> | 20 | #include <linux/skbuff.h> | 
| 21 | #include <linux/netlink.h> | ||
| 22 | #include <linux/rtnetlink.h> | 21 | #include <linux/rtnetlink.h> | 
| 23 | #include <linux/pfkeyv2.h> | 22 | #include <linux/pfkeyv2.h> | 
| 24 | #include <linux/ipsec.h> | 23 | #include <linux/ipsec.h> | 
| @@ -26,6 +25,7 @@ | |||
| 26 | #include <linux/security.h> | 25 | #include <linux/security.h> | 
| 27 | #include <net/sock.h> | 26 | #include <net/sock.h> | 
| 28 | #include <net/xfrm.h> | 27 | #include <net/xfrm.h> | 
| 28 | #include <net/netlink.h> | ||
| 29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> | 
| 30 | 30 | ||
| 31 | static struct sock *xfrm_nl; | 31 | static struct sock *xfrm_nl; | 
| @@ -979,8 +979,6 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
| 979 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 979 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 
| 980 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | 980 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | 
| 981 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | 981 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | 
| 982 | u32 rlen; | ||
| 983 | |||
| 984 | if (link->dump == NULL) | 982 | if (link->dump == NULL) | 
| 985 | goto err_einval; | 983 | goto err_einval; | 
| 986 | 984 | ||
| @@ -988,10 +986,8 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
| 988 | link->dump, NULL)) != 0) { | 986 | link->dump, NULL)) != 0) { | 
| 989 | return -1; | 987 | return -1; | 
| 990 | } | 988 | } | 
| 991 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 989 | |
| 992 | if (rlen > skb->len) | 990 | netlink_queue_skip(nlh, skb); | 
| 993 | rlen = skb->len; | ||
| 994 | skb_pull(skb, rlen); | ||
| 995 | return -1; | 991 | return -1; | 
| 996 | } | 992 | } | 
| 997 | 993 | ||
| @@ -1026,60 +1022,13 @@ err_einval: | |||
| 1026 | return -1; | 1022 | return -1; | 
| 1027 | } | 1023 | } | 
| 1028 | 1024 | ||
| 1029 | static int xfrm_user_rcv_skb(struct sk_buff *skb) | ||
| 1030 | { | ||
| 1031 | int err; | ||
| 1032 | struct nlmsghdr *nlh; | ||
| 1033 | |||
| 1034 | while (skb->len >= NLMSG_SPACE(0)) { | ||
| 1035 | u32 rlen; | ||
| 1036 | |||
| 1037 | nlh = (struct nlmsghdr *) skb->data; | ||
| 1038 | if (nlh->nlmsg_len < sizeof(*nlh) || | ||
| 1039 | skb->len < nlh->nlmsg_len) | ||
| 1040 | return 0; | ||
| 1041 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | ||
| 1042 | if (rlen > skb->len) | ||
| 1043 | rlen = skb->len; | ||
| 1044 | if (xfrm_user_rcv_msg(skb, nlh, &err) < 0) { | ||
| 1045 | if (err == 0) | ||
| 1046 | return -1; | ||
| 1047 | netlink_ack(skb, nlh, err); | ||
| 1048 | } else if (nlh->nlmsg_flags & NLM_F_ACK) | ||
| 1049 | netlink_ack(skb, nlh, 0); | ||
| 1050 | skb_pull(skb, rlen); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | return 0; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 1025 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 
| 1057 | { | 1026 | { | 
| 1058 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | 1027 | unsigned int qlen = 0; | 
| 1059 | 1028 | ||
| 1060 | do { | 1029 | do { | 
| 1061 | struct sk_buff *skb; | ||
| 1062 | |||
| 1063 | down(&xfrm_cfg_sem); | 1030 | down(&xfrm_cfg_sem); | 
| 1064 | 1031 | netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg); | |
| 1065 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) | ||
| 1066 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
| 1067 | |||
| 1068 | for (; qlen; qlen--) { | ||
| 1069 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
| 1070 | if (xfrm_user_rcv_skb(skb)) { | ||
| 1071 | if (skb->len) | ||
| 1072 | skb_queue_head(&sk->sk_receive_queue, | ||
| 1073 | skb); | ||
| 1074 | else { | ||
| 1075 | kfree_skb(skb); | ||
| 1076 | qlen--; | ||
| 1077 | } | ||
| 1078 | break; | ||
| 1079 | } | ||
| 1080 | kfree_skb(skb); | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | up(&xfrm_cfg_sem); | 1032 | up(&xfrm_cfg_sem); | 
| 1084 | 1033 | ||
| 1085 | } while (qlen); | 1034 | } while (qlen); | 
