]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: topology/ioctl: correctly handle kernel types
authorThomas Weißschuh <thomas@t-8ch.de>
Tue, 2 Apr 2024 16:55:29 +0000 (18:55 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Wed, 3 Apr 2024 10:24:42 +0000 (12:24 +0200)
Commit 5d71d711d07a ("libblkid: topolicy/ioctl: use union for multiple data types")
incorrectly assumed that set_ulong and set_int refer to the type
returned by the kernel. Instead the different function pointer names
refer to the types of the function pointers.
However all ioctls, except for the later added BLKGETDISKSEQ, return
32bit integers.
This made libblkid also interpret the upper 32bits too, leading to
garbage values.

Introduce a new member 'kernel_size' to also handle the 64bit
BLKGETDISKSEQ.

Drop data.ul as it is no actually used.

Closes #2904
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
libblkid/src/topology/ioctl.c

index 3560a2fb5375dd21907e713f87081ef115726c31..4be20e80240b7d55bf2eb1b5560b9107eebc05c9 100644 (file)
@@ -24,6 +24,7 @@
 static const struct topology_val {
 
        long  ioc;
+       size_t kernel_size;
 
        /* functions to set probing result */
        int (*set_ulong)(blkid_probe, unsigned long);
@@ -31,11 +32,16 @@ static const struct topology_val {
        int (*set_u64)(blkid_probe, uint64_t);
 
 } topology_vals[] = {
-       { BLKALIGNOFF, NULL, blkid_topology_set_alignment_offset },
-       { BLKIOMIN, blkid_topology_set_minimum_io_size },
-       { BLKIOOPT, blkid_topology_set_optimal_io_size },
-       { BLKPBSZGET, blkid_topology_set_physical_sector_size },
-       { BLKGETDISKSEQ, .set_u64 = blkid_topology_set_diskseq },
+       { BLKALIGNOFF, sizeof(int),
+         .set_int = blkid_topology_set_alignment_offset },
+       { BLKIOMIN, sizeof(int),
+         .set_ulong = blkid_topology_set_minimum_io_size },
+       { BLKIOOPT, sizeof(int),
+         .set_ulong = blkid_topology_set_optimal_io_size },
+       { BLKPBSZGET, sizeof(int),
+         .set_ulong = blkid_topology_set_physical_sector_size },
+       { BLKGETDISKSEQ, sizeof(uint64_t),
+         .set_u64 = blkid_topology_set_diskseq },
        /* we read BLKSSZGET in topology.c */
 };
 
@@ -48,18 +54,21 @@ static int probe_ioctl_tp(blkid_probe pr,
                const struct topology_val *val = &topology_vals[i];
                int rc = 1;
                union {
-                       unsigned long ul;
-                       int i;
+                       int s32;
                        uint64_t u64;
-               } data;
+               } data = { 0 };
 
                if (ioctl(pr->fd, val->ioc, &data) == -1)
                        goto nothing;
 
+               /* Convert from kernel to libblkid type */
+               if (val->kernel_size == 4)
+                       data.u64 = data.s32;
+
                if (val->set_int)
-                       rc = val->set_int(pr, data.i);
+                       rc = val->set_int(pr, data.u64);
                else if (val->set_ulong)
-                       rc = val->set_ulong(pr, data.ul);
+                       rc = val->set_ulong(pr, data.u64);
                else
                        rc = val->set_u64(pr, data.u64);