Rely on the fd exit path machinery.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 drivers/iio/industrialio-buffer.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/industrialio-buffer.c 
b/drivers/iio/industrialio-buffer.c
index 2c9ec93dff47..9fb15bf82d0a 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -2041,7 +2041,7 @@ static long iio_device_buffer_getfd(struct iio_dev 
*indio_dev, unsigned long arg
        int __user *ival = (int __user *)arg;
        struct iio_dev_buffer_pair *ib;
        struct iio_buffer *buffer;
-       int fd, idx, ret;
+       int idx, ret, fdno;
 
        if (copy_from_user(&idx, ival, sizeof(idx)))
                return -EFAULT;
@@ -2067,26 +2067,18 @@ static long iio_device_buffer_getfd(struct iio_dev 
*indio_dev, unsigned long arg
        ib->indio_dev = indio_dev;
        ib->buffer = buffer;
 
-       fd = anon_inode_getfd("iio:buffer", &iio_buffer_chrdev_fileops,
-                             ib, O_RDWR | O_CLOEXEC);
-       if (fd < 0) {
-               ret = fd;
+       FD_PREPARE(fdf, O_RDWR | O_CLOEXEC,
+                  anon_inode_getfile("iio:buffer", &iio_buffer_chrdev_fileops,
+                                     ib, O_RDWR | O_CLOEXEC));
+       if (IS_ERR(fdf)) {
+               ret = PTR_ERR(fdf);
                goto error_free_ib;
        }
 
-       if (copy_to_user(ival, &fd, sizeof(fd))) {
-               /*
-                * "Leak" the fd, as there's not much we can do about this
-                * anyway. 'fd' might have been closed already, as
-                * anon_inode_getfd() called fd_install() on it, which made
-                * it reachable by userland.
-                *
-                * Instead of allowing a malicious user to play tricks with
-                * us, rely on the process exit path to do any necessary
-                * cleanup, as in releasing the file, if still needed.
-                */
+       fdno = fd_prepare_fd(fdf);
+       /* The staged file is dropped with its descriptor if this faults. */
+       if (copy_to_user(ival, &fdno, sizeof(fdno)))
                return -EFAULT;
-       }
 
        return 0;
 

-- 
2.53.0


Reply via email to