/*=========================================================================== Copyright (c) 1998-2000, The Santa Cruz Operation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: *Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. *Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. *Neither name of The Santa Cruz Operation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ /* $Id: vpaccess.c,v 1.3 2009/04/10 13:39:23 broeker Exp $ */ /* vpaccess - view path version of the access system call */ #include #include #include "vp.h" #include int vpaccess(char *path, mode_t amode) { char buf[MAXPATH + 1]; int returncode; int i; if ((returncode = access(path, amode)) == -1 && path[0] != '/') { vpinit(NULL); for (i = 1; i < vpndirs; i++) { (void) snprintf(buf, sizeof(buf), "%s/%s", vpdirs[i], path); if ((returncode = access(buf, amode)) != -1) { break; } } } return(returncode); } msg
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2016-10-24 13:59:15 +0200
committerLinus Walleij <linus.walleij@linaro.org>2016-10-31 21:23:44 +0100
commit953b956a2e6d35298e684f251bad98ea6c96f982 (patch)
treea18a8ab665392e1214ce1d5a7ef1cfd538c660e7
parenta909d3e636995ba7c349e2ca5dbb528154d4ac30 (diff)
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>