diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-10-08 23:44:00 -0400 |
---|---|---|
committer | Stefan Bader <stefan.bader@canonical.com> | 2014-11-25 15:20:27 +0100 |
commit | e7dce3496ccd15cb3e8a0d33ab41d5e217f39de6 (patch) | |
tree | 0312788804698829affefe7da337fb3c389a97a4 | |
parent | 6af4278b89c6f7fd9d980e1595ee88c83232ea5e (diff) | |
download | linux-2.6.32.y-drm33.z-e7dce3496ccd15cb3e8a0d33ab41d5e217f39de6.tar.gz |
fix misuses of f_count() in ppp and netlink
we used to check for "nobody else could start doing anything with
that opened file" by checking that refcount was 2 or less - one
for descriptor table and one we'd acquired in fget() on the way to
wherever we are. That was race-prone (somebody else might have
had a reference to descriptor table and do fget() just as we'd
been checking) and it had become flat-out incorrect back when
we switched to fget_light() on those codepaths - unlike fget(),
it doesn't grab an extra reference unless the descriptor table
is shared. The same change allowed a race-free check, though -
we are safe exactly when refcount is less than 2.
It was a long time ago; pre-2.6.12 for ioctl() (the codepath leading
to ppp one) and 2.6.17 for sendmsg() (netlink one). OTOH,
netlink hadn't grown that check until 3.9 and ppp used to live
in drivers/net, not drivers/net/ppp until 3.1. The bug existed
well before that, though, and the same fix used to apply in old
location of file.
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
(cherry picked from commit 24dff96a37a2ca319e75a74d3929b2de22447ca6)
[wt: apply to drivers/net/ppp_generic.c only]
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
-rw-r--r-- | drivers/net/ppp_generic.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 965adb6174c33..5e9156a8415ef 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -590,7 +590,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (file == ppp->owner) ppp_shutdown_interface(ppp); } - if (atomic_long_read(&file->f_count) <= 2) { + if (atomic_long_read(&file->f_count) < 2) { ppp_release(NULL, file); err = 0; } else |