]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ublk: don't allow user copy for unprivileged device
authorMing Lei <ming.lei@redhat.com>
Wed, 16 Oct 2024 13:48:47 +0000 (21:48 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 16 Oct 2024 14:08:18 +0000 (08:08 -0600)
UBLK_F_USER_COPY requires userspace to call write() on ublk char
device for filling request buffer, and unprivileged device can't
be trusted.

So don't allow user copy for unprivileged device.

Cc: stable@vger.kernel.org
Fixes: 1172d5b8beca ("ublk: support user copy")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20241016134847.2911721-1-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/ublk_drv.c
include/uapi/linux/ublk_cmd.h

index a6c8e5cc6051730f23e25c6788a9a5ced7c92441..6ba2c1dd1d878a6a797b41f270a913ae84e5071e 100644 (file)
@@ -2380,10 +2380,19 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
         * TODO: provide forward progress for RECOVERY handler, so that
         * unprivileged device can benefit from it
         */
-       if (info.flags & UBLK_F_UNPRIVILEGED_DEV)
+       if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
                info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE |
                                UBLK_F_USER_RECOVERY);
 
+               /*
+                * For USER_COPY, we depends on userspace to fill request
+                * buffer by pwrite() to ublk char device, which can't be
+                * used for unprivileged device
+                */
+               if (info.flags & UBLK_F_USER_COPY)
+                       return -EINVAL;
+       }
+
        /* the created device is always owned by current user */
        ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid);
 
index c8dc5f8ea699627402dc2069615acd066f103981..12873639ea9644ea7264e5577c672dae54643489 100644 (file)
 /* use ioctl encoding for uring command */
 #define UBLK_F_CMD_IOCTL_ENCODE        (1UL << 6)
 
-/* Copy between request and user buffer by pread()/pwrite() */
+/*
+ *  Copy between request and user buffer by pread()/pwrite()
+ *
+ *  Not available for UBLK_F_UNPRIVILEGED_DEV, otherwise userspace may
+ *  deceive us by not filling request buffer, then kernel uninitialized
+ *  data may be leaked.
+ */
 #define UBLK_F_USER_COPY       (1UL << 7)
 
 /*