* [PATCH] can: etas_es58x: fix error handling
@ 2021-11-14 20:58 Pavel Skripkin
2021-11-15 5:27 ` Vincent MAILHOL
0 siblings, 1 reply; 12+ messages in thread
From: Pavel Skripkin @ 2021-11-14 20:58 UTC (permalink / raw)
To: mailhol.vincent, wg, mkl, davem, kuba
Cc: linux-can, netdev, linux-kernel, Pavel Skripkin
When register_candev() fails there are 2 possible device states:
NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable
for calling unregister_candev(), because of following checks in
unregister_netdevice_many():
if (dev->reg_state == NETREG_UNINITIALIZED)
WARN_ON(1);
...
BUG_ON(dev->reg_state != NETREG_REGISTERED);
To avoid possible BUG_ON or WARN_ON let's free current netdev before
returning from es58x_init_netdev() and leave others (registered)
net devices for es58x_free_netdevs().
Fixes: 004653f0abf2 ("can: etas_es58x: add es58x_free_netdevs() to factorize code")
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
drivers/net/can/usb/etas_es58x/es58x_core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 96a13c770e4a..41c721f2fbbe 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -2098,8 +2098,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
netdev->flags |= IFF_ECHO; /* We support local echo */
ret = register_candev(netdev);
- if (ret)
+ if (ret) {
+ free_candev(netdev);
+ es58x_dev->netdev[channel_idx] = NULL;
return ret;
+ }
netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0),
es58x_dev->param->dql_min_limit);
--
2.33.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH] can: etas_es58x: fix error handling 2021-11-14 20:58 [PATCH] can: etas_es58x: fix error handling Pavel Skripkin @ 2021-11-15 5:27 ` Vincent MAILHOL 2021-11-15 7:40 ` Pavel Skripkin 2021-11-15 7:51 ` [PATCH v2] " Pavel Skripkin 0 siblings, 2 replies; 12+ messages in thread From: Vincent MAILHOL @ 2021-11-15 5:27 UTC (permalink / raw) To: Pavel Skripkin; +Cc: wg, mkl, davem, kuba, linux-can, netdev, linux-kernel Hi Pavel, Thanks for the patch! On Mon. 15 Nov 2021 at 05:58, Pavel Skripkin <paskripkin@gmail.com> wrote: > When register_candev() fails there are 2 possible device states: > NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable > for calling unregister_candev(), because of following checks in > unregister_netdevice_many(): > > if (dev->reg_state == NETREG_UNINITIALIZED) > WARN_ON(1); > ... > BUG_ON(dev->reg_state != NETREG_REGISTERED); > > To avoid possible BUG_ON or WARN_ON let's free current netdev before > returning from es58x_init_netdev() and leave others (registered) > net devices for es58x_free_netdevs(). > > Fixes: 004653f0abf2 ("can: etas_es58x: add es58x_free_netdevs() to factorize code") Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") The bug existed from the initial commit. Prior to the introduction of es58x_free_netdevs(), unregister_candev() was called in the error handling of es58x_probe(): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/usb/etas_es58x/es58x_core.c?id=8537257874e949a59c834cecfd5a063e11b64b0b#n2234 > Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> > --- > drivers/net/can/usb/etas_es58x/es58x_core.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c > index 96a13c770e4a..41c721f2fbbe 100644 > --- a/drivers/net/can/usb/etas_es58x/es58x_core.c > +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c > @@ -2098,8 +2098,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) > netdev->flags |= IFF_ECHO; /* We support local echo */ > > ret = register_candev(netdev); > - if (ret) > + if (ret) { > + free_candev(netdev); > + es58x_dev->netdev[channel_idx] = NULL; A nitpick, but if you don’t mind, I would prefer to set es58x_dev->netdev[channel_idx] after register_candev() succeeds so that we do not have to reset it to NULL in the error handling. diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index ce2b9e1ce3af..fb0daad9b9c8 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -2091,18 +2091,20 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) return -ENOMEM; } SET_NETDEV_DEV(netdev, dev); - es58x_dev->netdev[channel_idx] = netdev; es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx); netdev->netdev_ops = &es58x_netdev_ops; netdev->flags |= IFF_ECHO; /* We support local echo */ ret = register_candev(netdev); - if (ret) + if (ret) { + free_candev(netdev); return ret; + } netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), es58x_dev->param->dql_min_limit); + es58x_dev->netdev[channel_idx] = netdev; return ret; } > return ret; > + } > > netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), > es58x_dev->param->dql_min_limit); ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] can: etas_es58x: fix error handling 2021-11-15 5:27 ` Vincent MAILHOL @ 2021-11-15 7:40 ` Pavel Skripkin 2021-11-15 7:51 ` [PATCH v2] " Pavel Skripkin 1 sibling, 0 replies; 12+ messages in thread From: Pavel Skripkin @ 2021-11-15 7:40 UTC (permalink / raw) To: Vincent MAILHOL; +Cc: wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On 11/15/21 08:27, Vincent MAILHOL wrote: > Hi Pavel, > > Thanks for the patch! > > On Mon. 15 Nov 2021 at 05:58, Pavel Skripkin <paskripkin@gmail.com> wrote: >> When register_candev() fails there are 2 possible device states: >> NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable >> for calling unregister_candev(), because of following checks in >> unregister_netdevice_many(): >> >> if (dev->reg_state == NETREG_UNINITIALIZED) >> WARN_ON(1); >> ... >> BUG_ON(dev->reg_state != NETREG_REGISTERED); >> >> To avoid possible BUG_ON or WARN_ON let's free current netdev before >> returning from es58x_init_netdev() and leave others (registered) >> net devices for es58x_free_netdevs(). >> >> Fixes: 004653f0abf2 ("can: etas_es58x: add es58x_free_netdevs() to factorize code") > Hi, Vincent! > Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X > CAN USB interfaces") > > The bug existed from the initial commit. Prior to the > introduction of es58x_free_netdevs(), unregister_candev() was > called in the error handling of es58x_probe(): > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/usb/etas_es58x/es58x_core.c?id=8537257874e949a59c834cecfd5a063e11b64b0b#n2234 > I see, will fix in v2 >> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> >> --- >> drivers/net/can/usb/etas_es58x/es58x_core.c | 5 ++++- >> 1 file changed, 4 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c >> index 96a13c770e4a..41c721f2fbbe 100644 >> --- a/drivers/net/can/usb/etas_es58x/es58x_core.c >> +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c >> @@ -2098,8 +2098,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) >> netdev->flags |= IFF_ECHO; /* We support local echo */ >> >> ret = register_candev(netdev); >> - if (ret) >> + if (ret) { >> + free_candev(netdev); >> + es58x_dev->netdev[channel_idx] = NULL; > > A nitpick, but if you don’t mind, I would prefer to set > es58x_dev->netdev[channel_idx] after register_candev() succeeds > so that we do not have to reset it to NULL in the error handling. > > diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c > b/drivers/net/can/usb/etas_es58x/es58x_core.c > index ce2b9e1ce3af..fb0daad9b9c8 100644 > --- a/drivers/net/can/usb/etas_es58x/es58x_core.c > +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c > @@ -2091,18 +2091,20 @@ static int es58x_init_netdev(struct > es58x_device *es58x_dev, int channel_idx) > return -ENOMEM; > } > SET_NETDEV_DEV(netdev, dev); > - es58x_dev->netdev[channel_idx] = netdev; > es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx); > > netdev->netdev_ops = &es58x_netdev_ops; > netdev->flags |= IFF_ECHO; /* We support local echo */ > > ret = register_candev(netdev); > - if (ret) > + if (ret) { > + free_candev(netdev); > return ret; > + } > > netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), > es58x_dev->param->dql_min_limit); > + es58x_dev->netdev[channel_idx] = netdev; > > return ret; > } > Also will do in v2. Thank you for your review :) With regards, Pavel Skripkin ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 5:27 ` Vincent MAILHOL 2021-11-15 7:40 ` Pavel Skripkin @ 2021-11-15 7:51 ` Pavel Skripkin 2021-11-15 8:11 ` Johan Hovold 1 sibling, 1 reply; 12+ messages in thread From: Pavel Skripkin @ 2021-11-15 7:51 UTC (permalink / raw) To: mailhol.vincent, wg, mkl, davem, kuba Cc: linux-can, netdev, linux-kernel, Pavel Skripkin When register_candev() fails there are 2 possible device states: NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable for calling unregister_candev(), because of following checks in unregister_netdevice_many(): if (dev->reg_state == NETREG_UNINITIALIZED) WARN_ON(1); ... BUG_ON(dev->reg_state != NETREG_REGISTERED); To avoid possible BUG_ON or WARN_ON let's free current netdev before returning from es58x_init_netdev() and leave others (registered) net devices for es58x_free_netdevs(). Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> --- Changes in v2: - Fixed Fixes: tag - Moved es58x_dev->netdev[channel_idx] initialization at the end of the function --- drivers/net/can/usb/etas_es58x/es58x_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 96a13c770e4a..b3af8f2e32ac 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -2091,19 +2091,22 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) return -ENOMEM; } SET_NETDEV_DEV(netdev, dev); - es58x_dev->netdev[channel_idx] = netdev; es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx); netdev->netdev_ops = &es58x_netdev_ops; netdev->flags |= IFF_ECHO; /* We support local echo */ ret = register_candev(netdev); - if (ret) + if (ret) { + free_candev(netdev); return ret; + } netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), es58x_dev->param->dql_min_limit); + es58x_dev->netdev[channel_idx] = netdev; + return ret; } -- 2.33.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 7:51 ` [PATCH v2] " Pavel Skripkin @ 2021-11-15 8:11 ` Johan Hovold 2021-11-15 8:15 ` Pavel Skripkin 2021-11-15 8:37 ` [PATCH v3] " Pavel Skripkin 0 siblings, 2 replies; 12+ messages in thread From: Johan Hovold @ 2021-11-15 8:11 UTC (permalink / raw) To: Pavel Skripkin Cc: mailhol.vincent, wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On Mon, Nov 15, 2021 at 10:51:24AM +0300, Pavel Skripkin wrote: > When register_candev() fails there are 2 possible device states: > NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable > for calling unregister_candev(), because of following checks in > unregister_netdevice_many(): > > if (dev->reg_state == NETREG_UNINITIALIZED) > WARN_ON(1); > ... > BUG_ON(dev->reg_state != NETREG_REGISTERED); > > To avoid possible BUG_ON or WARN_ON let's free current netdev before > returning from es58x_init_netdev() and leave others (registered) > net devices for es58x_free_netdevs(). > > Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") > Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> > --- > > Changes in v2: > - Fixed Fixes: tag > - Moved es58x_dev->netdev[channel_idx] initialization at the end > of the function > > --- > drivers/net/can/usb/etas_es58x/es58x_core.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c > index 96a13c770e4a..b3af8f2e32ac 100644 > --- a/drivers/net/can/usb/etas_es58x/es58x_core.c > +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c > @@ -2091,19 +2091,22 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) > return -ENOMEM; > } > SET_NETDEV_DEV(netdev, dev); > - es58x_dev->netdev[channel_idx] = netdev; > es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx); > > netdev->netdev_ops = &es58x_netdev_ops; > netdev->flags |= IFF_ECHO; /* We support local echo */ > > ret = register_candev(netdev); > - if (ret) > + if (ret) { > + free_candev(netdev); > return ret; > + } > > netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), > es58x_dev->param->dql_min_limit); > > + es58x_dev->netdev[channel_idx] = netdev; > + Just a drive-by comment: Are you sure about this move of the netdev[channel_idx] initialisation? What happens if the registered can device is opened before you initialise the pointer? NULL-deref in es58x_send_msg()? You generally want the driver data fully initialised before you register the device so this looks broken. And either way it is arguably an unrelated change that should go in a separate patch explaining why it is needed and safe. > return ret; > } Johan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 8:11 ` Johan Hovold @ 2021-11-15 8:15 ` Pavel Skripkin 2021-11-15 8:16 ` Johan Hovold 2021-11-15 8:37 ` [PATCH v3] " Pavel Skripkin 1 sibling, 1 reply; 12+ messages in thread From: Pavel Skripkin @ 2021-11-15 8:15 UTC (permalink / raw) To: Johan Hovold Cc: mailhol.vincent, wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On 11/15/21 11:11, Johan Hovold wrote: > Just a drive-by comment: > > Are you sure about this move of the netdev[channel_idx] initialisation? > What happens if the registered can device is opened before you > initialise the pointer? NULL-deref in es58x_send_msg()? > > You generally want the driver data fully initialised before you register > the device so this looks broken. > > And either way it is arguably an unrelated change that should go in a > separate patch explaining why it is needed and safe. > It was suggested by Vincent who is the maintainer of this driver [1]. [1] https://lore.kernel.org/linux-can/CAMZ6Rq+orfUuUCCgeWyGc7P0vp3t-yjf_g9H=Jhk43f1zXGfDQ@mail.gmail.com/ With regards, Pavel Skripkin ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 8:15 ` Pavel Skripkin @ 2021-11-15 8:16 ` Johan Hovold 2021-11-15 8:30 ` Pavel Skripkin 0 siblings, 1 reply; 12+ messages in thread From: Johan Hovold @ 2021-11-15 8:16 UTC (permalink / raw) To: Pavel Skripkin Cc: mailhol.vincent, wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On Mon, Nov 15, 2021 at 11:15:07AM +0300, Pavel Skripkin wrote: > On 11/15/21 11:11, Johan Hovold wrote: > > Just a drive-by comment: > > > > Are you sure about this move of the netdev[channel_idx] initialisation? > > What happens if the registered can device is opened before you > > initialise the pointer? NULL-deref in es58x_send_msg()? > > > > You generally want the driver data fully initialised before you register > > the device so this looks broken. > > > > And either way it is arguably an unrelated change that should go in a > > separate patch explaining why it is needed and safe. > > > > > It was suggested by Vincent who is the maintainer of this driver [1]. Yeah, I saw that, but that doesn't necessarily mean it is correct. You're still responsible for the changes you make and need to be able to argue why they are correct. Johan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 8:16 ` Johan Hovold @ 2021-11-15 8:30 ` Pavel Skripkin 2021-11-15 9:24 ` Vincent MAILHOL 0 siblings, 1 reply; 12+ messages in thread From: Pavel Skripkin @ 2021-11-15 8:30 UTC (permalink / raw) To: Johan Hovold Cc: mailhol.vincent, wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On 11/15/21 11:16, Johan Hovold wrote: > On Mon, Nov 15, 2021 at 11:15:07AM +0300, Pavel Skripkin wrote: >> On 11/15/21 11:11, Johan Hovold wrote: >> > Just a drive-by comment: >> > >> > Are you sure about this move of the netdev[channel_idx] initialisation? >> > What happens if the registered can device is opened before you >> > initialise the pointer? NULL-deref in es58x_send_msg()? >> > >> > You generally want the driver data fully initialised before you register >> > the device so this looks broken. >> > >> > And either way it is arguably an unrelated change that should go in a >> > separate patch explaining why it is needed and safe. >> > >> >> >> It was suggested by Vincent who is the maintainer of this driver [1]. > > Yeah, I saw that, but that doesn't necessarily mean it is correct. > > You're still responsible for the changes you make and need to be able to > argue why they are correct. > Sure! I should have check it before sending v2 :( My bad, sorry. I see now, that there is possible calltrace which can hit NULL defer. One thing I am wondering about is why in some code parts there are validation checks for es58x_dev->netdev[i] and in others they are missing. Anyway, it's completely out of scope of current patch, I am going to resend v1 with fixed Fixes tag. Thank you for review! With regards, Pavel Skripkin ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 8:30 ` Pavel Skripkin @ 2021-11-15 9:24 ` Vincent MAILHOL 2021-11-15 9:26 ` Pavel Skripkin 0 siblings, 1 reply; 12+ messages in thread From: Vincent MAILHOL @ 2021-11-15 9:24 UTC (permalink / raw) To: Pavel Skripkin Cc: Johan Hovold, wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On Mon. 15 Nov 2021 at 17:30, Pavel Skripkin <paskripkin@gmail.com> wrote: > On 11/15/21 11:16, Johan Hovold wrote: > > On Mon, Nov 15, 2021 at 11:15:07AM +0300, Pavel Skripkin wrote: > >> On 11/15/21 11:11, Johan Hovold wrote: > >> > Just a drive-by comment: > >> > > >> > Are you sure about this move of the netdev[channel_idx] initialisation? > >> > What happens if the registered can device is opened before you > >> > initialise the pointer? NULL-deref in es58x_send_msg()? > >> > > >> > You generally want the driver data fully initialised before you register > >> > the device so this looks broken. > >> > > >> > And either way it is arguably an unrelated change that should go in a > >> > separate patch explaining why it is needed and safe. > >> > > >> > >> > >> It was suggested by Vincent who is the maintainer of this driver [1]. > > > > Yeah, I saw that, but that doesn't necessarily mean it is correct. > > > > You're still responsible for the changes you make and need to be able to > > argue why they are correct. > > > > Sure! I should have check it before sending v2 :( My bad, sorry. I see > now, that there is possible calltrace which can hit NULL defer. I should be the one apologizing here. Sorry for the confusion. > One thing I am wondering about is why in some code parts there are > validation checks for es58x_dev->netdev[i] and in others they are missing. There is a validation when it is accessed in a for loop. It is not guarded in es58x_send_msg() because this function expects the channel_idx to be a valid index. Does this answer your wonders? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] can: etas_es58x: fix error handling 2021-11-15 9:24 ` Vincent MAILHOL @ 2021-11-15 9:26 ` Pavel Skripkin 0 siblings, 0 replies; 12+ messages in thread From: Pavel Skripkin @ 2021-11-15 9:26 UTC (permalink / raw) To: Vincent MAILHOL Cc: Johan Hovold, wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On 11/15/21 12:24, Vincent MAILHOL wrote: >> Sure! I should have check it before sending v2 :( My bad, sorry. I see >> now, that there is possible calltrace which can hit NULL defer. > > I should be the one apologizing here. Sorry for the confusion. > >> One thing I am wondering about is why in some code parts there are >> validation checks for es58x_dev->netdev[i] and in others they are missing. > > There is a validation when it is accessed in a for loop. > It is not guarded in es58x_send_msg() because this function > expects the channel_idx to be a valid index. > > Does this answer your wonders? > Yeah! I have just looked at the code one more time and came up with the same idea. Thank you for confirming and acking my patch :) With regards, Pavel Skripkin ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3] can: etas_es58x: fix error handling 2021-11-15 8:11 ` Johan Hovold 2021-11-15 8:15 ` Pavel Skripkin @ 2021-11-15 8:37 ` Pavel Skripkin 2021-11-15 9:15 ` Vincent MAILHOL 1 sibling, 1 reply; 12+ messages in thread From: Pavel Skripkin @ 2021-11-15 8:37 UTC (permalink / raw) To: mailhol.vincent, wg, mkl, davem, kuba Cc: linux-can, netdev, linux-kernel, Pavel Skripkin When register_candev() fails there are 2 possible device states: NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable for calling unregister_candev(), because of following checks in unregister_netdevice_many(): if (dev->reg_state == NETREG_UNINITIALIZED) WARN_ON(1); ... BUG_ON(dev->reg_state != NETREG_REGISTERED); To avoid possible BUG_ON or WARN_ON let's free current netdev before returning from es58x_init_netdev() and leave others (registered) net devices for es58x_free_netdevs(). Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> --- Changes in v3: - Moved back es58x_dev->netdev[channel_idx] initialization, since it's unsafe to intialize it _after_ register_candev() call. Thanks to Johan Hovold <johan@kernel.org> for spotting it Changes in v2: - Fixed Fixes: tag - Moved es58x_dev->netdev[channel_idx] initialization at the end of the function --- drivers/net/can/usb/etas_es58x/es58x_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 96a13c770e4a..41c721f2fbbe 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -2098,8 +2098,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) netdev->flags |= IFF_ECHO; /* We support local echo */ ret = register_candev(netdev); - if (ret) + if (ret) { + free_candev(netdev); + es58x_dev->netdev[channel_idx] = NULL; return ret; + } netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), es58x_dev->param->dql_min_limit); -- 2.33.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3] can: etas_es58x: fix error handling 2021-11-15 8:37 ` [PATCH v3] " Pavel Skripkin @ 2021-11-15 9:15 ` Vincent MAILHOL 0 siblings, 0 replies; 12+ messages in thread From: Vincent MAILHOL @ 2021-11-15 9:15 UTC (permalink / raw) To: Pavel Skripkin; +Cc: wg, mkl, davem, kuba, linux-can, netdev, linux-kernel On Mon. 15 Nov 2021 at 17:37, Pavel Skripkin <paskripkin@gmail.com> wrote: > When register_candev() fails there are 2 possible device states: > NETREG_UNINITIALIZED and NETREG_UNREGISTERED. None of them are suitable > for calling unregister_candev(), because of following checks in > unregister_netdevice_many(): > > if (dev->reg_state == NETREG_UNINITIALIZED) > WARN_ON(1); > ... > BUG_ON(dev->reg_state != NETREG_REGISTERED); > > To avoid possible BUG_ON or WARN_ON let's free current netdev before > returning from es58x_init_netdev() and leave others (registered) > net devices for es58x_free_netdevs(). > > Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") > Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> Acked-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> > --- > > Changes in v3: > - Moved back es58x_dev->netdev[channel_idx] initialization, > since it's unsafe to intialize it _after_ register_candev() > call. Thanks to Johan Hovold <johan@kernel.org> for spotting > it My bad on that. I missed the fact that the netdev_ops becomes active once register_candev() returns. > Changes in v2: > - Fixed Fixes: tag > - Moved es58x_dev->netdev[channel_idx] initialization at the end > of the function > > --- > drivers/net/can/usb/etas_es58x/es58x_core.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c > index 96a13c770e4a..41c721f2fbbe 100644 > --- a/drivers/net/can/usb/etas_es58x/es58x_core.c > +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c > @@ -2098,8 +2098,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) > netdev->flags |= IFF_ECHO; /* We support local echo */ > > ret = register_candev(netdev); > - if (ret) > + if (ret) { > + free_candev(netdev); > + es58x_dev->netdev[channel_idx] = NULL; > return ret; > + } > > netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), > es58x_dev->param->dql_min_limit); > -- > 2.33.1 > ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-11-15 9:27 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-11-14 20:58 [PATCH] can: etas_es58x: fix error handling Pavel Skripkin 2021-11-15 5:27 ` Vincent MAILHOL 2021-11-15 7:40 ` Pavel Skripkin 2021-11-15 7:51 ` [PATCH v2] " Pavel Skripkin 2021-11-15 8:11 ` Johan Hovold 2021-11-15 8:15 ` Pavel Skripkin 2021-11-15 8:16 ` Johan Hovold 2021-11-15 8:30 ` Pavel Skripkin 2021-11-15 9:24 ` Vincent MAILHOL 2021-11-15 9:26 ` Pavel Skripkin 2021-11-15 8:37 ` [PATCH v3] " Pavel Skripkin 2021-11-15 9:15 ` Vincent MAILHOL
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox