]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
skb->sk is used in dev_pick_tx() which is called from dev_queue_xmit(). If
authorhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Mon, 6 Dec 2010 16:44:00 +0000 (16:44 +0000)
committerhartkopp <hartkopp@030b6a49-0b11-0410-94ab-b0dab22257f2>
Mon, 6 Dec 2010 16:44:00 +0000 (16:44 +0000)
sk points to an arbitrary magic value, dev_pick_tx() returns a wrong value,
which can lead to various memory corruption bugs.

In commit a4ee3ce3293dc931fab19beb472a8bde1295aebe dev_pick_tx() was
changed  to look the new field in socket called sk_tx_queue_mapping.

Original patch provided by Michal Sojka <sojkam1@fel.cvut.cz>

git-svn-id: svn://svn.berlios.de//socketcan/trunk@1223 030b6a49-0b11-0410-94ab-b0dab22257f2

kernel/2.6/net/can/gw.c

index e512427c697c7715a559a3f39f9a518c711ac1fc..e451b090288e2ba1f8d575ddd605e1b278a791a8 100644 (file)
@@ -58,6 +58,7 @@
 #include <socketcan/can/gw.h>
 #include <net/rtnetlink.h>
 #include <net/net_namespace.h>
+#include <net/sock.h>
 
 #include <socketcan/can/version.h> /* for RCSID. Removed by mkpatch script */
 RCSID("$Id$");
@@ -76,7 +77,7 @@ static struct notifier_block notifier;
 
 static struct kmem_cache *cgw_cache __read_mostly;
 
-#define CGW_SK_MAGIC ((void *)(&notifier))
+static struct sock gw_dummy_sk;
 
 /* structure that contains the (on-the-fly) CAN frame modifications */
 struct cf_mod {
@@ -346,7 +347,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
        int modidx = 0;
 
        /* do not handle already routed frames */
-       if (skb->sk == CGW_SK_MAGIC)
+       if (skb->sk == &gw_dummy_sk)
                return;
 
        if (!(gwj->dst.dev->flags & IFF_UP)) {
@@ -371,7 +372,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
        }
 
        /* mark routed frames with a 'special' sk value */
-       nskb->sk = CGW_SK_MAGIC;
+       nskb->sk = &gw_dummy_sk;
        nskb->dev = gwj->dst.dev;
 
        /* pointer to modifiable CAN frame */
@@ -928,6 +929,11 @@ static __init int cgw_module_init(void)
        notifier.notifier_call = cgw_notifier;
        register_netdevice_notifier(&notifier);
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
+       /* initialize struct for dev_pick_tx() */
+       sk_tx_queue_clear(&gw_dummy_sk);
+#endif
+
        if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs)) {
                unregister_netdevice_notifier(&notifier);
                kmem_cache_destroy(cgw_cache);