All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: "David S . Miller" <davem@davemloft.net>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	netdev <netdev@vger.kernel.org>,
	"Eric Dumazet" <edumazet@google.com>, 赵子轩 <beraphin@gmail.com>,
	"Stoyan Manolov" <smanolov@suse.de>
Subject: Re: [PATCH net-next] llc: fix netdevice reference leaks in llc_ui_bind()
Date: Thu, 24 Mar 2022 09:22:43 +0300	[thread overview]
Message-ID: <20220324062243.GA2496@kili> (raw)
In-Reply-To: <20220323004147.1990845-1-eric.dumazet@gmail.com>

On Tue, Mar 22, 2022 at 05:41:47PM -0700, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> Whenever llc_ui_bind() and/or llc_ui_autobind()
> took a reference on a netdevice but subsequently fail,
> they must properly release their reference
> or risk the infamous message from unregister_netdevice()
> at device dismantle.
> 
> unregister_netdevice: waiting for eth0 to become free. Usage count = 3
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: 赵子轩 <beraphin@gmail.com>
> Reported-by: Stoyan Manolov <smanolov@suse.de>
> ---
> 
> This can be applied on net tree, depending on how network maintainers
> plan to push the fix to Linus, this is obviously a stable candidate.

This patch is fine, but it's that function is kind of ugly and difficult
for static analysis to parse.

net/llc/af_llc.c
   274  static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
   275  {
   276          struct sock *sk = sock->sk;
   277          struct llc_sock *llc = llc_sk(sk);
   278          struct llc_sap *sap;
   279          int rc = -EINVAL;
   280  
   281          if (!sock_flag(sk, SOCK_ZAPPED))
   282                  goto out;

This condition is checking to see if someone else already initialized
llc->dev.  If we call dev_put_track(llc->dev, &llc->dev_tracker) on
something we didn't allocate then it leads to a use after free.  But
fortunately the callers all check SOCK_ZAPPED so the condition is
impossible.

   283          if (!addr->sllc_arphrd)
   284                  addr->sllc_arphrd = ARPHRD_ETHER;
   285          if (addr->sllc_arphrd != ARPHRD_ETHER)
   286                  goto out;

Thus we know that "llc->dev" is NULL on these first couple gotos and
calling dev_put_track(llc->dev, &llc->dev_tracker); is a no-op so it's
fine.

But complicated to review.

   287          rc = -ENODEV;
   288          if (sk->sk_bound_dev_if) {
   289                  llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
   290                  if (llc->dev && addr->sllc_arphrd != llc->dev->type) {
   291                          dev_put(llc->dev);
   292                          llc->dev = NULL;
   293                  }
   294          } else
   295                  llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd);
   296          if (!llc->dev)
   297                  goto out;
   298          netdev_tracker_alloc(llc->dev, &llc->dev_tracker, GFP_KERNEL);
   299          rc = -EUSERS;
   300          llc->laddr.lsap = llc_ui_autoport();
   301          if (!llc->laddr.lsap)
   302                  goto out;
   303          rc = -EBUSY; /* some other network layer is using the sap */
   304          sap = llc_sap_open(llc->laddr.lsap, NULL);
   305          if (!sap)
   306                  goto out;
   307          memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
   308          memcpy(&llc->addr, addr, sizeof(llc->addr));
   309          /* assign new connection to its SAP */
   310          llc_sap_add_socket(sap, sk);
   311          sock_reset_flag(sk, SOCK_ZAPPED);
   312          rc = 0;
   313  out:
   314          if (rc) {
   315                  dev_put_track(llc->dev, &llc->dev_tracker);
   316                  llc->dev = NULL;
   317          }
   318          return rc;
   319  }

regards,
dan carpenter

  parent reply	other threads:[~2022-03-24  6:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-23  0:41 [PATCH net-next] llc: fix netdevice reference leaks in llc_ui_bind() Eric Dumazet
2022-03-23 18:00 ` patchwork-bot+netdevbpf
2022-03-24  6:22 ` Dan Carpenter [this message]
2022-03-24 14:38   ` Eric Dumazet
2022-03-24 16:25     ` 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=20220324062243.GA2496@kili \
    --to=dan.carpenter@oracle.com \
    --cc=beraphin@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=eric.dumazet@gmail.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=smanolov@suse.de \
    /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.