Hi! > From: Eric Dumazet <edumazet@xxxxxxxxxx> > > commit 764f4eb6846f5475f1244767d24d25dd86528a4a upstream. > > 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 Can someone check this? AFAICT this is buggy. static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) { struct sock *sk = sock->sk; struct llc_sock *llc = llc_sk(sk); struct llc_sap *sap; int rc = -EINVAL; if (!sock_flag(sk, SOCK_ZAPPED)) goto out; There are 'goto out's from both before dev_get() and after it, dev_put() will be called with NULL pointer. dev_put() can't handle NULL at least in the old kernels... this is simply confused. Mainline has dev_put_track() there, but I see same confusion. Best regards, Pavel > --- a/net/llc/af_llc.c > +++ b/net/llc/af_llc.c > @@ -311,6 +311,10 @@ static int llc_ui_autobind(struct socket > sock_reset_flag(sk, SOCK_ZAPPED); > rc = 0; > out: > + if (rc) { > + dev_put(llc->dev); > + llc->dev = NULL; > + } > return rc; > } > > @@ -409,6 +413,10 @@ static int llc_ui_bind(struct socket *so > out_put: > llc_sap_put(sap); > out: > + if (rc) { > + dev_put(llc->dev); > + llc->dev = NULL; > + } > release_sock(sk); > return rc; > } > -- 'DENX Software Engineering GmbH, Managing Director: Wolfgang Denk' 'HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany'
Attachment:
signature.asc
Description: PGP signature