lkml.org 
[lkml]   [2017]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 13/28] vrf: Fix use-after-free in vrf_xmit
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: David Ahern <dsa@cumulusnetworks.com>


    [ Upstream commit f7887d40e541f74402df0684a1463c0a0bb68c68 ]

    KASAN detected a use-after-free:

    [ 269.467067] BUG: KASAN: use-after-free in vrf_xmit+0x7f1/0x827 [vrf] at addr ffff8800350a21c0
    [ 269.467067] Read of size 4 by task ssh/1879
    [ 269.467067] CPU: 1 PID: 1879 Comm: ssh Not tainted 4.10.0+ #249
    [ 269.467067] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
    [ 269.467067] Call Trace:
    [ 269.467067] dump_stack+0x81/0xb6
    [ 269.467067] kasan_object_err+0x21/0x78
    [ 269.467067] kasan_report+0x2f7/0x450
    [ 269.467067] ? vrf_xmit+0x7f1/0x827 [vrf]
    [ 269.467067] ? ip_output+0xa4/0xdb
    [ 269.467067] __asan_load4+0x6b/0x6d
    [ 269.467067] vrf_xmit+0x7f1/0x827 [vrf]
    ...

    Which corresponds to the skb access after xmit handling. Fix by saving
    skb->len and using the saved value to update stats.

    Fixes: 193125dbd8eb2 ("net: Introduce VRF device driver")
    Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/vrf.c | 3 ++-
    1 file changed, 2 insertions(+), 1 deletion(-)

    --- a/drivers/net/vrf.c
    +++ b/drivers/net/vrf.c
    @@ -345,6 +345,7 @@ static netdev_tx_t is_ip_tx_frame(struct

    static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
    {
    + int len = skb->len;
    netdev_tx_t ret = is_ip_tx_frame(skb, dev);

    if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
    @@ -352,7 +353,7 @@ static netdev_tx_t vrf_xmit(struct sk_bu

    u64_stats_update_begin(&dstats->syncp);
    dstats->tx_pkts++;
    - dstats->tx_bytes += skb->len;
    + dstats->tx_bytes += len;
    u64_stats_update_end(&dstats->syncp);
    } else {
    this_cpu_inc(dev->dstats->tx_drps);

    \
     
     \ /
      Last update: 2017-03-20 19:39    [W:3.828 / U:0.304 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site