diff options
| -rw-r--r-- | include/linux/netfilter/nfnetlink.h | 2 | ||||
| -rw-r--r-- | include/net/netlink.h | 2 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 46 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 46 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink.c | 26 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_log.c | 4 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_queue.c | 6 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 21 | ||||
| -rw-r--r-- | net/netlink/genetlink.c | 56 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 40 |
10 files changed, 93 insertions, 156 deletions
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index e1ea5dfbbb..0f9311df15 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h | |||
| @@ -111,7 +111,7 @@ struct nfgenmsg { | |||
| 111 | struct nfnl_callback | 111 | struct nfnl_callback |
| 112 | { | 112 | { |
| 113 | int (*call)(struct sock *nl, struct sk_buff *skb, | 113 | int (*call)(struct sock *nl, struct sk_buff *skb, |
| 114 | struct nlmsghdr *nlh, struct nfattr *cda[], int *errp); | 114 | struct nlmsghdr *nlh, struct nfattr *cda[]); |
| 115 | u_int16_t attr_count; /* number of nfattr's */ | 115 | u_int16_t attr_count; /* number of nfattr's */ |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
diff --git a/include/net/netlink.h b/include/net/netlink.h index 510ca7fabe..1c11518fc8 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
| @@ -214,7 +214,7 @@ struct nl_info { | |||
| 214 | 214 | ||
| 215 | extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, | 215 | extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, |
| 216 | int (*cb)(struct sk_buff *, | 216 | int (*cb)(struct sk_buff *, |
| 217 | struct nlmsghdr *, int *)); | 217 | struct nlmsghdr *)); |
| 218 | extern void netlink_queue_skip(struct nlmsghdr *nlh, | 218 | extern void netlink_queue_skip(struct nlmsghdr *nlh, |
| 219 | struct sk_buff *skb); | 219 | struct sk_buff *skb); |
| 220 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, | 220 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b2136accd2..14241ada41 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -852,8 +852,7 @@ static int rtattr_max; | |||
| 852 | 852 | ||
| 853 | /* Process one rtnetlink message. */ | 853 | /* Process one rtnetlink message. */ |
| 854 | 854 | ||
| 855 | static __inline__ int | 855 | static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 856 | rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | ||
| 857 | { | 856 | { |
| 858 | rtnl_doit_func doit; | 857 | rtnl_doit_func doit; |
| 859 | int sz_idx, kind; | 858 | int sz_idx, kind; |
| @@ -863,10 +862,8 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 863 | int err; | 862 | int err; |
| 864 | 863 | ||
| 865 | type = nlh->nlmsg_type; | 864 | type = nlh->nlmsg_type; |
| 866 | |||
| 867 | /* Unknown message: reply with EINVAL */ | ||
| 868 | if (type > RTM_MAX) | 865 | if (type > RTM_MAX) |
| 869 | goto err_inval; | 866 | return -EINVAL; |
| 870 | 867 | ||
| 871 | type -= RTM_BASE; | 868 | type -= RTM_BASE; |
| 872 | 869 | ||
| @@ -875,40 +872,33 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 875 | return 0; | 872 | return 0; |
| 876 | 873 | ||
| 877 | family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; | 874 | family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; |
| 878 | if (family >= NPROTO) { | 875 | if (family >= NPROTO) |
| 879 | *errp = -EAFNOSUPPORT; | 876 | return -EAFNOSUPPORT; |
| 880 | return -1; | ||
| 881 | } | ||
| 882 | 877 | ||
| 883 | sz_idx = type>>2; | 878 | sz_idx = type>>2; |
| 884 | kind = type&3; | 879 | kind = type&3; |
| 885 | 880 | ||
| 886 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) { | 881 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) |
| 887 | *errp = -EPERM; | 882 | return -EPERM; |
| 888 | return -1; | ||
| 889 | } | ||
| 890 | 883 | ||
| 891 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 884 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
| 892 | rtnl_dumpit_func dumpit; | 885 | rtnl_dumpit_func dumpit; |
| 893 | 886 | ||
| 894 | dumpit = rtnl_get_dumpit(family, type); | 887 | dumpit = rtnl_get_dumpit(family, type); |
| 895 | if (dumpit == NULL) | 888 | if (dumpit == NULL) |
| 896 | goto err_inval; | 889 | return -EINVAL; |
| 897 | |||
| 898 | if ((*errp = netlink_dump_start(rtnl, skb, nlh, | ||
| 899 | dumpit, NULL)) != 0) { | ||
| 900 | return -1; | ||
| 901 | } | ||
| 902 | 890 | ||
| 903 | netlink_queue_skip(nlh, skb); | 891 | err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); |
| 904 | return -1; | 892 | if (err == 0) |
| 893 | err = -EINTR; | ||
| 894 | return err; | ||
| 905 | } | 895 | } |
| 906 | 896 | ||
| 907 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); | 897 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); |
| 908 | 898 | ||
| 909 | min_len = rtm_min[sz_idx]; | 899 | min_len = rtm_min[sz_idx]; |
| 910 | if (nlh->nlmsg_len < min_len) | 900 | if (nlh->nlmsg_len < min_len) |
| 911 | goto err_inval; | 901 | return -EINVAL; |
| 912 | 902 | ||
| 913 | if (nlh->nlmsg_len > min_len) { | 903 | if (nlh->nlmsg_len > min_len) { |
| 914 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); | 904 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); |
| @@ -918,7 +908,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 918 | unsigned flavor = attr->rta_type; | 908 | unsigned flavor = attr->rta_type; |
| 919 | if (flavor) { | 909 | if (flavor) { |
| 920 | if (flavor > rta_max[sz_idx]) | 910 | if (flavor > rta_max[sz_idx]) |
| 921 | goto err_inval; | 911 | return -EINVAL; |
| 922 | rta_buf[flavor-1] = attr; | 912 | rta_buf[flavor-1] = attr; |
| 923 | } | 913 | } |
| 924 | attr = RTA_NEXT(attr, attrlen); | 914 | attr = RTA_NEXT(attr, attrlen); |
| @@ -927,15 +917,9 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 927 | 917 | ||
| 928 | doit = rtnl_get_doit(family, type); | 918 | doit = rtnl_get_doit(family, type); |
| 929 | if (doit == NULL) | 919 | if (doit == NULL) |
| 930 | goto err_inval; | 920 | return -EINVAL; |
| 931 | err = doit(skb, nlh, (void *)&rta_buf[0]); | ||
| 932 | |||
| 933 | *errp = err; | ||
| 934 | return err; | ||
| 935 | 921 | ||
| 936 | err_inval: | 922 | return doit(skb, nlh, (void *)&rta_buf[0]); |
| 937 | *errp = -EINVAL; | ||
| 938 | return -1; | ||
| 939 | } | 923 | } |
| 940 | 924 | ||
| 941 | static void rtnetlink_rcv(struct sock *sk, int len) | 925 | static void rtnetlink_rcv(struct sock *sk, int len) |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 76f11f3259..443ba7753a 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -661,7 +661,7 @@ static const size_t cta_min[CTA_MAX] = { | |||
| 661 | 661 | ||
| 662 | static int | 662 | static int |
| 663 | ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | 663 | ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, |
| 664 | struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) | 664 | struct nlmsghdr *nlh, struct nfattr *cda[]) |
| 665 | { | 665 | { |
| 666 | struct nf_conntrack_tuple_hash *h; | 666 | struct nf_conntrack_tuple_hash *h; |
| 667 | struct nf_conntrack_tuple tuple; | 667 | struct nf_conntrack_tuple tuple; |
| @@ -709,7 +709,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 709 | 709 | ||
| 710 | static int | 710 | static int |
| 711 | ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | 711 | ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, |
| 712 | struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) | 712 | struct nlmsghdr *nlh, struct nfattr *cda[]) |
| 713 | { | 713 | { |
| 714 | struct nf_conntrack_tuple_hash *h; | 714 | struct nf_conntrack_tuple_hash *h; |
| 715 | struct nf_conntrack_tuple tuple; | 715 | struct nf_conntrack_tuple tuple; |
| @@ -720,22 +720,15 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 720 | int err = 0; | 720 | int err = 0; |
| 721 | 721 | ||
| 722 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 722 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
| 723 | u32 rlen; | ||
| 724 | |||
| 725 | #ifndef CONFIG_NF_CT_ACCT | 723 | #ifndef CONFIG_NF_CT_ACCT |
| 726 | if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) | 724 | if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) |
| 727 | return -ENOTSUPP; | 725 | return -ENOTSUPP; |
| 728 | #endif | 726 | #endif |
| 729 | if ((*errp = netlink_dump_start(ctnl, skb, nlh, | 727 | err = netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, |
| 730 | ctnetlink_dump_table, | 728 | ctnetlink_done); |
| 731 | ctnetlink_done)) != 0) | 729 | if (err == 0) |
| 732 | return -EINVAL; | 730 | err = -EINTR; |
| 733 | 731 | return err; | |
| 734 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | ||
| 735 | if (rlen > skb->len) | ||
| 736 | rlen = skb->len; | ||
| 737 | skb_pull(skb, rlen); | ||
| 738 | return 0; | ||
| 739 | } | 732 | } |
| 740 | 733 | ||
| 741 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) | 734 | if (nfattr_bad_size(cda, CTA_MAX, cta_min)) |
| @@ -1009,7 +1002,7 @@ err: | |||
| 1009 | 1002 | ||
| 1010 | static int | 1003 | static int |
| 1011 | ctnetlink_new_conntrack(stru | ||
