aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-07 12:24:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-07 12:24:28 -0400
commitb2798bf0ec2cb5a17bfc1430c5ba6d971c436a03 (patch)
treeef2b01160811d8d6312518a177968d58d5fe9e44 /net
parent3bc5ab9b7f2760d2892fd0a0589e1077e869d4f5 (diff)
parent7f2d38eb7a42bea1c1df51bbdaa2ca0f0bdda07f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: can: add sanity checks fs_enet: restore promiscuous and multicast settings in restart() ibm_newemac: Fixes entry of short packets ibm_newemac: Fixes kernel crashes when speed of cable connected changes pasemi_mac: Access iph->tot_len with correct endianness ehea: Access iph->tot_len with correct endianness ehea: fix race condition ehea: add MODULE_DEVICE_TABLE ehea: fix might sleep problem forcedeth: fix lockdep warning on ethtool -s Add missing skb->dev assignment in Frame Relay RX code bridge: fix use-after-free in br_cleanup_bridges() tcp: fix a size_t < 0 comparison in tcp_read_sock tcp: net/ipv4/tcp.c needs linux/scatterlist.h libertas: support USB persistence on suspend/resume (resend) iwlwifi: drop skb silently for Tx request in monitor mode iwlwifi: fix incorrect 5GHz rates reported in monitor mode
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_if.c10
-rw-r--r--net/can/af_can.c10
-rw-r--r--net/can/bcm.c23
-rw-r--r--net/can/raw.c3
-rw-r--r--net/ipv4/tcp.c4
5 files changed, 42 insertions, 8 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index c2397f503b0..f38cc5317b8 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -442,12 +442,16 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
442 442
443void __exit br_cleanup_bridges(void) 443void __exit br_cleanup_bridges(void)
444{ 444{
445 struct net_device *dev, *nxt; 445 struct net_device *dev;
446 446
447 rtnl_lock(); 447 rtnl_lock();
448 for_each_netdev_safe(&init_net, dev, nxt) 448restart:
449 if (dev->priv_flags & IFF_EBRIDGE) 449 for_each_netdev(&init_net, dev) {
450 if (dev->priv_flags & IFF_EBRIDGE) {
450 del_br(dev->priv); 451 del_br(dev->priv);
452 goto restart;
453 }
454 }
451 rtnl_unlock(); 455 rtnl_unlock();
452 456
453} 457}
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 7e8ca283645..484bbf6dd03 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -205,12 +205,19 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
205 * -ENOBUFS on full driver queue (see net_xmit_errno()) 205 * -ENOBUFS on full driver queue (see net_xmit_errno())
206 * -ENOMEM when local loopback failed at calling skb_clone() 206 * -ENOMEM when local loopback failed at calling skb_clone()
207 * -EPERM when trying to send on a non-CAN interface 207 * -EPERM when trying to send on a non-CAN interface
208 * -EINVAL when the skb->data does not contain a valid CAN frame
208 */ 209 */
209int can_send(struct sk_buff *skb, int loop) 210int can_send(struct sk_buff *skb, int loop)
210{ 211{
211 struct sk_buff *newskb = NULL; 212 struct sk_buff *newskb = NULL;
213 struct can_frame *cf = (struct can_frame *)skb->data;
212 int err; 214 int err;
213 215
216 if (skb->len != sizeof(struct can_frame) || cf->can_dlc > 8) {
217 kfree_skb(skb);
218 return -EINVAL;
219 }
220
214 if (skb->dev->type != ARPHRD_CAN) { 221 if (skb->dev->type != ARPHRD_CAN) {
215 kfree_skb(skb); 222 kfree_skb(skb);
216 return -EPERM; 223 return -EPERM;
@@ -605,6 +612,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
605 struct packet_type *pt, struct net_device *orig_dev) 612 struct packet_type *pt, struct net_device *orig_dev)
606{ 613{
607 struct dev_rcv_lists *d; 614 struct dev_rcv_lists *d;
615 struct can_frame *cf = (struct can_frame *)skb->data;
608 int matches; 616 int matches;
609 617
610 if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) { 618 if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) {
@@ -612,6 +620,8 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
612 return 0; 620 return 0;
613 } 621 }
614 622
623 BUG_ON(skb->len != sizeof(struct can_frame) || cf->can_dlc > 8);
624
615 /* update statistics */ 625 /* update statistics */
616 can_stats.rx_frames++; 626 can_stats.rx_frames++;
617 can_stats.rx_frames_delta++; 627 can_stats.rx_frames_delta++;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index d9a3a9d13be..72c2ce904f8 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -298,7 +298,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
298 298
299 if (head->nframes) { 299 if (head->nframes) {
300 /* can_frames starting here */ 300 /* can_frames starting here */
301 firstframe = (struct can_frame *) skb_tail_pointer(skb); 301 firstframe = (struct can_frame *)skb_tail_pointer(skb);
302 302
303 memcpy(skb_put(skb, datalen), frames, datalen); 303 memcpy(skb_put(skb, datalen), frames, datalen);
304 304
@@ -826,6 +826,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
826 for (i = 0; i < msg_head->nframes; i++) { 826 for (i = 0; i < msg_head->nframes; i++) {
827 err = memcpy_fromiovec((u8 *)&op->frames[i], 827 err = memcpy_fromiovec((u8 *)&op->frames[i],
828 msg->msg_iov, CFSIZ); 828 msg->msg_iov, CFSIZ);
829
830 if (op->frames[i].can_dlc > 8)
831 err = -EINVAL;
832
829 if (err < 0) 833 if (err < 0)
830 return err; 834 return err;
831 835
@@ -858,6 +862,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
858 for (i = 0; i < msg_head->nframes; i++) { 862 for (i = 0; i < msg_head->nframes; i++) {
859 err = memcpy_fromiovec((u8 *)&op->frames[i], 863 err = memcpy_fromiovec((u8 *)&op->frames[i],
860 msg->msg_iov, CFSIZ); 864 msg->msg_iov, CFSIZ);
865
866 if (op->frames[i].can_dlc > 8)
867 err = -EINVAL;
868
861 if (err < 0) { 869 if (err < 0) {
862 if (op->frames != &op->sframe) 870 if (op->frames != &op->sframe)
863 kfree(op->frames); 871 kfree(op->frames);
@@ -1164,9 +1172,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
1164 1172
1165 skb->dev = dev; 1173 skb->dev = dev;
1166 skb->sk = sk; 1174 skb->sk = sk;
1167 can_send(skb, 1); /* send with loopback */ 1175 err = can_send(skb, 1); /* send with loopback */
1168 dev_put(dev); 1176 dev_put(dev);
1169 1177
1178 if (err)
1179 return err;
1180
1170 return CFSIZ + MHSIZ; 1181 return CFSIZ + MHSIZ;
1171} 1182}
1172 1183
@@ -1185,6 +1196,10 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
1185 if (!bo->bound) 1196 if (!bo->bound)
1186 return -ENOTCONN; 1197 return -ENOTCONN;
1187 1198
1199 /* check for valid message length from userspace */
1200 if (size < MHSIZ || (size - MHSIZ) % CFSIZ)
1201 return -EINVAL;
1202
1188 /* check for alternative ifindex for this bcm_op */ 1203 /* check for alternative ifindex for this bcm_op */
1189 1204
1190 if (!ifindex && msg->msg_name) { 1205 if (!ifindex && msg->msg_name) {
@@ -1259,8 +1274,8 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
1259 break; 1274 break;
1260 1275
1261 case TX_SEND: 1276 case TX_SEND:
1262 /* we need at least one can_frame */ 1277 /* we need exactly one can_frame behind the msg head */
1263 if (msg_head.nframes < 1) 1278 if ((msg_head.nframes != 1) || (size != CFSIZ + MHSIZ))
1264 ret = -EINVAL; 1279 ret = -EINVAL;
1265 else 1280 else
1266 ret = bcm_tx_send(msg, ifindex, sk); 1281 ret = bcm_tx_send(msg, ifindex, sk);
diff --git a/net/can/raw.c b/net/can/raw.c
index 69877b8e7e9..3e46ee36a1a 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -632,6 +632,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
632 } else 632 } else
633 ifindex = ro->ifindex; 633 ifindex = ro->ifindex;
634 634
635 if (size != sizeof(struct can_frame))
636 return -EINVAL;
637
635 dev = dev_get_by_index(&init_net, ifindex); 638 dev = dev_get_by_index(&init_net, ifindex);
636 if (!dev) 639 if (!dev)
637 return -ENXIO; 640 return -ENXIO;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 850825dc86e..1d723de1868 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -255,6 +255,7 @@
255#include <linux/init.h> 255#include <linux/init.h>
256#include <linux/fs.h> 256#include <linux/fs.h>
257#include <linux/skbuff.h> 257#include <linux/skbuff.h>
258#include <linux/scatterlist.h>
258#include <linux/splice.h> 259#include <linux/splice.h>
259#include <linux/net.h> 260#include <linux/net.h>
260#include <linux/socket.h> 261#include <linux/socket.h>
@@ -1208,7 +1209,8 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
1208 return -ENOTCONN; 1209 return -ENOTCONN;
1209 while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { 1210 while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
1210 if (offset < skb->len) { 1211 if (offset < skb->len) {
1211 size_t used, len; 1212 int used;
1213 size_t len;
1212 1214
1213 len = skb->len - offset; 1215 len = skb->len - offset;
1214 /* Stop reading if we hit a patch of urgent data */ 1216 /* Stop reading if we hit a patch of urgent data */