nvme-ioctl: move capable() admin check to the end
authorKeith Busch <kbusch@kernel.org>
Tue, 2 May 2023 18:43:41 +0000 (11:43 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Jan 2024 10:51:41 +0000 (11:51 +0100)
[ Upstream commit 7be866b1cf0bf1dfa74480fe8097daeceda68622 ]

This can be an expensive call on some kernel configs. Move it to the end
after checking the cheaper ways to determine if the command is allowed.

Reviewed-by: Jens Axboe <axboe@kernel.dk>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/nvme/host/ioctl.c

index 529b995..4939ed3 100644 (file)
@@ -18,15 +18,12 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
 {
        u32 effects;
 
-       if (capable(CAP_SYS_ADMIN))
-               return true;
-
        /*
         * Do not allow unprivileged passthrough on partitions, as that allows an
         * escape from the containment of the partition.
         */
        if (flags & NVME_IOCTL_PARTITION)
-               return false;
+               goto admin;
 
        /*
         * Do not allow unprivileged processes to send vendor specific or fabrics
@@ -34,7 +31,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
         */
        if (c->common.opcode >= nvme_cmd_vendor_start ||
            c->common.opcode == nvme_fabrics_command)
-               return false;
+               goto admin;
 
        /*
         * Do not allow unprivileged passthrough of admin commands except
@@ -53,7 +50,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
                                return true;
                        }
                }
-               return false;
+               goto admin;
        }
 
        /*
@@ -63,7 +60,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
         */
        effects = nvme_command_effects(ns->ctrl, ns, c->common.opcode);
        if (!(effects & NVME_CMD_EFFECTS_CSUPP))
-               return false;
+               goto admin;
 
        /*
         * Don't allow passthrough for command that have intrusive (or unknown)
@@ -72,16 +69,20 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
        if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC |
                        NVME_CMD_EFFECTS_UUID_SEL |
                        NVME_CMD_EFFECTS_SCOPE_MASK))
-               return false;
+               goto admin;
 
        /*
         * Only allow I/O commands that transfer data to the controller or that
         * change the logical block contents if the file descriptor is open for
         * writing.
         */
-       if (nvme_is_write(c) || (effects & NVME_CMD_EFFECTS_LBCC))
-               return open_for_write;
+       if ((nvme_is_write(c) || (effects & NVME_CMD_EFFECTS_LBCC)) &&
+           !open_for_write)
+               goto admin;
+
        return true;
+admin:
+       return capable(CAP_SYS_ADMIN);
 }
 
 /*