]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nvme: reject invalid pr_read_keys() num_keys values
authorStefan Hajnoczi <stefanha@redhat.com>
Mon, 1 Dec 2025 21:43:27 +0000 (16:43 -0500)
committerJens Axboe <axboe@kernel.dk>
Thu, 4 Dec 2025 14:19:26 +0000 (07:19 -0700)
The pr_read_keys() interface has a u32 num_keys parameter. The NVMe
Reservation Report command has a u32 maximum length. Reject num_keys
values that are too large to fit.

This will become important when pr_read_keys() is exposed to untrusted
userspace via an <linux/pr.h> ioctl.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/nvme/host/pr.c

index ca6a74607b139795687217e3827beaf761f62057..ad2ecc2f49a97217b91e86452bb0277f81da0cc0 100644 (file)
@@ -228,7 +228,8 @@ retry:
 static int nvme_pr_read_keys(struct block_device *bdev,
                struct pr_keys *keys_info)
 {
-       u32 rse_len, num_keys = keys_info->num_keys;
+       size_t rse_len;
+       u32 num_keys = keys_info->num_keys;
        struct nvme_reservation_status_ext *rse;
        int ret, i;
        bool eds;
@@ -238,6 +239,9 @@ static int nvme_pr_read_keys(struct block_device *bdev,
         * enough to get enough keys to fill the return keys buffer.
         */
        rse_len = struct_size(rse, regctl_eds, num_keys);
+       if (rse_len > U32_MAX)
+               return -EINVAL;
+
        rse = kzalloc(rse_len, GFP_KERNEL);
        if (!rse)
                return -ENOMEM;