* [PATCH net] ppp: ensure file->private_data can't be overridden @ 2016-03-08 19:14 Guillaume Nault 2016-03-11 19:42 ` David Miller 0 siblings, 1 reply; 5+ messages in thread From: Guillaume Nault @ 2016-03-08 19:14 UTC (permalink / raw) To: netdev; +Cc: Paul Mackerras, David Miller, Alan Cox, Arnd Bergmann Lock ppp_mutex and check that file->private_data is NULL before executing any action in ppp_unattached_ioctl(). The test done by ppp_ioctl() can't be relied upon, because file->private_data may have been updated meanwhile. In which case ppp_unattached_ioctl() will override file->private_data and mess up reference counters or loose pointer to previously allocated PPP unit. In case the test fails, -ENOTTY is returned, just like if ppp_ioctl() had rejected the ioctl in the first place. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> --- This seems to originate in BKL removal : f3ff8a4d80e8 ("ppp: push BKL down into the driver") moved the test on file->private_data (in ppp_ioctl()) out of BKL protection. BKL was then replaced by ppp_mutex in 15fd0cd9a2ad ("net: autoconvert trivial BKL users to private mutex"). drivers/net/ppp/ppp_generic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index d61da9ec..d1dbcb6 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -845,6 +845,11 @@ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, int __user *p = (int __user *)arg; mutex_lock(&ppp_mutex); + if (file->private_data) { + mutex_unlock(&ppp_mutex); + return -ENOTTY; + } + switch (cmd) { case PPPIOCNEWUNIT: /* Create a new ppp unit */ -- 2.7.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net] ppp: ensure file->private_data can't be overridden 2016-03-08 19:14 [PATCH net] ppp: ensure file->private_data can't be overridden Guillaume Nault @ 2016-03-11 19:42 ` David Miller 2016-03-14 17:59 ` Guillaume Nault 0 siblings, 1 reply; 5+ messages in thread From: David Miller @ 2016-03-11 19:42 UTC (permalink / raw) To: g.nault; +Cc: netdev, paulus, alan, arnd From: Guillaume Nault <g.nault@alphalink.fr> Date: Tue, 8 Mar 2016 20:14:30 +0100 > Lock ppp_mutex and check that file->private_data is NULL before > executing any action in ppp_unattached_ioctl(). > The test done by ppp_ioctl() can't be relied upon, because > file->private_data may have been updated meanwhile. In which case > ppp_unattached_ioctl() will override file->private_data and mess up > reference counters or loose pointer to previously allocated PPP unit. > > In case the test fails, -ENOTTY is returned, just like if ppp_ioctl() > had rejected the ioctl in the first place. > > Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> If this thing can disappear on us, then we need to make the entirety of ppp_ioctl() run with the mutex held to fix this properly. Otherwise ->private_data could go NULL on us meanwhile as well. We should hold the mutex, to stabilize the value of ->private_data. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] ppp: ensure file->private_data can't be overridden 2016-03-11 19:42 ` David Miller @ 2016-03-14 17:59 ` Guillaume Nault 2016-03-14 18:57 ` David Miller 0 siblings, 1 reply; 5+ messages in thread From: Guillaume Nault @ 2016-03-14 17:59 UTC (permalink / raw) To: David Miller; +Cc: netdev, paulus, alan, arnd On Fri, Mar 11, 2016 at 02:42:16PM -0500, David Miller wrote: > From: Guillaume Nault <g.nault@alphalink.fr> > Date: Tue, 8 Mar 2016 20:14:30 +0100 > > > Lock ppp_mutex and check that file->private_data is NULL before > > executing any action in ppp_unattached_ioctl(). > > The test done by ppp_ioctl() can't be relied upon, because > > file->private_data may have been updated meanwhile. In which case > > ppp_unattached_ioctl() will override file->private_data and mess up > > reference counters or loose pointer to previously allocated PPP unit. > > > > In case the test fails, -ENOTTY is returned, just like if ppp_ioctl() > > had rejected the ioctl in the first place. > > > > Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> > > If this thing can disappear on us, then we need to make the entirety > of ppp_ioctl() run with the mutex held to fix this properly. > > Otherwise ->private_data could go NULL on us meanwhile as well. > > We should hold the mutex, to stabilize the value of ->private_data. Actually, only ppp_release() can reset ->private_data to NULL. Beyond closing the file's last reference, the only way to trigger it is to run the PPPIOCDETACH ioctl. But even then, ppp_release() isn't called if the file has more than one reference. So ->private_data should never go NULL from under another user. As for setting ->private_data to non-NULL value, this is exclusively handled by ppp_unattached_ioctl(). Since the ppp_mutex is held at the beginning of the function, calls are serialised, but one may still overwrite ->private_data and leak the memory previously pointed to. By testing ->private_data with ppp_mutex held, this patch fixes this issue, and ->private_data is now guaranteed to remain constant after it's been set. Testing ->private_data without lock in ppp_ioctl() before calling ppp_unattached_ioctl() is fine, because either ->private_data is not NULL and thus is stable, or it is and ppp_unattached_ioctl() takes care of not overriding ->private_data, should its value get modified before taking the mutex. I considered moving ppp_mutex up to cover the entirety of ppp_ioctl() too, but finally choosed to handle everything in ppp_unattached_ioctl() because that's where the problem really stands. ppp_ioctl() takes the mutex for historical reasons (semi-automatic BKL removal) and there are several places where holding ppp_mutex seems unnecessary (e.g. for PPPIOCDETACH). So I felt the right direction was to move ppp_mutex further down rather than moving it up to cover the entirety of ppp_ioctl(). In particular, with regard to adding rtnetlink handlers for PPP (which is the objective that lead to those PPP fixes), holding ppp_mutex for too long is a problem. An rtnetlink handler would run under protection of the rtnl mutex, and would need to grab ppp_mutex too (unless we don't associate the PPP unit fd to the net device in the .newlink callback). But currently the PPPIOCNEWUNIT ioctl holds ppp_mutex before taking the rtnl mutex (in ppp_create_interface()). In this context moving ppp_mutex up to ppp_ioctl() makes things more difficult because what's required is, on the contrary, moving it further down so that it gets held after the rtnl mutex. However I'd agree that such consideration shouldn't come into play for fixes on net. It weighted a bit in my decision to not push ppp_mutex up though. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] ppp: ensure file->private_data can't be overridden 2016-03-14 17:59 ` Guillaume Nault @ 2016-03-14 18:57 ` David Miller 2016-03-14 19:09 ` Guillaume Nault 0 siblings, 1 reply; 5+ messages in thread From: David Miller @ 2016-03-14 18:57 UTC (permalink / raw) To: g.nault; +Cc: netdev, paulus, alan, arnd From: Guillaume Nault <g.nault@alphalink.fr> Date: Mon, 14 Mar 2016 18:59:40 +0100 > Testing ->private_data without lock in ppp_ioctl() before calling > ppp_unattached_ioctl() is fine, because either ->private_data is > not NULL and thus is stable, or it is and ppp_unattached_ioctl() > takes care of not overriding ->private_data, should its value get > modified before taking the mutex. This is exactly the ambiguous behavior I want you to avoid. The decision should be atomic from ppp_ioctl()'s test all the way until ppp_unattached_ioctl() does it's work. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] ppp: ensure file->private_data can't be overridden 2016-03-14 18:57 ` David Miller @ 2016-03-14 19:09 ` Guillaume Nault 0 siblings, 0 replies; 5+ messages in thread From: Guillaume Nault @ 2016-03-14 19:09 UTC (permalink / raw) To: David Miller; +Cc: netdev, paulus, alan, arnd On Mon, Mar 14, 2016 at 02:57:59PM -0400, David Miller wrote: > From: Guillaume Nault <g.nault@alphalink.fr> > Date: Mon, 14 Mar 2016 18:59:40 +0100 > > > Testing ->private_data without lock in ppp_ioctl() before calling > > ppp_unattached_ioctl() is fine, because either ->private_data is > > not NULL and thus is stable, or it is and ppp_unattached_ioctl() > > takes care of not overriding ->private_data, should its value get > > modified before taking the mutex. > > This is exactly the ambiguous behavior I want you to avoid. > > The decision should be atomic from ppp_ioctl()'s test all the way > until ppp_unattached_ioctl() does it's work. OK, will fix in v2. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-03-14 19:09 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-03-08 19:14 [PATCH net] ppp: ensure file->private_data can't be overridden Guillaume Nault 2016-03-11 19:42 ` David Miller 2016-03-14 17:59 ` Guillaume Nault 2016-03-14 18:57 ` David Miller 2016-03-14 19:09 ` Guillaume Nault
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).