lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6514889a7af123eed01e3471ae1c48252e9aa296.camel@mendozajonas.com>
Date:   Thu, 12 Nov 2020 08:25:39 -0800
From:   Samuel Mendoza-Jonas <sam@...dozajonas.com>
To:     Joel Stanley <joel@....id.au>,
        "David S . Miller" <davem@...emloft.net>,
        Jakub Kicinski <kuba@...nel.org>
Cc:     Andrew Jeffery <andrew@...id.au>, netdev@...r.kernel.org
Subject: Re: [PATCH v2] net/ncsi: Fix netlink registration

On Thu, 2020-11-12 at 16:42 +1030, Joel Stanley wrote:
> If a user unbinds and re-binds a NC-SI aware driver the kernel will
> attempt to register the netlink interface at runtime. The structure
> is
> marked __ro_after_init so registration fails spectacularly at this
> point.

Reviewed-by: Samuel Mendoza-Jonas <sam@...dozajonas.com>

> 
>  # echo 1e660000.ethernet >
> /sys/bus/platform/drivers/ftgmac100/unbind
>  # echo 1e660000.ethernet > /sys/bus/platform/drivers/ftgmac100/bind
>   ftgmac100 1e660000.ethernet: Read MAC address 52:54:00:12:34:56
> from chip
>   ftgmac100 1e660000.ethernet: Using NCSI interface
>   8<--- cut here ---
>   Unable to handle kernel paging request at virtual address 80a8f858
>   pgd = 8c768dd6
>   [80a8f858] *pgd=80a0841e(bad)
>   Internal error: Oops: 80d [#1] SMP ARM
>   CPU: 0 PID: 116 Comm: sh Not tainted 5.10.0-rc3-next-20201111-
> 00003-gdd25b227ec1e #51
>   Hardware name: Generic DT based system
>   PC is at genl_register_family+0x1f8/0x6d4
>   LR is at 0xff26ffff
>   pc : [<8073f930>]    lr : [<ff26ffff>]    psr: 20000153
>   sp : 8553bc80  ip : 81406244  fp : 8553bd04
>   r10: 8085d12c  r9 : 80a8f73c  r8 : 85739000
>   r7 : 00000017  r6 : 80a8f860  r5 : 80c8ab98  r4 : 80a8f858
>   r3 : 00000000  r2 : 00000000  r1 : 81406130  r0 : 00000017
>   Flags: nzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
>   Control: 00c5387d  Table: 85524008  DAC: 00000051
>   Process sh (pid: 116, stack limit = 0x1f1988d6)
>  ...
>   Backtrace:
>   [<8073f738>] (genl_register_family) from [<80860ac0>]
> (ncsi_init_netlink+0x20/0x48)
>    r10:8085d12c r9:80c8fb0c r8:85739000 r7:00000000 r6:81218000
> r5:85739000
>    r4:8121c000
>   [<80860aa0>] (ncsi_init_netlink) from [<8085d740>]
> (ncsi_register_dev+0x1b0/0x210)
>    r5:8121c400 r4:8121c000
>   [<8085d590>] (ncsi_register_dev) from [<805a8060>]
> (ftgmac100_probe+0x6e0/0x778)
>    r10:00000004 r9:80950228 r8:8115bc10 r7:8115ab00 r6:9eae2c24
> r5:813b6f88
>    r4:85739000
>   [<805a7980>] (ftgmac100_probe) from [<805355ec>]
> (platform_drv_probe+0x58/0xa8)
>    r9:80c76bb0 r8:00000000 r7:80cd4974 r6:80c76bb0 r5:8115bc10
> r4:00000000
>   [<80535594>] (platform_drv_probe) from [<80532d58>]
> (really_probe+0x204/0x514)
>    r7:80cd4974 r6:00000000 r5:80cd4868 r4:8115bc10
> 
> Jakub pointed out that ncsi_register_dev is obviously broken, because
> there is only one family so it would never work if there was more
> than
> one ncsi netdev.
> 
> Fix the crash by registering the netlink family once on boot, and
> drop
> the code to unregister it.
> 
> Fixes: 955dc68cb9b2 ("net/ncsi: Add generic netlink family")
> Signed-off-by: Joel Stanley <joel@....id.au>
> ---
> v2: Implement Jakub's suggestion
>  - drop __ro_after_init change
>  - register netlink with subsys_intcall
>  - remove unregister function
> 
>  net/ncsi/ncsi-manage.c  |  5 -----
>  net/ncsi/ncsi-netlink.c | 22 +++-------------------
>  net/ncsi/ncsi-netlink.h |  3 ---
>  3 files changed, 3 insertions(+), 27 deletions(-)
> 
> diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
> index f1be3e3f6425..a9cb355324d1 100644
> --- a/net/ncsi/ncsi-manage.c
> +++ b/net/ncsi/ncsi-manage.c
> @@ -1726,9 +1726,6 @@ struct ncsi_dev *ncsi_register_dev(struct
> net_device *dev,
>         ndp->ptype.dev = dev;
>         dev_add_pack(&ndp->ptype);
>  
> -       /* Set up generic netlink interface */
> -       ncsi_init_netlink(dev);
> -
>         pdev = to_platform_device(dev->dev.parent);
>         if (pdev) {
>                 np = pdev->dev.of_node;
> @@ -1892,8 +1889,6 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
>         list_del_rcu(&ndp->node);
>         spin_unlock_irqrestore(&ncsi_dev_lock, flags);
>  
> -       ncsi_unregister_netlink(nd->dev);
> -
>         kfree(ndp);
>  }
>  EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
> diff --git a/net/ncsi/ncsi-netlink.c b/net/ncsi/ncsi-netlink.c
> index adddc7707aa4..bb5f1650f11c 100644
> --- a/net/ncsi/ncsi-netlink.c
> +++ b/net/ncsi/ncsi-netlink.c
> @@ -766,24 +766,8 @@ static struct genl_family ncsi_genl_family
> __ro_after_init = {
>         .n_small_ops = ARRAY_SIZE(ncsi_ops),
>  };
>  
> -int ncsi_init_netlink(struct net_device *dev)
> +static int __init ncsi_init_netlink(void)
>  {
> -       int rc;
> -
> -       rc = genl_register_family(&ncsi_genl_family);
> -       if (rc)
> -               netdev_err(dev, "ncsi: failed to register netlink
> family\n");
> -
> -       return rc;
> -}
> -
> -int ncsi_unregister_netlink(struct net_device *dev)
> -{
> -       int rc;
> -
> -       rc = genl_unregister_family(&ncsi_genl_family);
> -       if (rc)
> -               netdev_err(dev, "ncsi: failed to unregister netlink
> family\n");
> -
> -       return rc;
> +       return genl_register_family(&ncsi_genl_family);
>  }
> +subsys_initcall(ncsi_init_netlink);
> diff --git a/net/ncsi/ncsi-netlink.h b/net/ncsi/ncsi-netlink.h
> index 7502723fba83..39a1a9d7bf77 100644
> --- a/net/ncsi/ncsi-netlink.h
> +++ b/net/ncsi/ncsi-netlink.h
> @@ -22,7 +22,4 @@ int ncsi_send_netlink_err(struct net_device *dev,
>                           struct nlmsghdr *nlhdr,
>                           int err);
>  
> -int ncsi_init_netlink(struct net_device *dev);
> -int ncsi_unregister_netlink(struct net_device *dev);
> -
>  #endif /* __NCSI_NETLINK_H__ */


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ