From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
To: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: Fwd: Possible bug in net/ipv4/route.c?
Date: Fri, 02 Jul 2010 11:49:55 +0900 [thread overview]
Message-ID: <4C2D53D3.6050106@linux-ipv6.org> (raw)
Switch to netdev.
--yoshfuji
-------- Original Message --------
Subject: Possible bug in net/ipv4/route.c?
Date: Thu, 1 Jul 2010 16:00:29 -0700
From: Sol Kavy <skavy@ubicom.com>
To: <linux-kernel@vger.kernel.org>
CC: Greg Ren <gren@ubicom.com>, Guojun Jin <gjin@ubicom.com>, Murat Sezgin <msezgin@ubicom.com>, Sener Ilgen <silgen@ubicom.com>
Found Linux: 2.6.28
Arch: Ubicom32 <not yet pushed>
Project: uCLinux based Router
Test: Bit torrent Stress Test
Note: The top of Linus git net/ipv4/route.c appears to have the same issue.
The following is a patch for clearing out IP options area in an input skb during link failure processing. Without this patch, the icmp_send() can result in a call to ip_options_echo() where the common buffer area of the skb is incorrectly interpreted. Depending on the previous use of the skb->cb[], the interpreted option length values can cause stack corruption by copying more than 40 bytes to the output options.
In our case, a driver is using the skb->cb[] area to hold driver specific data. The driver is not zeroing out the area after use. I can see three basic solutions:
1) Drivers are not allowed to use the skb->cb[] area at all. Ubicom should modify the driver to use a different approach.
2) The layer using skb->cb[] should clear this area after use and before handing the skb to another layer. Ubicom should modify the driver to clear the skb->cb[] area before sending it up the line.
3) Any layer that "uses" the skb->cb[] area must clear the area before use. In which case, the proposed patch would fix the problem for the ipv4_link_failure(). I believe that this is the correct fix because I see ip_rcv() clears the skb->cb[] before using it.
Can someone confirm that this is the appropriate fix? If this is documented somewhere, please direct me to the documentation.
Please send email to sol@ubicom.com in addition to posting your response.
Thanks,
Sol Kavy/Murat Sezgin
Ubicom, Inc.
Patch:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 125ee64..d13805f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1606,6 +1606,14 @@ static void ipv4_link_failure(struct sk_buff *skb)
{
struct rtable *rt;
+ /*
+ * Since link failure can be called with skbs from many layers (see arp)
+ * the cb area of the skb must be cleared before use. Because the cb area
+ * can be formatted according to the caller layer's cb area format and it may cause
+ * corruptions when it is handled in a different network layer.
+ */
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
rt = skb->rtable;
The packet is enqueud by:
do_IRQ()->do_softirq()->__do_softirq()->net_rx_action()->ubi32_eth_napi_poll()->ubi32_eth_receive()->__vlan_hwaccel_rx()->netif_receive_skb()->br_handle_frame()->nf_hook_slow()->br_nf_pre_routing_finish()->br_nfr_pre_routing_finish_bridge()->neight_resolve_output()->__neigh_event_send().
The packet is then dequeued by:
do_IRQ() -> irq_exit() -> do_softirq() -> run_timer_softirq() -> neigh_timer_handler() -> arp_error_report() -> ipv4_link_failure() -> icmp_send() -> ip_options_echo().
Because the Ubicom Ethernet driver overwrites the common buffer area, the enqueued packet contains garbage when casted as an IP options data structure. This results in ip_options_echo() miss reading the option length information and overwriting memory. By clearing the skb->cb[] before processing the icmp_send() against the packet, we ensure that ip_options_echo() does not corrupt memory.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
WARNING: multiple messages have this Message-ID (diff)
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
To: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: Fwd: Possible bug in net/ipv4/route.c?
Date: Fri, 02 Jul 2010 11:49:55 +0900 [thread overview]
Message-ID: <4C2D53D3.6050106@linux-ipv6.org> (raw)
Switch to netdev.
--yoshfuji
-------- Original Message --------
Subject: Possible bug in net/ipv4/route.c?
Date: Thu, 1 Jul 2010 16:00:29 -0700
From: Sol Kavy <skavy@ubicom.com>
To: <linux-kernel@vger.kernel.org>
CC: Greg Ren <gren@ubicom.com>, Guojun Jin <gjin@ubicom.com>, Murat Sezgin <msezgin@ubicom.com>, Sener Ilgen <silgen@ubicom.com>
Found Linux: 2.6.28
Arch: Ubicom32 <not yet pushed>
Project: uCLinux based Router
Test: Bit torrent Stress Test
Note: The top of Linus git net/ipv4/route.c appears to have the same issue.
The following is a patch for clearing out IP options area in an input skb during link failure processing. Without this patch, the icmp_send() can result in a call to ip_options_echo() where the common buffer area of the skb is incorrectly interpreted. Depending on the previous use of the skb->cb[], the interpreted option length values can cause stack corruption by copying more than 40 bytes to the output options.
In our case, a driver is using the skb->cb[] area to hold driver specific data. The driver is not zeroing out the area after use. I can see three basic solutions:
1) Drivers are not allowed to use the skb->cb[] area at all. Ubicom should modify the driver to use a different approach.
2) The layer using skb->cb[] should clear this area after use and before handing the skb to another layer. Ubicom should modify the driver to clear the skb->cb[] area before sending it up the line.
3) Any layer that "uses" the skb->cb[] area must clear the area before use. In which case, the proposed patch would fix the problem for the ipv4_link_failure(). I believe that this is the correct fix because I see ip_rcv() clears the skb->cb[] before using it.
Can someone confirm that this is the appropriate fix? If this is documented somewhere, please direct me to the documentation.
Please send email to sol@ubicom.com in addition to posting your response.
Thanks,
Sol Kavy/Murat Sezgin
Ubicom, Inc.
Patch:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 125ee64..d13805f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1606,6 +1606,14 @@ static void ipv4_link_failure(struct sk_buff *skb)
{
struct rtable *rt;
+ /*
+ * Since link failure can be called with skbs from many layers (see arp)
+ * the cb area of the skb must be cleared before use. Because the cb area
+ * can be formatted according to the caller layer's cb area format and it may cause
+ * corruptions when it is handled in a different network layer.
+ */
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
rt = skb->rtable;
The packet is enqueud by:
do_IRQ()->do_softirq()->__do_softirq()->net_rx_action()->ubi32_eth_napi_poll()->ubi32_eth_receive()->__vlan_hwaccel_rx()->netif_receive_skb()->br_handle_frame()->nf_hook_slow()->br_nf_pre_routing_finish()->br_nfr_pre_routing_finish_bridge()->neight_resolve_output()->__neigh_event_send().
The packet is then dequeued by:
do_IRQ() -> irq_exit() -> do_softirq() -> run_timer_softirq() -> neigh_timer_handler() -> arp_error_report() -> ipv4_link_failure() -> icmp_send() -> ip_options_echo().
Because the Ubicom Ethernet driver overwrites the common buffer area, the enqueued packet contains garbage when casted as an IP options data structure. This results in ip_options_echo() miss reading the option length information and overwriting memory. By clearing the skb->cb[] before processing the icmp_send() against the packet, we ensure that ip_options_echo() does not corrupt memory.
next reply other threads:[~2010-07-02 2:50 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-02 2:49 YOSHIFUJI Hideaki [this message]
2010-07-02 2:49 ` Fwd: Possible bug in net/ipv4/route.c? YOSHIFUJI Hideaki
2010-07-02 5:38 ` Eric Dumazet
2010-07-05 12:06 ` Herbert Xu
2010-07-05 12:06 ` Herbert Xu
2010-07-05 12:59 ` Eric Dumazet
2010-07-05 12:59 ` Eric Dumazet
2010-07-05 13:22 ` Herbert Xu
2010-07-05 13:22 ` Herbert Xu
2010-07-05 13:34 ` Eric Dumazet
2010-07-05 13:34 ` Eric Dumazet
2010-07-05 14:42 ` Herbert Xu
2010-07-05 14:42 ` Herbert Xu
2010-07-05 20:07 ` Henrique de Moraes Holschuh
2010-07-05 20:07 ` Henrique de Moraes Holschuh
2010-07-05 20:18 ` Eric Dumazet
2010-07-05 20:18 ` Eric Dumazet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C2D53D3.6050106@linux-ipv6.org \
--to=yoshfuji@linux-ipv6.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.