aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--include/net/netlink.h2
-rw-r--r--net/core/rtnetlink.c46
-rw-r--r--net/netfilter/nf_conntrack_netlink.c46
-rw-r--r--net/netfilter/nfnetlink.c26
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netlink/af_netlink.c21
-rw-r--r--net/netlink/genetlink.c56
-rw-r--r--net/xfrm/xfrm_user.c40
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 {
111struct nfnl_callback 111struct 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
215extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, 215extern 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 *));
218extern void netlink_queue_skip(struct nlmsghdr *nlh, 218extern void netlink_queue_skip(struct nlmsghdr *nlh,
219 struct sk_buff *skb); 219 struct sk_buff *skb);
220extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, 220extern 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
855static __inline__ int 855static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
856rtnetlink_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
936err_inval: 922 return doit(skb, nlh, (void *)&rta_buf[0]);
937 *errp = -EINVAL;
938 return -1;
939} 923}
940 924
941static void rtnetlink_rcv(struct sock *sk, int len) 925static 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
662static int 662static int
663ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 663ctnetlink_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
710static int 710static int
711ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, 711ctnetlink_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
1010static int 1003static int
1011ctnetlink_new_conntrack(stru