]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commit
gpio: GPIO_GET_LINE{HANDLE,EVENT}_IOCTL: Fix file descriptor leak
authorLars-Peter Clausen <lars@metafoo.de>
Mon, 24 Oct 2016 11:59:15 +0000 (13:59 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 31 Oct 2016 20:23:44 +0000 (21:23 +0100)
commit953b956a2e6d35298e684f251bad98ea6c96f982
treea18a8ab665392e1214ce1d5a7ef1cfd538c660e7
parenta909d3e636995ba7c349e2ca5dbb528154d4ac30
gpio: GPIO_GET_LINE{HANDLE,EVENT}_IOCTL: Fix file descriptor leak

When allocating a new line handle or event a file is allocated that it is
associated to. The file is attached to a file descriptor of the current
process and the file descriptor is returned to userspace using
copy_to_user(). If this copy operation fails the line handle or event
allocation is aborted, all acquired resources are freed and an error is
returned.

But the file struct is not freed and left attached to the userspace
application and even though the file descriptor number was not copied it is
trivial to guess. If a userspace application performs a IOCTL on such a
left over file descriptor it will trigger a use-after-free and if the file
descriptor is closed (latest when the application exits) a double-free is
triggered.

anon_inode_getfd() performs 3 tasks, allocate a file struct, allocate a
file descriptor for the current process and install the file struct in the
file descriptor. As soon as the file struct is installed in the file
descriptor it is accessible by userspace (even if the IOCTL itself hasn't
completed yet), this means uninstalling the fd on the error path is not an
option, since userspace might already got a reference to the file.

Instead anon_inode_getfd() needs to be broken into its individual steps.
The allocation of the file struct and file descriptor is done first, then
the copy_to_user() is executed and only if it succeeds the file is
installed.

Since the file struct is reference counted it can not be just freed, but
its reference needs to be dropped, which will also call the release()
callback, which will free the state attached to the file. So in this case
the normal error cleanup path should not be taken.

Cc: stable@vger.kernel.org
Fixes: d932cd49182f ("gpio: free handles in fringe cases")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib.c