* Re: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
@ 2021-03-12 14:47 ` lyl2019
0 siblings, 0 replies; 13+ messages in thread
From: lyl2019 @ 2021-03-12 14:47 UTC (permalink / raw)
To: Tom Parkin; +Cc: paulus, davem, linux-ppp, netdev, linux-kernel
DQoNCg0KPiAtLS0tLeWOn+Wni+mCruS7ti0tLS0tDQo+IOWPkeS7tuS6ujogIlRvbSBQYXJraW4i
IDx0cGFya2luQGthdGFsaXguY29tPg0KPiDlj5HpgIHml7bpl7Q6IDIwMjEtMDMtMTIgMTg6MTI6
NTggKOaYn+acn+S6lCkNCj4g5pS25Lu25Lq6OiBseWwyMDE5QG1haWwudXN0Yy5lZHUuY24NCj4g
5oqE6YCBOiBwYXVsdXNAc2FtYmEub3JnLCBkYXZlbUBkYXZlbWxvZnQubmV0LCBsaW51eC1wcHBA
dmdlci5rZXJuZWwub3JnLCBuZXRkZXZAdmdlci5rZXJuZWwub3JnLCBsaW51eC1rZXJuZWxAdmdl
ci5rZXJuZWwub3JnDQo+IOS4u+mimDogUmU6IFtCVUddIG5ldC9wcHA6IEEgdXNlIGFmdGVyIGZy
ZWUgaW4gcHBwX3VucmVnaXN0ZXJfY2hhbm5lDQo+IA0KPiBUaGFua3MgZm9yIHRoZSByZXBvcnQh
DQo+IA0KPiBPbiAgVGh1LCBNYXIgMTEsIDIwMjEgYXQgMjA6MzQ6NDQgKzA4MDAsIGx5bDIwMTlA
bWFpbC51c3RjLmVkdS5jbiB3cm90ZToNCj4gPiBGaWxlOiBkcml2ZXJzL25ldC9wcHAvcHBwX2dl
bmVyaWMuYw0KPiA+IA0KPiA+IEluIHBwcF91bnJlZ2lzdGVyX2NoYW5uZWwsIHBjaCBjb3VsZCBi
ZSBmcmVlZCBpbiBwcHBfdW5icmlkZ2VfY2hhbm5lbHMoKQ0KPiA+IGJ1dCBhZnRlciB0aGF0IHBj
aCBpcyBzdGlsbCBpbiB1c2UuIEluc2lkZSB0aGUgZnVuY3Rpb24gcHBwX3VuYnJpZGdlX2NoYW5u
ZWxzLA0KPiA+IGlmICJwY2hiYiA9PSBwY2giIGlzIHRydWUgYW5kIHRoZW4gcGNoIHdpbGwgYmUg
ZnJlZWQuDQo+IA0KPiBEbyB5b3UgaGF2ZSBhIHdheSB0byByZXByb2R1Y2UgYSB1c2UtYWZ0ZXIt
ZnJlZSBzY2VuYXJpbz8NCj4gDQo+IEZyb20gc3RhdGljIGFuYWx5c2lzIEknbSBub3Qgc3VyZSBo
b3cgcGNoIHdvdWxkIGJlIGZyZWVkIGluDQo+IHBwcF91bmJyaWRnZV9jaGFubmVscyB3aGVuIGNh
bGxlZCB2aWEuIHBwcF91bnJlZ2lzdGVyX2NoYW5uZWwuDQo+IA0KPiBJbiB0aGVvcnkgKGF0IGxl
YXN0ISkgdGhlIGNhbGxlciBvZiBwcHBfcmVnaXN0ZXJfbmV0X2NoYW5uZWwgaG9sZHMgDQo+IGEg
cmVmZXJlbmNlIG9uIHN0cnVjdCBjaGFubmVsIHdoaWNoIHBwcF91bnJlZ2lzdGVyX2NoYW5uZWwg
ZHJvcHMuDQo+IA0KPiBFYWNoIGNoYW5uZWwgaW4gYSBicmlkZ2VkIHBhaXIgaG9sZHMgYSByZWZl
cmVuY2Ugb24gdGhlIG90aGVyLg0KPiANCj4gSGVuY2Ugb24gcmV0dXJuIGZyb20gcHBwX3VuYnJp
ZGdlX2NoYW5uZWxzLCB0aGUgY2hhbm5lbCBzaG91bGQgbm90IGhhdmUNCj4gYmVlbiBmcmVlZCAo
aW4gdGhpcyBjb2RlIHBhdGgpIGJlY2F1c2UgdGhlIHBwcF9yZWdpc3Rlcl9uZXRfY2hhbm5lbA0K
PiByZWZlcmVuY2UgaGFzIG5vdCB5ZXQgYmVlbiBkcm9wcGVkLg0KPiANCj4gTWF5YmUgdGhlcmUg
aXMgYW4gaXNzdWUgd2l0aCB0aGUgcmVmZXJlbmNlIGNvdW50aW5nIG9yIGEgcmFjZSBvZiBzb21l
DQo+IHNvcnQ/DQo+IA0KPiA+IEkgY2hlY2tlZCB0aGUgY29tbWl0IGhpc3RvcnkgYW5kIGZvdW5k
IHRoYXQgdGhpcyBwcm9ibGVtIGlzIGludHJvZHVjZWQgZnJvbQ0KPiA+IDRjZjQ3NmNlZDQ1ZDcg
KCJwcHA6IGFkZCBQUFBJT0NCUklER0VDSEFOIGFuZCBQUFBJT0NVTkJSSURHRUNIQU4gaW9jdGxz
IikuDQo+ID4gDQo+ID4gSSBoYXZlIG5vIGlkZWEgYWJvdXQgaG93IHRvIGdlbmVyYXRlIGEgc3Vp
dGFibGUgcGF0Y2gsIHNvcnJ5Lg0KDQpUaGlzIGlzc3VlIHdhcyByZXBvcnRlZCBieSBhIHBhdGgt
c2Vuc2l0aXZlIHN0YXRpYyBhbmFseXplciBkZXZlbG9wZWQgYnkgb3VyIExhYiwNCnRodXMgaSBo
YXZlIG5vdCBhIGNyYXNoIG9yIGJ1ZyBsb2cuDQoNCkFzIHRoZSByZXR1cm4gdHlwZSBvZiBwcHBf
dW5icmlkZ2VfY2hhbm5lbHMoKSBpcyBhIGludCwgY2FuIHdlIHJldHVybiBhIHZhbHVlIHRvDQpp
bmZvcm0gY2FsbGVyIHRoYXQgdGhlIGNoYW5uZWwgaXMgZnJlZWQ/DQoNCg=
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
2021-03-12 14:47 ` lyl2019
(?)
@ 2021-03-15 9:57 ` Tom Parkin
-1 siblings, 0 replies; 13+ messages in thread
From: Tom Parkin @ 2021-03-15 9:57 UTC (permalink / raw)
To: lyl2019; +Cc: paulus, davem, linux-ppp, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2631 bytes --]
On Fri, Mar 12, 2021 at 22:47:53 +0800, lyl2019@mail.ustc.edu.cn wrote:
>
>
>
> > -----原始邮件-----
> > 发件人: "Tom Parkin" <tparkin@katalix.com>
> > 发送时间: 2021-03-12 18:12:58 (星期五)
> > 收件人: lyl2019@mail.ustc.edu.cn
> > 抄送: paulus@samba.org, davem@davemloft.net, linux-ppp@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
> > 主题: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
> >
> > Thanks for the report!
> >
> > On Thu, Mar 11, 2021 at 20:34:44 +0800, lyl2019@mail.ustc.edu.cn wrote:
> > > File: drivers/net/ppp/ppp_generic.c
> > >
> > > In ppp_unregister_channel, pch could be freed in ppp_unbridge_channels()
> > > but after that pch is still in use. Inside the function ppp_unbridge_channels,
> > > if "pchbb == pch" is true and then pch will be freed.
> >
> > Do you have a way to reproduce a use-after-free scenario?
> >
> > From static analysis I'm not sure how pch would be freed in
> > ppp_unbridge_channels when called via. ppp_unregister_channel.
> >
> > In theory (at least!) the caller of ppp_register_net_channel holds
> > a reference on struct channel which ppp_unregister_channel drops.
> >
> > Each channel in a bridged pair holds a reference on the other.
> >
> > Hence on return from ppp_unbridge_channels, the channel should not have
> > been freed (in this code path) because the ppp_register_net_channel
> > reference has not yet been dropped.
> >
> > Maybe there is an issue with the reference counting or a race of some
> > sort?
> >
> > > I checked the commit history and found that this problem is introduced from
> > > 4cf476ced45d7 ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls").
> > >
> > > I have no idea about how to generate a suitable patch, sorry.
>
> This issue was reported by a path-sensitive static analyzer developed by our Lab,
> thus i have not a crash or bug log.
Does the analyzer report the sequence of events that lead to a
possible use-after-free? Is it starting from the assumption that
ppp_unbridge_channels is called with pch->file.refcnt == 1?
> As the return type of ppp_unbridge_channels() is a int, can we return a value to
> inform caller that the channel is freed?
If ppp_unbridge_channels frees the channel in the
ppp_unregister_channel call path, that implies that
ppp_unregister_channel is called when only the bridge is keeping the
channel alive. So the caller is attempting to drop a reference it
doesn't in fact have.
It might be preferable to defensively code against that possibility of
course.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
2021-03-12 14:47 ` lyl2019
@ 2021-03-15 12:18 ` Guillaume Nault
-1 siblings, 0 replies; 13+ messages in thread
From: Guillaume Nault @ 2021-03-15 12:18 UTC (permalink / raw)
To: lyl2019; +Cc: Tom Parkin, paulus, davem, linux-ppp, netdev, linux-kernel
On Fri, Mar 12, 2021 at 10:47:53PM +0800, lyl2019@mail.ustc.edu.cn wrote:
>
>
>
> > -----原始邮件-----
> > 发件人: "Tom Parkin" <tparkin@katalix.com>
> > 发送时间: 2021-03-12 18:12:58 (星期五)
> > 收件人: lyl2019@mail.ustc.edu.cn
> > 抄送: paulus@samba.org, davem@davemloft.net, linux-ppp@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
> > 主题: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
> >
> > Thanks for the report!
> >
> > On Thu, Mar 11, 2021 at 20:34:44 +0800, lyl2019@mail.ustc.edu.cn wrote:
> > > File: drivers/net/ppp/ppp_generic.c
> > >
> > > In ppp_unregister_channel, pch could be freed in ppp_unbridge_channels()
> > > but after that pch is still in use. Inside the function ppp_unbridge_channels,
> > > if "pchbb == pch" is true and then pch will be freed.
> >
> > Do you have a way to reproduce a use-after-free scenario?
> >
> > From static analysis I'm not sure how pch would be freed in
> > ppp_unbridge_channels when called via. ppp_unregister_channel.
> >
> > In theory (at least!) the caller of ppp_register_net_channel holds
> > a reference on struct channel which ppp_unregister_channel drops.
> >
> > Each channel in a bridged pair holds a reference on the other.
> >
> > Hence on return from ppp_unbridge_channels, the channel should not have
> > been freed (in this code path) because the ppp_register_net_channel
> > reference has not yet been dropped.
> >
> > Maybe there is an issue with the reference counting or a race of some
> > sort?
> >
> > > I checked the commit history and found that this problem is introduced from
> > > 4cf476ced45d7 ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls").
> > >
> > > I have no idea about how to generate a suitable patch, sorry.
>
> This issue was reported by a path-sensitive static analyzer developed by our Lab,
> thus i have not a crash or bug log.
>
> As the return type of ppp_unbridge_channels() is a int, can we return a value to
> inform caller that the channel is freed?
I don't think this is going to improve anything, as
ppp_unregister_channel() couldn't take any corrective action anyway.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
@ 2021-03-15 12:18 ` Guillaume Nault
0 siblings, 0 replies; 13+ messages in thread
From: Guillaume Nault @ 2021-03-15 12:18 UTC (permalink / raw)
To: lyl2019; +Cc: Tom Parkin, paulus, davem, linux-ppp, netdev, linux-kernel
On Fri, Mar 12, 2021 at 10:47:53PM +0800, lyl2019@mail.ustc.edu.cn wrote:
>
>
>
> > -----原始邮件-----
> > 发件人: "Tom Parkin" <tparkin@katalix.com>
> > 发送时间: 2021-03-12 18:12:58 (星期五)
> > 收件人: lyl2019@mail.ustc.edu.cn
> > 抄送: paulus@samba.org, davem@davemloft.net, linux-ppp@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
> > 主题: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
> >
> > Thanks for the report!
> >
> > On Thu, Mar 11, 2021 at 20:34:44 +0800, lyl2019@mail.ustc.edu.cn wrote:
> > > File: drivers/net/ppp/ppp_generic.c
> > >
> > > In ppp_unregister_channel, pch could be freed in ppp_unbridge_channels()
> > > but after that pch is still in use. Inside the function ppp_unbridge_channels,
> > > if "pchbb = pch" is true and then pch will be freed.
> >
> > Do you have a way to reproduce a use-after-free scenario?
> >
> > From static analysis I'm not sure how pch would be freed in
> > ppp_unbridge_channels when called via. ppp_unregister_channel.
> >
> > In theory (at least!) the caller of ppp_register_net_channel holds
> > a reference on struct channel which ppp_unregister_channel drops.
> >
> > Each channel in a bridged pair holds a reference on the other.
> >
> > Hence on return from ppp_unbridge_channels, the channel should not have
> > been freed (in this code path) because the ppp_register_net_channel
> > reference has not yet been dropped.
> >
> > Maybe there is an issue with the reference counting or a race of some
> > sort?
> >
> > > I checked the commit history and found that this problem is introduced from
> > > 4cf476ced45d7 ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls").
> > >
> > > I have no idea about how to generate a suitable patch, sorry.
>
> This issue was reported by a path-sensitive static analyzer developed by our Lab,
> thus i have not a crash or bug log.
>
> As the return type of ppp_unbridge_channels() is a int, can we return a value to
> inform caller that the channel is freed?
I don't think this is going to improve anything, as
ppp_unregister_channel() couldn't take any corrective action anyway.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
2021-03-15 12:18 ` Guillaume Nault
(?)
@ 2021-03-15 16:58 ` Tom Parkin
-1 siblings, 0 replies; 13+ messages in thread
From: Tom Parkin @ 2021-03-15 16:58 UTC (permalink / raw)
To: Guillaume Nault; +Cc: lyl2019, paulus, davem, linux-ppp, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2494 bytes --]
On Mon, Mar 15, 2021 at 13:18:24 +0100, Guillaume Nault wrote:
> On Fri, Mar 12, 2021 at 10:47:53PM +0800, lyl2019@mail.ustc.edu.cn wrote:
> >
> >
> >
> > > -----原始邮件-----
> > > 发件人: "Tom Parkin" <tparkin@katalix.com>
> > > 发送时间: 2021-03-12 18:12:58 (星期五)
> > > 收件人: lyl2019@mail.ustc.edu.cn
> > > 抄送: paulus@samba.org, davem@davemloft.net, linux-ppp@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
> > > 主题: Re: [BUG] net/ppp: A use after free in ppp_unregister_channe
> > >
> > > Thanks for the report!
> > >
> > > On Thu, Mar 11, 2021 at 20:34:44 +0800, lyl2019@mail.ustc.edu.cn wrote:
> > > > File: drivers/net/ppp/ppp_generic.c
> > > >
> > > > In ppp_unregister_channel, pch could be freed in ppp_unbridge_channels()
> > > > but after that pch is still in use. Inside the function ppp_unbridge_channels,
> > > > if "pchbb == pch" is true and then pch will be freed.
> > >
> > > Do you have a way to reproduce a use-after-free scenario?
> > >
> > > From static analysis I'm not sure how pch would be freed in
> > > ppp_unbridge_channels when called via. ppp_unregister_channel.
> > >
> > > In theory (at least!) the caller of ppp_register_net_channel holds
> > > a reference on struct channel which ppp_unregister_channel drops.
> > >
> > > Each channel in a bridged pair holds a reference on the other.
> > >
> > > Hence on return from ppp_unbridge_channels, the channel should not have
> > > been freed (in this code path) because the ppp_register_net_channel
> > > reference has not yet been dropped.
> > >
> > > Maybe there is an issue with the reference counting or a race of some
> > > sort?
> > >
> > > > I checked the commit history and found that this problem is introduced from
> > > > 4cf476ced45d7 ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls").
> > > >
> > > > I have no idea about how to generate a suitable patch, sorry.
> >
> > This issue was reported by a path-sensitive static analyzer developed by our Lab,
> > thus i have not a crash or bug log.
> >
> > As the return type of ppp_unbridge_channels() is a int, can we return a value to
> > inform caller that the channel is freed?
>
> I don't think this is going to improve anything, as
> ppp_unregister_channel() couldn't take any corrective action anyway.
I agree with you to be honest.
I think the best ppp_unregister_channel could to is to not access pch
again.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread