[PATCH] invalid lseek when determining uuid of (possibly corrupt) fat

Clemens Helfmeier clemensh at cs.tu-berlin.de
Mon Nov 24 07:02:31 PST 2008


Hi everybody,

I am new to the list.

There is a little problem with my busybox (1.12.2, gentoo ebuild 1.12.2-r1):
busybox mount -vv UUID=bfe76a13-f0f9-4512-9968-573b4cdecf1a /mnt/tmp/
mount: lseek(2701840384): Invalid argument

My setup is like this:
On a USB Stick:
# blkid /dev/sdc5
/dev/sdc5: UUID="bfe76a13-f0f9-4512-9968-573b4cdecf1a" SEC_TYPE="ext2"
TYPE="ext3"
# blkid /dev/sdc1
/dev/sdc1: UUID="F0D8-E3CE" TYPE="vfat" SEC_TYPE="msdos"
# fdisk -l /dev/sdc

Disk /dev/sdc: 2004 MB, 2004353024 bytes
62 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 3844 * 512 = 1968128 bytes
Disk identifier: 0x4a3e5bea

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1               1         955     1835479    b  W95 FAT32
/dev/sdc2             956        1018      121086    5  Extended
/dev/sdc5   *         956        1018      121055   83  Linux

Mounting works like this:
(busybox mount):
 # busybox mount /dev/sdc1 /tmp/
 # busybox umount /tmp/
 # busybox mount /dev/sdc5 /tmp/
 # busybox umount /tmp/
 # busybox mount UUID=bfe76a13-f0f9-4512-9968-573b4cdecf1a /tmp/
mount: lseek(2701840384): Invalid argument
 # busybox mount UUID=F0D8-E3CE /tmp/
mount: lseek(2701840384): Invalid argument

After looking at the code, i enabled dbg in volume_id_internal.h and found out,
that the failing mount calls do something like this (this does not change when
selecting the other uuid):

busybox -v mount UUID=bfe76a13-f0f9-4512-9968-573b4cdecf1a /tmp/
[...]
mount: /proc/partitions: maj:8 min:32 sz:1957376 name:'sdc'
mount: /proc/partitions: maj:8 min:33 sz:1835479 name:'sdc1'
mount: probing at offset 0x0, size 0x70075c00
mount: get buffer off 0x70060000(1879441408), len 0x800
mount: read seekbuf off:0x70060000 len:0x800
mount: got 0x800 (2048) bytes
mount: get buffer off 0x0(0), len 0x2
mount: read sbbuf len:0x2
mount: got 0x2 (2) bytes
mount: probing at offset 0x0
mount: get buffer off 0x0(0), len 0x200
mount: read sbbuf len:0x200
mount: got 0x200 (512) bytes
mount: sector_size 0x200
mount: sectors_per_cluster 0x8
mount: reserved 0x24
mount: sect_count 0x3803ae
mount: fat_length 0xdfa
mount: dir_size 0x0
mount: cluster_count 0x6fcf2
mount: root dir cluster 2
mount: next cluster 2
mount: cluster offset 0x383000
mount: get buffer off 0x383000(3682304), len 0x1000
mount: read seekbuf off:0x383000 len:0x1000
mount: got 0x1000 (4096) bytes
mount: expected entries 0x80
mount: skip dir entry
[..]
mount: get buffer off 0x4808(18440), len 0x1000
mount: read sbbuf len:0x5808
mount: got 0x5808 (22536) bytes
mount: next cluster 11190
mount: cluster offset 0x2f37000
mount: get buffer off 0x2f37000(49508352), len 0x1000
mount: read seekbuf off:0x2f37000 len:0x1000
mount: got 0x1000 (4096) bytes
mount: expected entries 0x80
mount: get buffer off 0xf6d8(63192), len 0x1000
mount: read sbbuf len:0x106d8
mount: got 0x106d8 (67288) bytes
mount: next cluster 268435455
mount: cluster offset 0x380000
mount: get buffer off 0x380000(3670016), len 0x1000
mount: read seekbuf off:0x380000 len:0x1000
mount: got 0x1000 (4096) bytes
mount: expected entries 0x80
mount: skip dir entry
[..]
mount: get buffer off 0x400047fc(1073760252), len 0x1000
mount: read seekbuf off:0x400047fc len:0x1000
mount: got 0x1000 (4096) bytes
mount: next cluster 154351922
mount: cluster offset 0x33cb3000
mount: get buffer off 0x33cb3000(868954112), len 0x1000
mount: read seekbuf off:0x33cb3000 len:0x1000
mount: got 0x1000 (4096) bytes
mount: expected entries 0x80
mount: skip dir entry
[..]
mount: get buffer off 0x24cd2cc8(617426120), len 0x1000
mount: read seekbuf off:0x24cd2cc8 len:0x1000
mount: got 0x1000 (4096) bytes
mount: next cluster 17435948
mount: cluster offset 0xa10ad000
mount: get buffer off 0xa10ad000(2701840384), len 0x1000
mount: read seekbuf off:0xa10ad000 len:0x1000
mount: lseek(2701840384): Invalid argument

I think there is something wrong when calculating the last cluster offset value.
The filesystem seems to be ok (fsck does not complain anything) and the
partition table looks good, too (fdisk's verify does not complain anything).
This started happening after writing to the fat partition from a friends vista
setup.

I have not found any validity checking of the values read in
volume_id_probe_vfat (util-linux/volume_id/fat.c). I think in case of failure to
determine UUID of a certain partition, busybox mount should tell some error but
continue finding the UUIDs of all the other partitions in the system. When I try
to mount the ext3 partition, it should not fail because of the vfat partition
which I am not interested in at that moment.

Here is what i changed in order to get it working (i think this is bad, but
please comment!). this patch gets both partition working with UUID parameter to
mount.

Clemens

diff -Nur busybox-1.12.2/util-linux/volume_id/fat.c
busybox-1.12.2-patched/util-linux/volume_id/fat.c
--- busybox-1.12.2/util-linux/volume_id/fat.c   2008-09-28 20:04:30.000000000 
+0200
+++ busybox-1.12.2-patched/util-linux/volume_id/fat.c   2008-11-24 
15:17:17.000000000 +0100
@@ -310,6 +310,11 @@
                next = le32_to_cpu(*((uint32_t *) buf) & 0x0fffffff);
                if (next == 0)
                        break;
+
+                if (next > cluster_count) {
+                        dbg("invalid cluster %u. cluster_count=%u", next, 
cluster_count);
+                        break;
+                }
        }
        if (maxloop == 0)
                dbg("reached maximum follow count of root cluster chain, give 
up");







More information about the busybox mailing list