diff options
author | Karel Zak | 2009-10-06 09:17:06 +0200 |
---|---|---|
committer | Karel Zak | 2009-10-06 09:17:06 +0200 |
commit | 041a4ff1db7c3004644211377ac828e8a536da02 (patch) | |
tree | f4164398acd178ec945c5673bab7844a58c0f8c7 /shlibs | |
parent | libblkid: fix FAT super block definition (diff) | |
download | kernel-qcow2-util-linux-041a4ff1db7c3004644211377ac828e8a536da02.tar.gz kernel-qcow2-util-linux-041a4ff1db7c3004644211377ac828e8a536da02.tar.xz kernel-qcow2-util-linux-041a4ff1db7c3004644211377ac828e8a536da02.zip |
libblkid: fix buffer usage in FAT prober
The blkid_probe_get_buffer() function returns buffer that could be
overwritten in the next blkid_probe_get_buffer() call. It means that
we have to save FAT super block to the temporary buffer if we want to
call blkid_probe_get_buffer() for directory entries or fsinfo.
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs')
-rw-r--r-- | shlibs/blkid/src/superblocks/vfat.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/shlibs/blkid/src/superblocks/vfat.c b/shlibs/blkid/src/superblocks/vfat.c index 8343c65c8..c47addbe7 100644 --- a/shlibs/blkid/src/superblocks/vfat.c +++ b/shlibs/blkid/src/superblocks/vfat.c @@ -189,14 +189,14 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) struct vfat_super_block *vs; struct msdos_super_block *ms; struct vfat_dir_entry *dir; - const unsigned char *vol_label = 0, *tmp; + const unsigned char *vol_label = NULL, *tmp; unsigned char *vol_serno; int maxloop = 100; uint16_t sector_size, dir_entries, reserved; uint32_t sect_count, fat_size, dir_size, cluster_count, fat_length; uint32_t buf_size, start_data_sect, next, root_start, root_dir_entries; const char *version = NULL; - + unsigned char sb_buf[512], label_buf[11]; /* non-standard magic strings */ if (mag->len <= 2 && probe_fat_nomagic(pr, mag) != 0) @@ -241,6 +241,12 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) if (cluster_count > FAT32_MAX) return 1; + /* all basic checks pass -- save the superblock to avoid overwriting + * by the next blkid_probe_get_buffer() call */ + memcpy(sb_buf, vs, sizeof(sb_buf)); + ms = (struct msdos_super_block *) sb_buf; + vs = (struct vfat_super_block *) sb_buf; + if (ms->ms_fat_length) { /* the label may be an attribute in the root directory */ root_start = (reserved + fat_size) * sector_size; @@ -268,6 +274,7 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) unsigned char *buf; uint16_t fsinfo_sect; + /* Search the FAT32 root dir for the label attribute */ buf_size = vs->vs_cluster_size * sector_size; start_data_sect = reserved + fat_size; @@ -292,8 +299,12 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag) count = buf_size / sizeof(struct vfat_dir_entry); vol_label = search_fat_label(dir, count); - if (vol_label) + if (vol_label) { + /* save the root dir entry label */ + memcpy(label_buf, vol_label, sizeof(label_buf)); + vol_label = label_buf; break; + } /* get FAT entry */ fat_entry_off = (reserved * sector_size) + |