* grub-core/fs/reiserfs.c (grub_reiserfs_iterate_dir): Put a trailing

zero after directory block since last entry may be not 0-terminated if
	it ends on block boundary. Use continue instead of if spanning whole
	loop.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-05-03 16:43:05 +02:00
parent a3a0eace51
commit 1516bfb43a
2 changed files with 173 additions and 165 deletions

View file

@ -1,3 +1,10 @@
2012-05-03 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/reiserfs.c (grub_reiserfs_iterate_dir): Put a trailing
zero after directory block since last entry may be not 0-terminated if
it ends on block boundary. Use continue instead of if spanning whole
loop.
2012-05-03 Vladimir Serbinenko <phcoder@gmail.com> 2012-05-03 Vladimir Serbinenko <phcoder@gmail.com>
Support 4K sectors UDF inline files. Support 4K sectors UDF inline files.

View file

@ -749,7 +749,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
goto fail; goto fail;
} }
block_size = grub_le_to_cpu16 (data->superblock.block_size); block_size = grub_le_to_cpu16 (data->superblock.block_size);
block_header = grub_malloc (block_size); block_header = grub_malloc (block_size + 1);
if (! block_header) if (! block_header)
goto fail; goto fail;
block_number = item->block_number; block_number = item->block_number;
@ -770,6 +770,8 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
if (grub_errno) if (grub_errno)
goto fail; goto fail;
((char *) block_header)[block_size] = 0;
#if 0 #if 0
if (grub_le_to_cpu16 (block_header->level) != 1) if (grub_le_to_cpu16 (block_header->level) != 1)
{ {
@ -793,181 +795,180 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
= &directory_headers[entry_number]; = &directory_headers[entry_number];
grub_uint16_t entry_state grub_uint16_t entry_state
= grub_le_to_cpu16 (directory_header->state); = grub_le_to_cpu16 (directory_header->state);
grub_fshelp_node_t entry_item;
struct grub_reiserfs_key entry_key;
enum grub_reiserfs_item_type entry_type;
char *entry_name;
if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK))
continue;
if (entry_state & GRUB_REISERFS_VISIBLE_MASK) entry_name = (((char *) directory_headers)
{ + grub_le_to_cpu16 (directory_header->location));
grub_fshelp_node_t entry_item; entry_key.directory_id = directory_header->directory_id;
struct grub_reiserfs_key entry_key; entry_key.object_id = directory_header->object_id;
enum grub_reiserfs_item_type entry_type; entry_key.u.v2.offset_type = 0;
char *entry_name; grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY,
2);
grub_reiserfs_set_key_offset (&entry_key, 1);
entry_name = (((char *) directory_headers) entry_item = grub_malloc (sizeof (*entry_item));
+ grub_le_to_cpu16 (directory_header->location)); if (! entry_item)
entry_key.directory_id = directory_header->directory_id; goto fail;
entry_key.object_id = directory_header->object_id;
entry_key.u.v2.offset_type = 0;
grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY,
2);
grub_reiserfs_set_key_offset (&entry_key, 1);
entry_item = grub_malloc (sizeof (*entry_item)); if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1)
if (! entry_item) != GRUB_ERR_NONE)
goto fail; {
grub_free (entry_item);
goto fail;
}
if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1) if (entry_item->type == GRUB_REISERFS_DIRECTORY)
!= GRUB_ERR_NONE) entry_type = GRUB_FSHELP_DIR;
{ else
grub_free (entry_item); {
goto fail; grub_uint32_t entry_block_number;
} /* Order is very important here.
First set the offset to 0 using current key version.
Then change the key type, which affects key version
detection. */
grub_reiserfs_set_key_offset (&entry_key, 0);
grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT,
2);
if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1)
!= GRUB_ERR_NONE)
{
grub_free (entry_item);
goto fail;
}
if (entry_item->type == GRUB_REISERFS_DIRECTORY) if (entry_item->block_number != 0)
entry_type = GRUB_FSHELP_DIR; {
else grub_uint16_t entry_version;
{ entry_version
grub_uint32_t entry_block_number; = grub_le_to_cpu16 (entry_item->header.version);
/* Order is very important here. entry_block_number = entry_item->block_number;
First set the offset to 0 using current key version. #if 0
Then change the key type, which affects key version grub_dprintf ("reiserfs",
detection. */ "version %04x block %08x (%08x) position %08x\n",
grub_reiserfs_set_key_offset (&entry_key, 0); entry_version, entry_block_number,
grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT, ((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
2); grub_le_to_cpu16 (entry_item->header.item_location));
if (grub_reiserfs_get_item (data, &entry_key, entry_item, 1) #endif
!= GRUB_ERR_NONE) if (entry_version == 0) /* Version 1 stat item. */
{ {
grub_free (entry_item); struct grub_reiserfs_stat_item_v1 entry_v1_stat;
goto fail; grub_disk_read (data->disk,
} entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
grub_le_to_cpu16 (entry_item->header.item_location),
if (entry_item->block_number != 0) sizeof (entry_v1_stat),
{ (char *) &entry_v1_stat);
grub_uint16_t entry_version; if (grub_errno)
entry_version goto fail;
= grub_le_to_cpu16 (entry_item->header.version);
entry_block_number = entry_item->block_number;
#if 0 #if 0
grub_dprintf ("reiserfs", grub_dprintf ("reiserfs",
"version %04x block %08x (%08x) position %08x\n", "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
entry_version, entry_block_number, grub_le_to_cpu16 (entry_v1_stat.mode),
((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE, grub_le_to_cpu16 (entry_v1_stat.hardlink_count),
grub_le_to_cpu16 (entry_item->header.item_location)); grub_le_to_cpu16 (entry_v1_stat.uid),
grub_le_to_cpu16 (entry_v1_stat.gid),
grub_le_to_cpu32 (entry_v1_stat.size),
grub_le_to_cpu32 (entry_v1_stat.atime),
grub_le_to_cpu32 (entry_v1_stat.mtime),
grub_le_to_cpu32 (entry_v1_stat.ctime),
grub_le_to_cpu32 (entry_v1_stat.rdev),
grub_le_to_cpu32 (entry_v1_stat.first_direct_byte));
grub_dprintf ("reiserfs",
"%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
entry_v1_stat.mode,
entry_v1_stat.hardlink_count,
entry_v1_stat.uid,
entry_v1_stat.gid,
entry_v1_stat.size,
entry_v1_stat.atime,
entry_v1_stat.mtime,
entry_v1_stat.ctime,
entry_v1_stat.rdev,
entry_v1_stat.first_direct_byte);
#endif #endif
if (entry_version == 0) /* Version 1 stat item. */ entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime);
{ if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
struct grub_reiserfs_stat_item_v1 entry_v1_stat; == S_IFLNK)
grub_disk_read (data->disk, entry_type = GRUB_FSHELP_SYMLINK;
entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS), else
grub_le_to_cpu16 (entry_item->header.item_location), entry_type = GRUB_FSHELP_REG;
sizeof (entry_v1_stat), }
(char *) &entry_v1_stat); else
if (grub_errno) {
goto fail; struct grub_reiserfs_stat_item_v2 entry_v2_stat;
grub_disk_read (data->disk,
entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
grub_le_to_cpu16 (entry_item->header.item_location),
sizeof (entry_v2_stat),
(char *) &entry_v2_stat);
if (grub_errno)
goto fail;
#if 0 #if 0
grub_dprintf ("reiserfs", grub_dprintf ("reiserfs",
"%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n", "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
grub_le_to_cpu16 (entry_v1_stat.mode), grub_le_to_cpu16 (entry_v2_stat.mode),
grub_le_to_cpu16 (entry_v1_stat.hardlink_count), grub_le_to_cpu16 (entry_v2_stat.reserved),
grub_le_to_cpu16 (entry_v1_stat.uid), grub_le_to_cpu32 (entry_v2_stat.hardlink_count),
grub_le_to_cpu16 (entry_v1_stat.gid), (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32),
grub_le_to_cpu32 (entry_v1_stat.size), (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF),
grub_le_to_cpu32 (entry_v1_stat.atime), grub_le_to_cpu32 (entry_v2_stat.uid),
grub_le_to_cpu32 (entry_v1_stat.mtime), grub_le_to_cpu32 (entry_v2_stat.gid),
grub_le_to_cpu32 (entry_v1_stat.ctime), grub_le_to_cpu32 (entry_v2_stat.atime),
grub_le_to_cpu32 (entry_v1_stat.rdev), grub_le_to_cpu32 (entry_v2_stat.mtime),
grub_le_to_cpu32 (entry_v1_stat.first_direct_byte)); grub_le_to_cpu32 (entry_v2_stat.ctime),
grub_dprintf ("reiserfs", grub_le_to_cpu32 (entry_v2_stat.blocks),
"%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n", grub_le_to_cpu32 (entry_v2_stat.first_direct_byte));
entry_v1_stat.mode, grub_dprintf ("reiserfs",
entry_v1_stat.hardlink_count, "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
entry_v1_stat.uid, entry_v2_stat.mode,
entry_v1_stat.gid, entry_v2_stat.reserved,
entry_v1_stat.size, entry_v2_stat.hardlink_count,
entry_v1_stat.atime, (unsigned int) (entry_v2_stat.size >> 32),
entry_v1_stat.mtime, (unsigned int) (entry_v2_stat.size && 0xFFFFFFFF),
entry_v1_stat.ctime, entry_v2_stat.uid,
entry_v1_stat.rdev, entry_v2_stat.gid,
entry_v1_stat.first_direct_byte); entry_v2_stat.atime,
entry_v2_stat.mtime,
entry_v2_stat.ctime,
entry_v2_stat.blocks,
entry_v2_stat.first_direct_byte);
#endif #endif
entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime); entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime);
if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK) if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
== S_IFLNK) == S_IFLNK)
entry_type = GRUB_FSHELP_SYMLINK; entry_type = GRUB_FSHELP_SYMLINK;
else else
entry_type = GRUB_FSHELP_REG; entry_type = GRUB_FSHELP_REG;
} }
else }
{ else
struct grub_reiserfs_stat_item_v2 entry_v2_stat; {
grub_disk_read (data->disk, /* Pseudo file ".." never has stat block. */
entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS), if (grub_strcmp (entry_name, ".."))
grub_le_to_cpu16 (entry_item->header.item_location), grub_dprintf ("reiserfs",
sizeof (entry_v2_stat), "Warning : %s has no stat block !\n",
(char *) &entry_v2_stat); entry_name);
if (grub_errno) grub_free (entry_item);
goto fail; goto next;
#if 0 }
grub_dprintf ("reiserfs", }
"%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n", if (hook (entry_name, entry_type, entry_item))
grub_le_to_cpu16 (entry_v2_stat.mode), {
grub_le_to_cpu16 (entry_v2_stat.reserved), grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
grub_le_to_cpu32 (entry_v2_stat.hardlink_count), entry_name, entry_type);
(unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32), ret = 1;
(unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF), goto found;
grub_le_to_cpu32 (entry_v2_stat.uid), }
grub_le_to_cpu32 (entry_v2_stat.gid),
grub_le_to_cpu32 (entry_v2_stat.atime),
grub_le_to_cpu32 (entry_v2_stat.mtime),
grub_le_to_cpu32 (entry_v2_stat.ctime),
grub_le_to_cpu32 (entry_v2_stat.blocks),
grub_le_to_cpu32 (entry_v2_stat.first_direct_byte));
grub_dprintf ("reiserfs",
"%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
entry_v2_stat.mode,
entry_v2_stat.reserved,
entry_v2_stat.hardlink_count,
(unsigned int) (entry_v2_stat.size >> 32),
(unsigned int) (entry_v2_stat.size && 0xFFFFFFFF),
entry_v2_stat.uid,
entry_v2_stat.gid,
entry_v2_stat.atime,
entry_v2_stat.mtime,
entry_v2_stat.ctime,
entry_v2_stat.blocks,
entry_v2_stat.first_direct_byte);
#endif
entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime);
if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
== S_IFLNK)
entry_type = GRUB_FSHELP_SYMLINK;
else
entry_type = GRUB_FSHELP_REG;
}
}
else
{
/* Pseudo file ".." never has stat block. */
if (grub_strcmp (entry_name, ".."))
grub_dprintf ("reiserfs",
"Warning : %s has no stat block !\n",
entry_name);
grub_free (entry_item);
goto next;
}
}
if (hook (entry_name, entry_type, entry_item))
{
grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
entry_name, entry_type);
ret = 1;
goto found;
}
next: next:
*entry_name = 0; /* Make sure next entry name (which is just *entry_name = 0; /* Make sure next entry name (which is just
before this one in disk order) stops before before this one in disk order) stops before
the current one. */ the current one. */
}
} }
if (next_offset == 0) if (next_offset == 0)