]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests: ublk: fix user_data truncation for tgt_data >= 256
authorMing Lei <ming.lei@redhat.com>
Fri, 16 Jan 2026 14:18:48 +0000 (22:18 +0800)
committerJens Axboe <axboe@kernel.dk>
Fri, 23 Jan 2026 03:05:41 +0000 (20:05 -0700)
The build_user_data() function packs multiple fields into a __u64
value using bit shifts. Without explicit __u64 casts before shifting,
the shift operations are performed on 32-bit unsigned integers before
being promoted to 64-bit, causing data loss.

Specifically, when tgt_data >= 256, the expression (tgt_data << 24)
shifts on a 32-bit value, truncating the upper 8 bits before promotion
to __u64. Since tgt_data can be up to 16 bits (assertion allows up to
65535), values >= 256 would have their high byte lost.

Add explicit __u64 casts to both op and tgt_data before shifting to
ensure the shift operations happen in 64-bit space, preserving all
bits of the input values.

user_data_to_tgt_data() is only used by stripe.c, in which the max
supported member disks are 4, so won't trigger this issue.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
tools/testing/selftests/ublk/kublk.h

index cb757fd9bf9d8ce5a67f2e01a9487cb824388a3d..69fd5794f3008a61c273039873c3d64175c0a32f 100644 (file)
@@ -262,7 +262,7 @@ static inline __u64 build_user_data(unsigned tag, unsigned op,
        _Static_assert(UBLK_MAX_QUEUES_SHIFT <= 7);
        assert(!(tag >> 16) && !(op >> 8) && !(tgt_data >> 16) && !(q_id >> 7));
 
-       return tag | (op << 16) | (tgt_data << 24) |
+       return tag | ((__u64)op << 16) | ((__u64)tgt_data << 24) |
                (__u64)q_id << 56 | (__u64)is_target_io << 63;
 }