lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 878/879] macsec: fix UAF bug for real_dev
    Date
    From: Ziyang Xuan <william.xuanziyang@huawei.com>

    commit 196a888ca6571deb344468e1d7138e3273206335 upstream.

    Create a new macsec device but not get reference to real_dev. That can
    not ensure that real_dev is freed after macsec. That will trigger the
    UAF bug for real_dev as following:

    ==================================================================
    BUG: KASAN: use-after-free in macsec_get_iflink+0x5f/0x70 drivers/net/macsec.c:3662
    Call Trace:
    ...
    macsec_get_iflink+0x5f/0x70 drivers/net/macsec.c:3662
    dev_get_iflink+0x73/0xe0 net/core/dev.c:637
    default_operstate net/core/link_watch.c:42 [inline]
    rfc2863_policy+0x233/0x2d0 net/core/link_watch.c:54
    linkwatch_do_dev+0x2a/0x150 net/core/link_watch.c:161

    Allocated by task 22209:
    ...
    alloc_netdev_mqs+0x98/0x1100 net/core/dev.c:10549
    rtnl_create_link+0x9d7/0xc00 net/core/rtnetlink.c:3235
    veth_newlink+0x20e/0xa90 drivers/net/veth.c:1748

    Freed by task 8:
    ...
    kfree+0xd6/0x4d0 mm/slub.c:4552
    kvfree+0x42/0x50 mm/util.c:615
    device_release+0x9f/0x240 drivers/base/core.c:2229
    kobject_cleanup lib/kobject.c:673 [inline]
    kobject_release lib/kobject.c:704 [inline]
    kref_put include/linux/kref.h:65 [inline]
    kobject_put+0x1c8/0x540 lib/kobject.c:721
    netdev_run_todo+0x72e/0x10b0 net/core/dev.c:10327

    After commit faab39f63c1f ("net: allow out-of-order netdev unregistration")
    and commit e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"), we
    can add dev_hold_track() in macsec_dev_init() and dev_put_track() in
    macsec_free_netdev() to fix the problem.

    Fixes: 2bce1ebed17d ("macsec: fix refcnt leak in module exit routine")
    Reported-by: syzbot+d0e94b65ac259c29ce7a@syzkaller.appspotmail.com
    Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
    Link: https://lore.kernel.org/r/20220531074500.1272846-1-william.xuanziyang@huawei.com
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/macsec.c | 7 +++++++
    1 file changed, 7 insertions(+)

    --- a/drivers/net/macsec.c
    +++ b/drivers/net/macsec.c
    @@ -99,6 +99,7 @@ struct pcpu_secy_stats {
    * struct macsec_dev - private data
    * @secy: SecY config
    * @real_dev: pointer to underlying netdevice
    + * @dev_tracker: refcount tracker for @real_dev reference
    * @stats: MACsec device stats
    * @secys: linked list of SecY's on the underlying device
    * @gro_cells: pointer to the Generic Receive Offload cell
    @@ -107,6 +108,7 @@ struct pcpu_secy_stats {
    struct macsec_dev {
    struct macsec_secy secy;
    struct net_device *real_dev;
    + netdevice_tracker dev_tracker;
    struct pcpu_secy_stats __percpu *stats;
    struct list_head secys;
    struct gro_cells gro_cells;
    @@ -3459,6 +3461,9 @@ static int macsec_dev_init(struct net_de
    if (is_zero_ether_addr(dev->broadcast))
    memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);

    + /* Get macsec's reference to real_dev */
    + dev_hold_track(real_dev, &macsec->dev_tracker, GFP_KERNEL);
    +
    return 0;
    }

    @@ -3704,6 +3709,8 @@ static void macsec_free_netdev(struct ne
    free_percpu(macsec->stats);
    free_percpu(macsec->secy.tx_sc.stats);

    + /* Get rid of the macsec's reference to real_dev */
    + dev_put_track(macsec->real_dev, &macsec->dev_tracker);
    }

    static void macsec_setup(struct net_device *dev)

    \
     
     \ /
      Last update: 2022-06-08 04:49    [W:4.022 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site