]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
mi: Cast values to u32 if shift overflows int
authorCaleb Sander <csander@purestorage.com>
Thu, 2 Nov 2023 13:29:46 +0000 (14:29 +0100)
committerDaniel Wagner <wagi@monom.org>
Thu, 2 Nov 2023 13:31:26 +0000 (14:31 +0100)
Bit shifts that overflow the resulting type are undefined behavior in C.
C arithmetic promotes to ints all smaller integer types.
There are several places where a 32-bit unsigned value
is constructed by shifting a u8 or u16 to the most significant bits.
Since this overflows a signed 32-bit integer,
explicitly cast to u32 to avoid the UB.
Technically, an int is allowed to only be 16 bits,
so any shift that could set bit 15 or higher is UB.
But platforms where int is s16 are not very common,
so it's likely not worth the effort to fix the code.

Signed-off-by: Caleb Sander <csander@purestorage.com>
src/nvme/mi.c

index 95f5224eb69571e83764516aace6e7e17fcb575d..82ed88a7ffe62c3d9e94262ecd1a5baa72884c88 100644 (file)
@@ -1048,7 +1048,7 @@ int nvme_mi_admin_set_features(nvme_mi_ctrl_t ctrl,
                               nvme_admin_set_features);
 
        req_hdr.cdw1 = cpu_to_le32(args->nsid);
-       req_hdr.cdw10 = cpu_to_le32((args->save ? 1 : 0) << 31 |
+       req_hdr.cdw10 = cpu_to_le32((__u32)!!args->save << 31 |
                                    (args->fid & 0xff));
        req_hdr.cdw14 = cpu_to_le32(args->uuidx & 0x7f);
        req_hdr.cdw11 = cpu_to_le32(args->cdw11);
@@ -1220,7 +1220,7 @@ int nvme_mi_admin_fw_commit(nvme_mi_ctrl_t ctrl,
        nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id,
                               nvme_admin_fw_commit);
 
-       req_hdr.cdw10 = cpu_to_le32(((args->bpid & 0x1) << 31) |
+       req_hdr.cdw10 = cpu_to_le32(((__u32)(args->bpid & 0x1) << 31) |
                                    ((args->action & 0x7) << 3) |
                                    ((args->slot & 0x7) << 0));