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); |