* [PATCH 0/1] ser_gigaset: use container_of() instead of detour
@ 2016-02-18 20:29 Paul Bolle
2016-02-18 20:29 ` [PATCH 1/1] " Paul Bolle
0 siblings, 1 reply; 7+ messages in thread
From: Paul Bolle @ 2016-02-18 20:29 UTC (permalink / raw)
To: netdev
Cc: Dmitry Vyukov, Uwe Kleine-König, Greg Kroah-Hartman,
Martin Wilck, Jarkko Sakkinen, Tilman Schmidt, linux-kernel,
gigaset307x-common
Dmitry Vyukov reported that the syzkaller fuzzer uncovered a leak in
ser_gigaset (see
https://lkml.kernel.org/g/CACT4Y+Y+P7-pM0D4HTz4ZF6i+Rya22eOkPdnrv_OmDCMB7eQtg@mail.gmail.com).
This small patch fixes that. The commit explanation contains all the details to
understand how this leak made its way into the code.
This should eventually land in stable. No fixes tag because backporting is
probably not so straightforward for v4.3 and earlier. So I suggest I'll send
proper backports in about two weeks.
Paul Bolle (1):
ser_gigaset: use container_of() instead of detour
drivers/isdn/gigaset/ser-gigaset.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
--
2.4.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/1] ser_gigaset: use container_of() instead of detour
2016-02-18 20:29 [PATCH 0/1] ser_gigaset: use container_of() instead of detour Paul Bolle
@ 2016-02-18 20:29 ` Paul Bolle
2016-02-18 21:42 ` Tilman Schmidt
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Paul Bolle @ 2016-02-18 20:29 UTC (permalink / raw)
To: netdev
Cc: Dmitry Vyukov, Uwe Kleine-König, Greg Kroah-Hartman,
Martin Wilck, Jarkko Sakkinen, Tilman Schmidt, linux-kernel,
gigaset307x-common
The purpose of gigaset_device_release() is to kfree() the struct
ser_cardstate that contains our struct device. This is done via a bit of
a detour. First we make our struct device's driver_data point to the
container of our struct ser_cardstate (which is a struct cardstate). In
gigaset_device_release() we then retrieve that driver_data again. And
after that we finally kfree() the struct ser_cardstate that was saved in
the struct cardstate.
All of this can be achieved much easier by using container_of() to get
from our struct device to its container, struct ser_cardstate. Do so.
Note that at the time the detour was implemented commit b8b2c7d845d5
("base/platform: assert that dev_pm_domain callbacks are called
unconditionally") had just entered the tree. That commit disconnected
our platform_device and our platform_driver. These were reconnected
again in v4.5-rc2 through commit 25cad69f21f5 ("base/platform: Fix
platform drivers with no probe callback"). And one of the consequences
of that fix was that it broke the detour via driver_data. That's because
it made __device_release_driver() stop being a NOP for our struct device
and actually do stuff again. One of the things it now does, is setting
our driver_data to NULL. That, in turn, makes it impossible for
gigaset_device_release() to get to our struct cardstate. Which has the
net effect of leaking a struct ser_cardstate at every call of this
driver's tty close() operation. So using container_of() has the
additional benefit of actually working.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
drivers/isdn/gigaset/ser-gigaset.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 2a506fe0c8a4..d1f8ab915b15 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -373,13 +373,7 @@ static void gigaset_freecshw(struct cardstate *cs)
static void gigaset_device_release(struct device *dev)
{
- struct cardstate *cs = dev_get_drvdata(dev);
-
- if (!cs)
- return;
- dev_set_drvdata(dev, NULL);
- kfree(cs->hw.ser);
- cs->hw.ser = NULL;
+ kfree(container_of(dev, struct ser_cardstate, dev.dev));
}
/*
@@ -408,7 +402,6 @@ static int gigaset_initcshw(struct cardstate *cs)
cs->hw.ser = NULL;
return rc;
}
- dev_set_drvdata(&cs->hw.ser->dev.dev, cs);
tasklet_init(&cs->write_tasklet,
gigaset_modem_fill, (unsigned long) cs);
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/1] ser_gigaset: use container_of() instead of detour
2016-02-18 20:29 ` [PATCH 1/1] " Paul Bolle
@ 2016-02-18 21:42 ` Tilman Schmidt
2016-02-18 22:14 ` Paul Bolle
2016-02-18 23:46 ` Greg KH
2016-02-19 20:56 ` David Miller
2 siblings, 1 reply; 7+ messages in thread
From: Tilman Schmidt @ 2016-02-18 21:42 UTC (permalink / raw)
To: Paul Bolle, netdev
Cc: Dmitry Vyukov, Uwe Kleine-König, Greg Kroah-Hartman,
Martin Wilck, Jarkko Sakkinen, linux-kernel, gigaset307x-common
[-- Attachment #1: Type: text/plain, Size: 2084 bytes --]
Am 18.02.2016 um 21:29 schrieb Paul Bolle:
> The purpose of gigaset_device_release() is to kfree() the struct
> ser_cardstate that contains our struct device. This is done via a bit of
> a detour. First we make our struct device's driver_data point to the
> container of our struct ser_cardstate (which is a struct cardstate). In
> gigaset_device_release() we then retrieve that driver_data again. And
> after that we finally kfree() the struct ser_cardstate that was saved in
> the struct cardstate.
>
> All of this can be achieved much easier by using container_of() to get
> from our struct device to its container, struct ser_cardstate. Do so.
You're absolutely right. Very nice!
> Note that at the time the detour was implemented commit b8b2c7d845d5
> ("base/platform: assert that dev_pm_domain callbacks are called
> unconditionally") had just entered the tree. That commit disconnected
> our platform_device and our platform_driver. These were reconnected
> again in v4.5-rc2 through commit 25cad69f21f5 ("base/platform: Fix
> platform drivers with no probe callback"). And one of the consequences
> of that fix was that it broke the detour via driver_data. That's because
> it made __device_release_driver() stop being a NOP for our struct device
> and actually do stuff again. One of the things it now does, is setting
> our driver_data to NULL. That, in turn, makes it impossible for
> gigaset_device_release() to get to our struct cardstate. Which has the
> net effect of leaking a struct ser_cardstate at every call of this
> driver's tty close() operation. So using container_of() has the
> additional benefit of actually working.
>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Tested-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Acked-by: Tilman Schmidt <tilman@imap.cc>
Thanks for cleaning up the mess I left behind.
Tilman
--
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Nous, on a des fleurs et des bougies pour nous protéger.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/1] ser_gigaset: use container_of() instead of detour
2016-02-18 21:42 ` Tilman Schmidt
@ 2016-02-18 22:14 ` Paul Bolle
0 siblings, 0 replies; 7+ messages in thread
From: Paul Bolle @ 2016-02-18 22:14 UTC (permalink / raw)
To: Tilman Schmidt, netdev
Cc: Dmitry Vyukov, Uwe Kleine-König, Greg Kroah-Hartman,
Martin Wilck, Jarkko Sakkinen, linux-kernel, gigaset307x-common
On do, 2016-02-18 at 22:42 +0100, Tilman Schmidt wrote:
> Acked-by: Tilman Schmidt <tilman@imap.cc>
>
> Thanks for cleaning up the mess I left behind.
That's not how I look at it.
Commit 4c5e354a9742 ("ser_gigaset: fix deallocation of platform device
structure") provided a plausible fix for the issue we were trying to fix
two months ago. If the platform code hadn't been broken when you wrote
it - broken for ser_gigaset's corner case, that is - you would have
noticed the lifetime rules of driver_data the hard way. (I suspect I
might have never noticed if syzkaller hadn't insisted in rubbing my nose
in it.)
So chances are you would have come up with something similar to this fix
would commit 25cad69f21f5 ("base/platform: Fix platform drivers with no
probe callback") already have landed.
Thanks,
Paul Bolle
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/1] ser_gigaset: use container_of() instead of detour
2016-02-18 20:29 ` [PATCH 1/1] " Paul Bolle
2016-02-18 21:42 ` Tilman Schmidt
@ 2016-02-18 23:46 ` Greg KH
2016-02-18 23:53 ` Paul Bolle
2016-02-19 20:56 ` David Miller
2 siblings, 1 reply; 7+ messages in thread
From: Greg KH @ 2016-02-18 23:46 UTC (permalink / raw)
To: Paul Bolle
Cc: netdev, Dmitry Vyukov, Uwe Kleine-König, Martin Wilck,
Jarkko Sakkinen, Tilman Schmidt, linux-kernel, gigaset307x-common
On Thu, Feb 18, 2016 at 09:29:08PM +0100, Paul Bolle wrote:
> The purpose of gigaset_device_release() is to kfree() the struct
> ser_cardstate that contains our struct device. This is done via a bit of
> a detour. First we make our struct device's driver_data point to the
> container of our struct ser_cardstate (which is a struct cardstate). In
> gigaset_device_release() we then retrieve that driver_data again. And
> after that we finally kfree() the struct ser_cardstate that was saved in
> the struct cardstate.
>
> All of this can be achieved much easier by using container_of() to get
> from our struct device to its container, struct ser_cardstate. Do so.
>
> Note that at the time the detour was implemented commit b8b2c7d845d5
> ("base/platform: assert that dev_pm_domain callbacks are called
> unconditionally") had just entered the tree. That commit disconnected
> our platform_device and our platform_driver. These were reconnected
> again in v4.5-rc2 through commit 25cad69f21f5 ("base/platform: Fix
> platform drivers with no probe callback"). And one of the consequences
> of that fix was that it broke the detour via driver_data. That's because
> it made __device_release_driver() stop being a NOP for our struct device
> and actually do stuff again. One of the things it now does, is setting
> our driver_data to NULL. That, in turn, makes it impossible for
> gigaset_device_release() to get to our struct cardstate. Which has the
> net effect of leaking a struct ser_cardstate at every call of this
> driver's tty close() operation. So using container_of() has the
> additional benefit of actually working.
>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Tested-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
> ---
> drivers/isdn/gigaset/ser-gigaset.c | 9 +--------
> 1 file changed, 1 insertion(+), 8 deletions(-)
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read Documentation/stable_kernel_rules.txt
for how to do this properly.
</formletter>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/1] ser_gigaset: use container_of() instead of detour
2016-02-18 23:46 ` Greg KH
@ 2016-02-18 23:53 ` Paul Bolle
0 siblings, 0 replies; 7+ messages in thread
From: Paul Bolle @ 2016-02-18 23:53 UTC (permalink / raw)
To: Greg KH
Cc: netdev, Dmitry Vyukov, Uwe Kleine-König, Martin Wilck,
Jarkko Sakkinen, Tilman Schmidt, linux-kernel, gigaset307x-common
Hi Greg,
On do, 2016-02-18 at 15:46 -0800, Greg KH wrote:
> <formletter>
>
> This is not the correct way to submit patches for inclusion in the
> stable kernel tree. Please read Documentation/stable_kernel_rules.txt
> for how to do this properly.
>
> </formletter>
What in my submission triggers this formletter?
Thanks,
Paul Bolle
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/1] ser_gigaset: use container_of() instead of detour
2016-02-18 20:29 ` [PATCH 1/1] " Paul Bolle
2016-02-18 21:42 ` Tilman Schmidt
2016-02-18 23:46 ` Greg KH
@ 2016-02-19 20:56 ` David Miller
2 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2016-02-19 20:56 UTC (permalink / raw)
To: pebolle
Cc: netdev, dvyukov, u.kleine-koenig, gregkh, Martin.Wilck,
jarkko.sakkinen, tilman, linux-kernel, gigaset307x-common
From: Paul Bolle <pebolle@tiscali.nl>
Date: Thu, 18 Feb 2016 21:29:08 +0100
> The purpose of gigaset_device_release() is to kfree() the struct
> ser_cardstate that contains our struct device. This is done via a bit of
> a detour. First we make our struct device's driver_data point to the
> container of our struct ser_cardstate (which is a struct cardstate). In
> gigaset_device_release() we then retrieve that driver_data again. And
> after that we finally kfree() the struct ser_cardstate that was saved in
> the struct cardstate.
>
> All of this can be achieved much easier by using container_of() to get
> from our struct device to its container, struct ser_cardstate. Do so.
>
> Note that at the time the detour was implemented commit b8b2c7d845d5
> ("base/platform: assert that dev_pm_domain callbacks are called
> unconditionally") had just entered the tree. That commit disconnected
> our platform_device and our platform_driver. These were reconnected
> again in v4.5-rc2 through commit 25cad69f21f5 ("base/platform: Fix
> platform drivers with no probe callback"). And one of the consequences
> of that fix was that it broke the detour via driver_data. That's because
> it made __device_release_driver() stop being a NOP for our struct device
> and actually do stuff again. One of the things it now does, is setting
> our driver_data to NULL. That, in turn, makes it impossible for
> gigaset_device_release() to get to our struct cardstate. Which has the
> net effect of leaking a struct ser_cardstate at every call of this
> driver's tty close() operation. So using container_of() has the
> additional benefit of actually working.
>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Tested-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Applied, thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-02-19 20:56 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-18 20:29 [PATCH 0/1] ser_gigaset: use container_of() instead of detour Paul Bolle
2016-02-18 20:29 ` [PATCH 1/1] " Paul Bolle
2016-02-18 21:42 ` Tilman Schmidt
2016-02-18 22:14 ` Paul Bolle
2016-02-18 23:46 ` Greg KH
2016-02-18 23:53 ` Paul Bolle
2016-02-19 20:56 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).