From fc482cc54e56bde012585905eb0f3565bec18ff5 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Fri, 25 Sep 2009 13:11:24 +0000 Subject: net: fix vlan_get_size to include vlan_flags size Fix vlan_get_size to include vlan->flags. Currently, the size of the vlan flags is not included in the nlmsg size. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- net/8021q/vlan_netlink.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index 343146e1bce..a9150485019 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c @@ -169,6 +169,7 @@ static size_t vlan_get_size(const struct net_device *dev) struct vlan_dev_info *vlan = vlan_dev_info(dev); return nla_total_size(2) + /* IFLA_VLAN_ID */ + sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */ vlan_qos_map_size(vlan->nr_ingress_mappings) + vlan_qos_map_size(vlan->nr_egress_mappings); } -- cgit v1.2.3 From 5dba93aedfc6906b27791c4a1136b177beae25b7 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Fri, 25 Sep 2009 13:11:44 +0000 Subject: net: fix nlmsg len size for skb when error bit is set. Currently, the nlmsg->len field is not set correctly in netlink_ack() for ack messages that include the nlmsg of the error frame. This corrects the length field passed to __nlmsg_put to use the correct payload size. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index a4bafbf1509..dd85320907c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1788,7 +1788,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) } rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, - NLMSG_ERROR, sizeof(struct nlmsgerr), 0); + NLMSG_ERROR, payload, 0); errmsg = nlmsg_data(rep); errmsg->error = err; memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh)); -- cgit v1.2.3 From 7eaf5077b37bb33dbd44e569ff88566d6fe286e9 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Fri, 25 Sep 2009 13:12:03 +0000 Subject: net: fix double skb free in dcbnl netlink_unicast() calls kfree_skb even in the error case. dcbnl calls netlink_unicast() which when it fails free's the skb and returns an error value. dcbnl is free'ing the skb again when this error occurs. This patch removes the double free. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index e0879bfb7dd..ac1205df6c8 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -194,7 +194,7 @@ static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, nlmsg_end(dcbnl_skb, nlh); ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) - goto err; + return -EINVAL; return 0; nlmsg_failure: @@ -275,7 +275,7 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) - goto err; + goto err_out; return 0; nlmsg_failure: @@ -316,12 +316,11 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) - goto err; + goto err_out; return 0; nlmsg_failure: -err: kfree_skb(dcbnl_skb); err_out: return -EINVAL; @@ -383,7 +382,7 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) - goto err; + goto err_out; return 0; nlmsg_failure: @@ -460,7 +459,7 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) { ret = -EINVAL; - goto err; + goto err_out; } return 0; @@ -799,7 +798,7 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) - goto err; + goto err_out; return 0; @@ -1063,7 +1062,7 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, ret = rtnl_unicast(dcbnl_skb, &init_net, pid); if (ret) - goto err; + goto err_out; return 0; -- cgit v1.2.3 From d1f8297a96b0d70f17704296a6666468f2087ce6 Mon Sep 17 00:00:00 2001 From: Sascha Hlusiak Date: Sat, 26 Sep 2009 20:28:07 -0700 Subject: Revert "sit: stateless autoconf for isatap" This reverts commit 645069299a1c7358cf7330afe293f07552f11a5d. While the code does not actually break anything, it does not completely follow RFC5214 yet. After talking back with Fred L. Templin, I agree that completing the ISATAP specific RS/RA code, would pollute the kernel a lot with code that is better implemented in userspace. The kernel should not send RS packages for ISATAP at all. Signed-off-by: Sascha Hlusiak Acked-by: Fred L. Templin Signed-off-by: David S. Miller --- net/ipv6/ndisc.c | 1 - net/ipv6/sit.c | 58 -------------------------------------------------------- 2 files changed, 59 deletions(-) (limited to 'net') diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 498b9b0b0fa..f74e4e2cdd0 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -658,7 +658,6 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, &icmp6h, NULL, send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0); } -EXPORT_SYMBOL(ndisc_send_rs); static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index fcb53962884..d65e0c496cc 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -15,7 +15,6 @@ * Roger Venning : 6to4 support * Nate Thompson : 6to4 support * Fred Templin : isatap support - * Sascha Hlusiak : stateless autoconf for isatap */ #include @@ -223,44 +222,6 @@ failed: return NULL; } -static void ipip6_tunnel_rs_timer(unsigned long data) -{ - struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *) data; - struct inet6_dev *ifp; - struct inet6_ifaddr *addr; - - spin_lock(&p->lock); - ifp = __in6_dev_get(p->tunnel->dev); - - read_lock_bh(&ifp->lock); - for (addr = ifp->addr_list; addr; addr = addr->if_next) { - struct in6_addr rtr; - - if (!(ipv6_addr_type(&addr->addr) & IPV6_ADDR_LINKLOCAL)) - continue; - - /* Send RS to guessed linklocal address of router - * - * Better: send to ff02::2 encapsuled in unicast directly - * to router-v4 instead of guessing the v6 address. - * - * Cisco/Windows seem to not set the u/l bit correctly, - * so we won't guess right. - */ - ipv6_addr_set(&rtr, htonl(0xFE800000), 0, 0, 0); - if (!__ipv6_isatap_ifid(rtr.s6_addr + 8, - p->addr)) { - ndisc_send_rs(p->tunnel->dev, &addr->addr, &rtr); - } - } - read_unlock_bh(&ifp->lock); - - mod_timer(&p->rs_timer, jiffies + HZ * p->rs_delay); - spin_unlock(&p->lock); - - return; -} - static struct ip_tunnel_prl_entry * __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) { @@ -319,7 +280,6 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t, continue; kp[c].addr = prl->addr; kp[c].flags = prl->flags; - kp[c].rs_delay = prl->rs_delay; c++; if (kprl.addr != htonl(INADDR_ANY)) break; @@ -369,23 +329,11 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) } p->next = t->prl; - p->tunnel = t; t->prl = p; t->prl_count++; - - spin_lock_init(&p->lock); - setup_timer(&p->rs_timer, ipip6_tunnel_rs_timer, (unsigned long) p); update: p->addr = a->addr; p->flags = a->flags; - p->rs_delay = a->rs_delay; - if (p->rs_delay == 0) - p->rs_delay = IPTUNNEL_RS_DEFAULT_DELAY; - spin_lock(&p->lock); - del_timer(&p->rs_timer); - if (p->flags & PRL_DEFAULT) - mod_timer(&p->rs_timer, jiffies + 1); - spin_unlock(&p->lock); out: write_unlock(&ipip6_lock); return err; @@ -404,9 +352,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) if ((*p)->addr == a->addr) { x = *p; *p = x->next; - spin_lock(&x->lock); - del_timer(&x->rs_timer); - spin_unlock(&x->lock); kfree(x); t->prl_count--; goto out; @@ -417,9 +362,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) while (t->prl) { x = t->prl; t->prl = t->prl->next; - spin_lock(&x->lock); - del_timer(&x->rs_timer); - spin_unlock(&x->lock); kfree(x); t->prl_count--; } -- cgit v1.2.3 From 2f72291d3d0e440f9343c7b97dc233c1a122165a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 28 Sep 2009 12:26:28 -0700 Subject: ax25: Add missing dev_put in ax25_setsockopt ax25_setsockopt SO_BINDTODEVICE is missing a dev_put call in case of success. Re-order code to fix this bug. While at it also reformat two lines of code to comply with the Linux coding style. Initial patch by Jarek Poplawski . Reported-by: Bernard Pidoux F6BVP Signed-off-by: Ralf Baechle Signed-off-by: David S. Miller --- net/ax25/af_ax25.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fbcac76fdc0..4102de1022e 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -641,15 +641,10 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, case SO_BINDTODEVICE: if (optlen > IFNAMSIZ) - optlen=IFNAMSIZ; - if (copy_from_user(devname, optval, optlen)) { - res = -EFAULT; - break; - } + optlen = IFNAMSIZ; - dev = dev_get_by_name(&init_net, devname); - if (dev == NULL) { - res = -ENODEV; + if (copy_from_user(devname, optval, optlen)) { + res = -EFAULT; break; } @@ -657,12 +652,18 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, (sock->state != SS_UNCONNECTED || sk->sk_state == TCP_LISTEN)) { res = -EADDRNOTAVAIL; - dev_put(dev); + break; + } + + dev = dev_get_by_name(&init_net, devname); + if (!dev) { + res = -ENODEV; break; } ax25->ax25_dev = ax25_dev_ax25dev(dev); ax25_fillin_cb(ax25, ax25->ax25_dev); + dev_put(dev); break; default: -- cgit v1.2.3 From 30df94f800368a016d09ee672c9fcc20751d0260 Mon Sep 17 00:00:00 2001 From: Jeff Hansen Date: Mon, 28 Sep 2009 12:54:25 -0700 Subject: bridge: Fix double-free in br_add_if. There is a potential double-kfree in net/bridge/br_if.c. If br_fdb_insert fails, then the kobject is put back (which calls kfree due to the kobject release), and then kfree is called again on the net_bridge_port. This patch fixes the crash. Thanks to Stephen Hemminger for the one-line fix. Signed-off-by: Jeff Hansen Signed-off-by: David S. Miller --- net/bridge/br_if.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 142ebac1417..b1b3b0fbf41 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -432,6 +432,7 @@ err2: br_fdb_delete_by_port(br, p, 1); err1: kobject_put(&p->kobj); + p = NULL; /* kobject_put frees */ err0: dev_set_promiscuity(dev, -1); put_back: -- cgit v1.2.3 From 47379052b5c87707bc6e20a2a4f6ac156fb8357c Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 28 Sep 2009 12:57:44 -0700 Subject: net: Add explicit bound checks in net/socket.c The sys_socketcall() function has a very clever system for the copy size of its arguments. Unfortunately, gcc cannot deal with this in terms of proving that the copy_from_user() is then always in bounds. This is the last (well 9th of this series, but last in the kernel) such case around. With this patch, we can turn on code to make having the boundary provably right for the whole kernel, and detect introduction of new security accidents of this type early on. Signed-off-by: Arjan van de Ven Signed-off-by: David S. Miller --- net/socket.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/socket.c b/net/socket.c index 49917a1cac7..41e8847508a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2098,12 +2098,17 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) unsigned long a[6]; unsigned long a0, a1; int err; + unsigned int len; if (call < 1 || call > SYS_ACCEPT4) return -EINVAL; + len = nargs[call]; + if (len > sizeof(a)) + return -EINVAL; + /* copy_from_user should be SMP safe. */ - if (copy_from_user(a, args, nargs[call])) + if (copy_from_user(a, args, len)) return -EFAULT; audit_socketcall(nargs[call] / sizeof(unsigned long), a); -- cgit v1.2.3 From 33de4f9d787e01646f715ac10c2699fb98fd479e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 17 Sep 2009 08:35:54 -0700 Subject: cfg80211: wext: don't display BSSID unless associated Currently, cfg80211's SIOCGIWAP implementation returns the BSSID that the user set, even if the connection has since been dropped due to other changes. It only should return the current BSSID when actually connected. Also do a small code cleanup. Reported-by: Thomas H. Guenther Signed-off-by: Johannes Berg Tested-by: Thomas H. Guenther Signed-off-by: John W. Linville --- net/wireless/wext-sme.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'net') diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index bf725275eb8..53c6ba98dc2 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -229,8 +229,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, data->flags = 1; data->length = wdev->wext.connect.ssid_len; memcpy(ssid, wdev->wext.connect.ssid, data->length); - } else - data->flags = 0; + } wdev_unlock(wdev); return 0; @@ -306,8 +305,6 @@ int cfg80211_mgd_wext_giwap(struct net_device *dev, wdev_lock(wdev); if (wdev->current_bss) memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); - else if (wdev->wext.connect.bssid) - memcpy(ap_addr->sa_data, wdev->wext.connect.bssid, ETH_ALEN); else memset(ap_addr->sa_data, 0, ETH_ALEN); wdev_unlock(wdev); -- cgit v1.2.3 From 4be3bd8ccc195297870b9ffca4ef18bcbc2f1822 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Sep 2009 09:00:57 +0200 Subject: cfg80211: don't set privacy w/o key When wpa_supplicant is used to connect to open networks, it causes the wdev->wext.keys to point to key memory, but that key memory is all empty. Only use privacy when there is a default key to be used. Signed-off-by: Johannes Berg Tested-by: Luis R. Rodriguez Tested-by: Kalle Valo Signed-off-by: John W. Linville --- net/wireless/wext-sme.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 53c6ba98dc2..5615a880253 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -30,7 +30,8 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, if (wdev->wext.keys) { wdev->wext.keys->def = wdev->wext.default_key; wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; - wdev->wext.connect.privacy = true; + if (wdev->wext.default_key != -1) + wdev->wext.connect.privacy = true; } if (!wdev->wext.connect.ssid_len) -- cgit v1.2.3 From 8bb894859e9495a94f94af3ee4711c89cdf24a95 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 26 Sep 2009 14:42:53 +0200 Subject: cfg80211: always get BSS Multiple problems were reported due to interaction between wpa_supplicant and the wext compat code in cfg80211, which appear to be due to it not getting any bss pointer here when wpa_supplicant sets all parameters -- do that now. We should still get the bss after doing an extra scan, but that appears to increase the time we need for connecting enough to sometimes cause timeouts. Signed-off-by: Johannes Berg Tested-by: Hin-Tak Leung , Signed-off-by: John W. Linville --- net/wireless/sme.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 7fae7eee65d..93c3ed32920 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -762,9 +762,8 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, wdev->conn->params.ssid = wdev->ssid; wdev->conn->params.ssid_len = connect->ssid_len; - /* don't care about result -- but fill bssid & channel */ - if (!wdev->conn->params.bssid || !wdev->conn->params.channel) - bss = cfg80211_get_conn_bss(wdev); + /* see if we have the bss already */ + bss = cfg80211_get_conn_bss(wdev); wdev->sme_state = CFG80211_SME_CONNECTING; wdev->connect_keys = connkeys; -- cgit v1.2.3 From 0ff716136ab73d2fc1edc0664e38169e7a76bb9a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 26 Sep 2009 14:45:41 +0200 Subject: mac80211: improve/fix mlme messages It's useful to know the MAC address when being disassociated; fix a typo (missing colon) and move some messages so we get them only when they are actually taking effect. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 97a278a2f48..8d26e9bf896 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1388,8 +1388,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", - sdata->dev->name, reason_code); + printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", + sdata->dev->name, mgmt->sa, reason_code); ieee80211_set_disassoc(sdata, false); return RX_MGMT_CFG80211_DISASSOC; @@ -1675,7 +1675,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, /* direct probe may be part of the association flow */ if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) { - printk(KERN_DEBUG "%s direct probe responded\n", + printk(KERN_DEBUG "%s: direct probe responded\n", sdata->dev->name); wk->tries = 0; wk->state = IEEE80211_MGD_STATE_AUTH; @@ -2502,9 +2502,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgd_work *wk; const u8 *bssid = NULL; - printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", - sdata->dev->name, req->reason_code); - mutex_lock(&ifmgd->mtx); if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { @@ -2532,6 +2529,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, mutex_unlock(&ifmgd->mtx); + printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", + sdata->dev->name, bssid, req->reason_code); + ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH, req->reason_code, cookie); @@ -2545,9 +2545,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", - sdata->dev->name, req->reason_code); - mutex_lock(&ifmgd->mtx); /* @@ -2561,6 +2558,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, return -ENOLINK; } + printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", + sdata->dev->name, req->bss->bssid, req->reason_code); + ieee80211_set_disassoc(sdata, false); mutex_unlock(&ifmgd->mtx); -- cgit v1.2.3 From 8503bd8c7dc6f82ec2de9d05e0a476e6ca5adc8b Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 26 Sep 2009 20:51:14 +0200 Subject: wext: Add bound checks for copy_from_user The wireless extensions have a copy_from_user to a local stack array "essid", but both me and gcc have failed to find where the bounds for this copy are located in the code. This patch adds some basic sanity checks for the copy length to make sure that we don't overflow the stack buffer. Signed-off-by: Arjan van de Ven Cc: linux-wireless@vger.kernel.org Signed-off-by: John W. Linville --- net/wireless/wext.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/wireless/wext.c b/net/wireless/wext.c index 5b4a0cee441..ac4ac26b53c 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -773,10 +773,13 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, essid_compat = 1; else if (IW_IS_SET(cmd) && (iwp->length != 0)) { char essid[IW_ESSID_MAX_SIZE + 1]; + unsigned int len; + len = iwp->length * descr->token_size; - err = copy_from_user(essid, iwp->pointer, - iwp->length * - descr->token_size); + if (len > IW_ESSID_MAX_SIZE) + return -EFAULT; + + err = copy_from_user(essid, iwp->pointer, len); if (err) return -EFAULT; -- cgit v1.2.3 From 8f1546cadf7ac5e9a40d54089a1c7302264ec49b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 28 Sep 2009 15:26:43 +0200 Subject: wext: add back wireless/ dir in sysfs for cfg80211 interfaces The move away from having drivers assign wireless handlers, in favour of making cfg80211 assign them, broke the sysfs registration (the wireless/ dir went missing) because the handlers are now assigned only after registration, which is too late. Fix this by special-casing cfg80211-based devices, all of which are required to have an ieee80211_ptr, in the sysfs code, and also using get_wireless_stats() to have the same values reported as in procfs. Signed-off-by: Johannes Berg Reported-by: Hugh Dickins Tested-by: Hugh Dickins Signed-off-by: John W. Linville --- net/core/net-sysfs.c | 12 +++++------- net/wireless/wext.c | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 7d4c57523b0..821d30918cf 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "net-sysfs.h" @@ -363,15 +363,13 @@ static ssize_t wireless_show(struct device *d, char *buf, char *)) { struct net_device *dev = to_net_dev(d); - const struct iw_statistics *iw = NULL; + const struct iw_statistics *iw; ssize_t ret = -EINVAL; read_lock(&dev_base_lock); if (dev_isalive(dev)) { - if (dev->wireless_handlers && - dev->wireless_handlers->get_wireless_stats) - iw = dev->wireless_handlers->get_wireless_stats(dev); - if (iw != NULL) + iw = get_wireless_stats(dev); + if (iw) ret = (*format)(iw, buf); } read_unlock(&dev_base_lock); @@ -505,7 +503,7 @@ int netdev_register_kobject(struct net_device *net) *groups++ = &netstat_group; #ifdef CONFIG_WIRELESS_EXT_SYSFS - if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats) + if (net->wireless_handlers || net->ieee80211_ptr) *groups++ = &wireless_group; #endif #endif /* CONFIG_SYSFS */ diff --git a/net/wireless/wext.c b/net/wireless/wext.c index ac4ac26b53c..60fe57761ca 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -470,7 +470,7 @@ static iw_handler get_handler(struct net_device *dev, unsigned int cmd) /* * Get statistics out of the driver */ -static struct iw_statistics *get_wireless_stats(struct net_device *dev) +struct iw_statistics *get_wireless_stats(struct net_device *dev) { /* New location */ if ((dev->wireless_handlers != NULL) && -- cgit v1.2.3 From b7058842c940ad2c08dd829b21e5c92ebe3b8758 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 30 Sep 2009 16:12:20 -0700 Subject: net: Make setsockopt() optlen be unsigned. This provides safety against negative optlen at the type level instead of depending upon (sometimes non-trivial) checks against this sprinkled all over the the place, in each and every implementation. Based upon work done by Arjan van de Ven and feedback from Linus Torvalds. Signed-off-by: David S. Miller --- net/atm/common.c | 2 +- net/atm/common.h | 2 +- net/atm/pvc.c | 2 +- net/atm/svc.c | 2 +- net/ax25/af_ax25.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/bluetooth/l2cap.c | 4 +-- net/bluetooth/rfcomm/sock.c | 4 +-- net/bluetooth/sco.c | 2 +- net/can/raw.c | 2 +- net/compat.c | 12 ++++---- net/core/sock.c | 8 +++--- net/dccp/dccp.h | 4 +-- net/dccp/proto.c | 10 +++---- net/decnet/af_decnet.c | 6 ++-- net/ieee802154/dgram.c | 2 +- net/ieee802154/raw.c | 2 +- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/ip_sockglue.c | 6 ++-- net/ipv4/ipmr.c | 2 +- net/ipv4/raw.c | 6 ++-- net/ipv4/tcp.c | 6 ++-- net/ipv4/udp.c | 6 ++-- net/ipv4/udp_impl.h | 4 +-- net/ipv6/ip6mr.c | 2 +- net/ipv6/ipv6_sockglue.c | 6 ++-- net/ipv6/raw.c | 6 ++-- net/ipv6/udp.c | 4 +-- net/ipv6/udp_impl.h | 4 +-- net/ipx/af_ipx.c | 2 +- net/irda/af_irda.c | 2 +- net/iucv/af_iucv.c | 2 +- net/llc/af_llc.c | 2 +- net/netfilter/nf_sockopt.c | 4 +-- net/netlink/af_netlink.c | 2 +- net/netrom/af_netrom.c | 2 +- net/packet/af_packet.c | 2 +- net/phonet/pep.c | 2 +- net/rds/af_rds.c | 2 +- net/rose/af_rose.c | 2 +- net/rxrpc/af_rxrpc.c | 2 +- net/sctp/socket.c | 62 ++++++++++++++++++++++------------------- net/socket.c | 2 +- net/tipc/socket.c | 2 +- net/x25/af_x25.c | 2 +- 45 files changed, 110 insertions(+), 106 deletions(-) (limited to 'net') diff --git a/net/atm/common.c b/net/atm/common.c index 8c4d843eb17..950bd16d238 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -679,7 +679,7 @@ static int check_qos(const struct atm_qos *qos) } int vcc_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct atm_vcc *vcc; unsigned long value; diff --git a/net/atm/common.h b/net/atm/common.h index 92e2981f479..f48a76b6cdf 100644 --- a/net/atm/common.h +++ b/net/atm/common.h @@ -21,7 +21,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait); int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int vcc_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); int vcc_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen); diff --git a/net/atm/pvc.c b/net/atm/pvc.c index e1d22d9430d..d4c024504f9 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c @@ -59,7 +59,7 @@ static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr, } static int pvc_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int error; diff --git a/net/atm/svc.c b/net/atm/svc.c index 7b831b526d0..f90d143c4b2 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c @@ -446,7 +446,7 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos) static int svc_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct atm_vcc *vcc = ATM_SD(sock); diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 4102de1022e..cd1c3dc0fe0 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -534,7 +534,7 @@ ax25_cb *ax25_create_cb(void) */ static int ax25_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; ax25_cb *ax25; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 4f9621f759a..75302a98606 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -466,7 +466,7 @@ drop: goto done; } -static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len) +static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len) { struct hci_ufilter uf = { .opcode = 0 }; struct sock *sk = sock->sk; diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index b0301256464..555d9da1869 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1698,7 +1698,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms return bt_sock_recvmsg(iocb, sock, msg, len, flags); } -static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) +static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct l2cap_options opts; @@ -1755,7 +1755,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us return err; } -static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) +static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct bt_security sec; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 0b85e811685..8a20aaf1f23 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -730,7 +730,7 @@ out: return copied ? : err; } -static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) +static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int err = 0; @@ -766,7 +766,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u return err; } -static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) +static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct bt_security sec; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 13c27f17192..77f4153bdb5 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -644,7 +644,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, return err; } -static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) +static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int err = 0; diff --git a/net/can/raw.c b/net/can/raw.c index db3152df7d2..b5e897922d3 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -411,7 +411,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr, } static int raw_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct raw_sock *ro = raw_sk(sk); diff --git a/net/compat.c b/net/compat.c index 12728b17a22..a407c3addba 100644 --- a/net/compat.c +++ b/net/compat.c @@ -331,7 +331,7 @@ struct compat_sock_fprog { }; static int do_set_attach_filter(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval; struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog)); @@ -351,7 +351,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname, } static int do_set_sock_timeout(struct socket *sock, int level, - int optname, char __user *optval, int optlen) + int optname, char __user *optval, unsigned int optlen) { struct compat_timeval __user *up = (struct compat_timeval __user *) optval; struct timeval ktime; @@ -373,7 +373,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, } static int compat_sock_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (optname == SO_ATTACH_FILTER) return do_set_attach_filter(sock, level, optname, @@ -385,7 +385,7 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname, } asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { int err; struct socket *sock; @@ -558,8 +558,8 @@ struct compat_group_filter { int compat_mc_setsockopt(struct sock *sock, int level, int optname, - char __user *optval, int optlen, - int (*setsockopt)(struct sock *,int,int,char __user *,int)) + char __user *optval, unsigned int optlen, + int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int)) { char __user *koptval = optval; int koptlen = optlen; diff --git a/net/core/sock.c b/net/core/sock.c index 524712a7b15..77fbfed332e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -446,7 +446,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) */ int sock_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int val; @@ -1697,7 +1697,7 @@ int sock_no_shutdown(struct socket *sock, int how) EXPORT_SYMBOL(sock_no_shutdown); int sock_no_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { return -EOPNOTSUPP; } @@ -2018,7 +2018,7 @@ EXPORT_SYMBOL(sock_common_recvmsg); * Set socket options on an inet socket. */ int sock_common_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; @@ -2028,7 +2028,7 @@ EXPORT_SYMBOL(sock_common_setsockopt); #ifdef CONFIG_COMPAT int compat_sock_common_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index d6bc47363b1..5ef32c2f0d6 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -290,14 +290,14 @@ extern int dccp_disconnect(struct sock *sk, int flags); extern int dccp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int dccp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); #ifdef CONFIG_COMPAT extern int compat_dccp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int compat_dccp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); #endif extern int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, diff --git a/net/dccp/proto.c b/net/dccp/proto.c index bc4467082a0..a156319fd0a 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -393,7 +393,7 @@ out: EXPORT_SYMBOL_GPL(dccp_ioctl); static int dccp_setsockopt_service(struct sock *sk, const __be32 service, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct dccp_sock *dp = dccp_sk(sk); struct dccp_service_list *sl = NULL; @@ -464,7 +464,7 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx) } static int dccp_setsockopt_ccid(struct sock *sk, int type, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { u8 *val; int rc = 0; @@ -494,7 +494,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type, } static int do_dccp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct dccp_sock *dp = dccp_sk(sk); int val, err = 0; @@ -546,7 +546,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, } int dccp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level != SOL_DCCP) return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level, @@ -559,7 +559,7 @@ EXPORT_SYMBOL_GPL(dccp_setsockopt); #ifdef CONFIG_COMPAT int compat_dccp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level != SOL_DCCP) return inet_csk_compat_setsockopt(sk, level, optname, diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 77d40289653..7a58c87baf1 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -157,7 +157,7 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; static struct hlist_head dn_wild_sk; static atomic_t decnet_memory_allocated; -static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags); +static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags); static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); static struct hlist_head *dn_find_list(struct sock *sk) @@ -1325,7 +1325,7 @@ out: return err; } -static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) +static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int err; @@ -1337,7 +1337,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use return err; } -static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags) +static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags) { struct sock *sk = sock->sk; struct dn_scp *scp = DN_SK(sk); diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 51593a48f2d..a413b1bf446 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname, } static int dgram_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct dgram_sock *ro = dgram_sk(sk); int val; diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 13198859982..30e74eee07d 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c @@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname, } static int raw_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { return -EOPNOTSUPP; } diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 22cd19ee44e..4351ca2cf0b 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -714,7 +714,7 @@ int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname, EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt); int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { const struct inet_connection_sock *icsk = inet_csk(sk); diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5a0693576e8..0c0b6e363a2 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -440,7 +440,7 @@ out: */ static int do_ip_setsockopt(struct sock *sk, int level, - int optname, char __user *optval, int optlen) + int optname, char __user *optval, unsigned int optlen) { struct inet_sock *inet = inet_sk(sk); int val = 0, err; @@ -950,7 +950,7 @@ e_inval: } int ip_setsockopt(struct sock *sk, int level, - int optname, char __user *optval, int optlen) + int optname, char __user *optval, unsigned int optlen) { int err; @@ -975,7 +975,7 @@ EXPORT_SYMBOL(ip_setsockopt); #ifdef CONFIG_COMPAT int compat_ip_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { int err; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c43ec2d51ce..630a56df7b4 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -931,7 +931,7 @@ static void mrtsock_destruct(struct sock *sk) * MOSPF/PIM router set up we can clean this up. */ -int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen) +int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen) { int ret; struct vifctl vif; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index ebb1e5848bc..757c9171e7c 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -741,7 +741,7 @@ out: return ret; } static int do_raw_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (optname == ICMP_FILTER) { if (inet_sk(sk)->num != IPPROTO_ICMP) @@ -753,7 +753,7 @@ static int do_raw_setsockopt(struct sock *sk, int level, int optname, } static int raw_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level != SOL_RAW) return ip_setsockopt(sk, level, optname, optval, optlen); @@ -762,7 +762,7 @@ static int raw_setsockopt(struct sock *sk, int level, int optname, #ifdef CONFIG_COMPAT static int compat_raw_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level != SOL_RAW) return compat_ip_setsockopt(sk, level, optname, optval, optlen); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 21387ebabf0..5a15e7629d8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2032,7 +2032,7 @@ int tcp_disconnect(struct sock *sk, int flags) * Socket option code for TCP. */ static int do_tcp_setsockopt(struct sock *sk, int level, - int optname, char __user *optval, int optlen) + int optname, char __user *optval, unsigned int optlen) { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); @@ -2220,7 +2220,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, } int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, - int optlen) + unsigned int optlen) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -2232,7 +2232,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, #ifdef CONFIG_COMPAT int compat_tcp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level != SOL_TCP) return inet_csk_compat_setsockopt(sk, level, optname, diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ebaaa7f973d..3326aff6590 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1359,7 +1359,7 @@ void udp_destroy_sock(struct sock *sk) * Socket option code for UDP */ int udp_lib_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen, + char __user *optval, unsigned int optlen, int (*push_pending_frames)(struct sock *)) { struct udp_sock *up = udp_sk(sk); @@ -1441,7 +1441,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, EXPORT_SYMBOL(udp_lib_setsockopt); int udp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level == SOL_UDP || level == SOL_UDPLITE) return udp_lib_setsockopt(sk, level, optname, optval, optlen, @@ -1451,7 +1451,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname, #ifdef CONFIG_COMPAT int compat_udp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level == SOL_UDP || level == SOL_UDPLITE) return udp_lib_setsockopt(sk, level, optname, optval, optlen, diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index 9f4a6165f72..aaad650d47d 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h @@ -11,13 +11,13 @@ extern void __udp4_lib_err(struct sk_buff *, u32, struct udp_table *); extern int udp_v4_get_port(struct sock *sk, unsigned short snum); extern int udp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); extern int udp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); #ifdef CONFIG_COMPAT extern int compat_udp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); extern int compat_udp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); #endif diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 090675e269e..716153941fc 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1281,7 +1281,7 @@ int ip6mr_sk_done(struct sock *sk) * MOSPF/PIM router set up we can clean this up. */ -int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen) +int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen) { int ret; struct mif6ctl vif; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index f5e0682b402..14f54eb5a7f 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -123,7 +123,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, } static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct ipv6_pinfo *np = inet6_sk(sk); struct net *net = sock_net(sk); @@ -773,7 +773,7 @@ e_inval: } int ipv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { int err; @@ -801,7 +801,7 @@ EXPORT_SYMBOL(ipv6_setsockopt); #ifdef CONFIG_COMPAT int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { int err; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 7d675b8d82d..4f24570b086 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -957,7 +957,7 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct raw6_sock *rp = raw6_sk(sk); int val; @@ -1000,7 +1000,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, } static int rawv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { switch(level) { case SOL_RAW: @@ -1024,7 +1024,7 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname, #ifdef CONFIG_COMPAT static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { switch (level) { case SOL_RAW: diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b265b7047d3..3a60f12b34e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1044,7 +1044,7 @@ void udpv6_destroy_sock(struct sock *sk) * Socket option code for UDP */ int udpv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level == SOL_UDP || level == SOL_UDPLITE) return udp_lib_setsockopt(sk, level, optname, optval, optlen, @@ -1054,7 +1054,7 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname, #ifdef CONFIG_COMPAT int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { if (level == SOL_UDP || level == SOL_UDPLITE) return udp_lib_setsockopt(sk, level, optname, optval, optlen, diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 6bb303471e2..d7571046bfc 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h @@ -16,10 +16,10 @@ extern int udp_v6_get_port(struct sock *sk, unsigned short snum); extern int udpv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int udpv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); #ifdef CONFIG_COMPAT extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen); + char __user *optval, unsigned int optlen); extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); #endif diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index f1118d92a19..66c7a20011f 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1292,7 +1292,7 @@ const char *ipx_device_name(struct ipx_interface *intrfc) * socket object. */ static int ipx_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int opt; diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 50b43c57d5d..dd35641835f 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1826,7 +1826,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon * */ static int irda_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index d985d163dcf..bada1b9c670 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -1387,7 +1387,7 @@ static int iucv_sock_release(struct socket *sock) /* getsockopt and setsockopt */ static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct iucv_sock *iucv = iucv_sk(sk); diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index c45eee1c0e8..7aa4fd17010 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -973,7 +973,7 @@ static int llc_ui_ioctl(struct socket *sock, unsigned int cmd, * Set various connection specific parameters. */ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct llc_sock *llc = llc_sk(sk); diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c index 8ab829f8657..f042ae52155 100644 --- a/net/netfilter/nf_sockopt.c +++ b/net/netfilter/nf_sockopt.c @@ -113,7 +113,7 @@ static int nf_sockopt(struct sock *sk, u_int8_t pf, int val, } int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, - int len) + unsigned int len) { return nf_sockopt(sk, pf, val, opt, &len, 0); } @@ -154,7 +154,7 @@ static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val, } int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, - int val, char __user *opt, int len) + int val, char __user *opt, unsigned int len) { return compat_nf_sockopt(sk, pf, val, opt, &len, 0); } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index dd85320907c..19e98007691 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1150,7 +1150,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk, } static int netlink_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct netlink_sock *nlk = nlk_sk(sk); diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index ce1a34b99c2..7a834952f67 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -301,7 +301,7 @@ void nr_destroy_socket(struct sock *sk) */ static int nr_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct nr_sock *nr = nr_sk(sk); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d3d52c66cdc..1238949e66a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1701,7 +1701,7 @@ static void packet_flush_mclist(struct sock *sk) } static int -packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) +packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct packet_sock *po = pkt_sk(sk); diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b8252d289cd..5f32d217535 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -742,7 +742,7 @@ static int pep_init(struct sock *sk) } static int pep_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct pep_sock *pn = pep_sk(sk); int val = 0, err = 0; diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 6b58aeff4c7..98e05382fd3 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -248,7 +248,7 @@ static int rds_cong_monitor(struct rds_sock *rs, char __user *optval, } static int rds_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct rds_sock *rs = rds_sk_to_rs(sock->sk); int ret; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 1e166c9685a..502cce76621 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -370,7 +370,7 @@ void rose_destroy_socket(struct sock *sk) */ static int rose_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct rose_sock *rose = rose_sk(sk); diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index bfe493ebf27..a86afceaa94 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -507,7 +507,7 @@ out: * set RxRPC socket options */ static int rxrpc_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct rxrpc_sock *rx = rxrpc_sk(sock->sk); unsigned min_sec_level; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 89af37a6c87..c8d05758661 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2027,7 +2027,8 @@ out: * instead a error will be indicated to the user. */ static int sctp_setsockopt_disable_fragments(struct sock *sk, - char __user *optval, int optlen) + char __user *optval, + unsigned int optlen) { int val; @@ -2043,7 +2044,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, } static int sctp_setsockopt_events(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { if (optlen > sizeof(struct sctp_event_subscribe)) return -EINVAL; @@ -2064,7 +2065,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, * association is closed. */ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_sock *sp = sctp_sk(sk); @@ -2318,7 +2319,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, } static int sctp_setsockopt_peer_addr_params(struct sock *sk, - char __user *optval, int optlen) + char __user *optval, + unsigned int optlen) { struct sctp_paddrparams params; struct sctp_transport *trans = NULL; @@ -2430,7 +2432,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk, */ static int sctp_setsockopt_delayed_ack(struct sock *sk, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { struct sctp_sack_info params; struct sctp_transport *trans = NULL; @@ -2546,7 +2548,7 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, * by the change). With TCP-style sockets, this option is inherited by * sockets derived from a listener socket. */ -static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int optlen) +static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen) { struct sctp_initmsg sinit; struct sctp_sock *sp = sctp_sk(sk); @@ -2583,7 +2585,8 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int opt * to this call if the caller is using the UDP model. */ static int sctp_setsockopt_default_send_param(struct sock *sk, - char __user *optval, int optlen) + char __user *optval, + unsigned int optlen) { struct sctp_sndrcvinfo info; struct sctp_association *asoc; @@ -2622,7 +2625,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, * association peer's addresses. */ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_prim prim; struct sctp_transport *trans; @@ -2651,7 +2654,7 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, * integer boolean flag. */ static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { int val; @@ -2676,7 +2679,8 @@ static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, * be changed. * */ -static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int optlen) { +static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen) +{ struct sctp_rtoinfo rtoinfo; struct sctp_association *asoc; @@ -2728,7 +2732,7 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int opt * See [SCTP] for more information. * */ -static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int optlen) +static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen) { struct sctp_assocparams assocparams; @@ -2800,7 +2804,7 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o * addresses and a user will receive both PF_INET6 and PF_INET type * addresses on the socket. */ -static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int optlen) +static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen) { int val; struct sctp_sock *sp = sctp_sk(sk); @@ -2844,7 +2848,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op * changed (effecting future associations only). * assoc_value: This parameter specifies the maximum size in bytes. */ -static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen) +static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen) { struct sctp_assoc_value params; struct sctp_association *asoc; @@ -2899,7 +2903,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl * set primary request: */ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_sock *sp; struct sctp_endpoint *ep; @@ -2950,7 +2954,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva } static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_setadaptation adaptation; @@ -2979,7 +2983,7 @@ static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval * saved with outbound messages. */ static int sctp_setsockopt_context(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_assoc_value params; struct sctp_sock *sp; @@ -3030,7 +3034,7 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval, */ static int sctp_setsockopt_fragment_interleave(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { int val; @@ -3063,7 +3067,7 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk, */ static int sctp_setsockopt_partial_delivery_point(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { u32 val; @@ -3096,7 +3100,7 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk, */ static int sctp_setsockopt_maxburst(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_assoc_value params; struct sctp_sock *sp; @@ -3140,8 +3144,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, * will only effect future associations on the socket. */ static int sctp_setsockopt_auth_chunk(struct sock *sk, - char __user *optval, - int optlen) + char __user *optval, + unsigned int optlen) { struct sctp_authchunk val; @@ -3172,8 +3176,8 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, * endpoint requires the peer to use. */ static int sctp_setsockopt_hmac_ident(struct sock *sk, - char __user *optval, - int optlen) + char __user *optval, + unsigned int optlen) { struct sctp_hmacalgo *hmacs; u32 idents; @@ -3215,7 +3219,7 @@ out: */ static int sctp_setsockopt_auth_key(struct sock *sk, char __user *optval, - int optlen) + unsigned int optlen) { struct sctp_authkey *authkey; struct sctp_association *asoc; @@ -3260,8 +3264,8 @@ out: * the association shared key. */ static int sctp_setsockopt_active_key(struct sock *sk, - char __user *optval, - int optlen) + char __user *optval, + unsigned int optlen) { struct sctp_authkeyid val; struct sctp_association *asoc; @@ -3288,8 +3292,8 @@ static int sctp_setsockopt_active_key(struct sock *sk, * This set option will delete a shared secret key from use. */ static int sctp_setsockopt_del_key(struct sock *sk, - char __user *optval, - int optlen) + char __user *optval, + unsigned int optlen) { struct sctp_authkeyid val; struct sctp_association *asoc; @@ -3332,7 +3336,7 @@ static int sctp_setsockopt_del_key(struct sock *sk, * optlen - the size of the buffer. */ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { int retval = 0; diff --git a/net/socket.c b/net/socket.c index 41e8847508a..75655365b5f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2391,7 +2391,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, } int kernel_setsockopt(struct socket *sock, int level, int optname, - char *optval, int optlen) + char *optval, unsigned int optlen) { mm_segment_t oldfs = get_fs(); int err; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e8254e809b7..e6d9abf7440 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1658,7 +1658,7 @@ restart: */ static int setsockopt(struct socket *sock, - int lvl, int opt, char __user *ov, int ol) + int lvl, int opt, char __user *ov, unsigned int ol) { struct sock *sk = sock->sk; struct tipc_port *tport = tipc_sk_port(sk); diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 5e6c072c64d..7fa9c7ad3d3 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -409,7 +409,7 @@ static void x25_destroy_socket(struct sock *sk) */ static int x25_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, int optlen) + char __user *optval, unsigned int optlen) { int opt; struct sock *sk = sock->sk; -- cgit v1.2.3 From d99927f4d93f36553699573b279e0ff98ad7dea6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 24 Sep 2009 10:49:24 +0000 Subject: net: Fix sock_wfree() race Commit 2b85a34e911bf483c27cfdd124aeb1605145dc80 (net: No more expensive sock_hold()/sock_put() on each tx) opens a window in sock_wfree() where another cpu might free the socket we are working on. A fix is to call sk->sk_write_space(sk) while still holding a reference on sk. Reported-by: Jike Song Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/sock.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/net/core/sock.c b/net/core/sock.c index 77fbfed332e..7626b6aacd6 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1228,17 +1228,22 @@ void __init sk_init(void) void sock_wfree(struct sk_buff *skb) { struct sock *sk = skb->sk; - int res; + unsigned int len = skb->truesize; - /* In case it might be waiting for more memory. */ - res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); - if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) + if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) { + /* + * Keep a reference on sk_wmem_alloc, this will be released + * after sk_write_space() call + */ + atomic_sub(len - 1, &sk->sk_wmem_alloc); sk->sk_write_space(sk); + len = 1; + } /* - * if sk_wmem_alloc reached 0, we are last user and should - * free this sock, as sk_free() call could not do it. + * if sk_wmem_alloc reaches 0, we must finish what sk_free() + * could not do because of in-flight packets */ - if (res == 0) + if (atomic_sub_and_test(len, &sk->sk_wmem_alloc)) __sk_free(sk); } EXPORT_SYMBOL(sock_wfree); -- cgit v1.2.3 From 298bf12ddb25841804f26234a43b89da1b1c0e21 Mon Sep 17 00:00:00 2001 From: Sascha Hlusiak Date: Tue, 29 Sep 2009 11:27:05 +0000 Subject: sit: fix off-by-one in ipip6_tunnel_get_prl When requesting all prl entries (kprl.addr == INADDR_ANY) and there are more prl entries than there is space passed from userspace, the existing code would always copy cmax+1 entries, which is more than can be handled. This patch makes the kernel copy only exactly cmax entries. Signed-off-by: Sascha Hlusiak Acked-By: Fred L. Templin Signed-off-by: David S. Miller --- net/ipv6/sit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d65e0c496cc..dbd19a78ca7 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -274,7 +274,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t, c = 0; for (prl = t->prl; prl; prl = prl->next) { - if (c > cmax) + if (c >= cmax) break; if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) continue; -- cgit v1.2.3 From 013820a360b63a0a18fa13afb858b9f1af7e64fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Wed, 30 Sep 2009 16:41:34 -0700 Subject: Phonet: fix mutex imbalance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Rémi Denis-Courmont port_mutex was unlocked twice. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/socket.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net') diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 07aa9f08d5f..aa5b5a972bf 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -407,7 +407,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport) return -EADDRINUSE; found: - mutex_unlock(&port_mutex); pn->sobject = pn_object(pn_addr(pn->sobject), sport); return 0; } -- cgit v1.2.3 From 81bbb3d4048cf577b5babcb0834230de391a35c5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 30 Sep 2009 16:42:42 -0700 Subject: net: restore tx timestamping for accelerated vlans Since commit 9b22ea560957de1484e6b3e8538f7eef202e3596 ( net: fix packet socket delivery in rx irq handler ) We lost rx timestamping of packets received on accelerated vlans. Effect is that tcpdump on real dev can show strange timings, since it gets rx timestamps too late (ie at skb dequeueing time, not at skb queueing time) 14:47:26.986871 IP 192.168.20.110 > 192.168.20.141: icmp 64: echo request seq 1 14:47:26.986786 IP 192.168.20.141 > 192.168.20.110: icmp 64: echo reply seq 1 14:47:27.986888 IP 192.168.20.110 > 192.168.20.141: icmp 64: echo request seq 2 14:47:27.986781 IP 192.168.20.141 > 192.168.20.110: icmp 64: echo reply seq 2 14:47:28.986896 IP 192.168.20.110 > 192.168.20.141: icmp 64: echo request seq 3 14:47:28.986780 IP 192.168.20.141 > 192.168.20.110: icmp 64: echo reply seq 3 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/core/dev.c b/net/core/dev.c index 560c8c9c03a..b8f74cfb1bf 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2288,6 +2288,9 @@ int netif_receive_skb(struct sk_buff *skb) int ret = NET_RX_DROP; __be16 type; + if (!skb->tstamp.tv64) + net_timestamp(skb); + if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) return NET_RX_SUCCESS; @@ -2295,9 +2298,6 @@ int netif_receive_skb(struct sk_buff *skb) if (netpoll_receive_skb(skb)) return NET_RX_DROP; - if (!skb->tstamp.tv64) - net_timestamp(skb); - if (!skb->iif) skb->iif = skb->dev->ifindex; -- cgit v1.2.3 From 8c185ab6185bf5e67766edb000ce428269364c86 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Sun, 27 Sep 2009 10:57:02 +0000 Subject: ax25: Fix possible oops in ax25_make_new In ax25_make_new, if kmemdup of digipeat returns an error, there would be an oops in sk_free while calling sk_destruct, because sk_protinfo is NULL at the moment; move sk->sk_destruct initialization after this. BTW of reported-by: Bernard Pidoux F6BVP Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/ax25/af_ax25.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index cd1c3dc0fe0..f4546073037 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -901,7 +901,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) sock_init_data(NULL, sk); - sk->sk_destruct = ax25_free_sock; sk->sk_type = osk->sk_type; sk->sk_priority = osk->sk_priority; sk->sk_protocol = osk->sk_protocol; @@ -939,6 +938,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) } sk->sk_protinfo = ax25; + sk->sk_destruct = ax25_free_sock; ax25->sk = sk; return sk; -- cgit v1.2.3