Hello. As I mentioned in my previous e-mail there seems to be a
problem in how HFS manages file->offset. Similar problems seem to
affect other filesystems as well. The similar check is already done in
kern/file.c I extend it to check for offsets past the file too and
eliminate the check in filesystems. In some cases I keep the check
because same function is used internally in filesystem module too
--
Regards
Vladimir 'phcoder' Serbinenko
Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
diff --git a/fs/hfs.c b/fs/hfs.c
index 2f0702c..5062b5f 100644
--- a/fs/hfs.c
+++ b/fs/hfs.c
@@ -243,10 +243,6 @@ grub_hfs_read_file (struct grub_hfs_data *data,
int i;
int blockcnt;
- /* Adjust len so it we can't read past the end of the file. */
- if (len > grub_le_to_cpu32 (data->size))
- len = grub_le_to_cpu32 (data->size);
-
blockcnt = ((len + pos)
+ data->blksz - 1) / data->blksz;
diff --git a/fs/jfs.c b/fs/jfs.c
index 51ca91a..5172b02 100644
--- a/fs/jfs.c
+++ b/fs/jfs.c
@@ -545,8 +545,8 @@ grub_jfs_read_file (struct grub_jfs_data *data,
int blockcnt;
/* Adjust len so it we can't read past the end of the file. */
- if (len > data->currinode.size)
- len = data->currinode.size;
+ if (len + pos > data->currinode.size)
+ len = data->currinode.size - pos;
blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
/ grub_le_to_cpu32 (data->sblock.blksz));
diff --git a/fs/minix.c b/fs/minix.c
index 44218fb..08eb607 100644
--- a/fs/minix.c
+++ b/fs/minix.c
@@ -193,8 +193,8 @@ grub_minix_read_file (struct grub_minix_data *data,
int blockcnt;
/* Adjust len so it we can't read past the end of the file. */
- if (len > GRUB_MINIX_INODE_SIZE (data))
- len = GRUB_MINIX_INODE_SIZE (data);
+ if (len + pos > GRUB_MINIX_INODE_SIZE (data))
+ len = GRUB_MINIX_INODE_SIZE (data) - pos;
blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
diff --git a/fs/ntfs.c b/fs/ntfs.c
index d03a940..3ff487c 100644
--- a/fs/ntfs.c
+++ b/fs/ntfs.c
@@ -970,15 +970,6 @@ grub_ntfs_read (grub_file_t file, char *buf, grub_size_t
len)
if (file->read_hook)
mft->attr.save_pos = 1;
- if (file->offset > file->size)
- {
- grub_error (GRUB_ERR_BAD_FS, "Bad offset");
- return -1;
- }
-
- if (file->offset + len > file->size)
- len = file->size - file->offset;
-
read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook);
return (grub_errno) ? 0 : len;
}
diff --git a/fs/reiserfs.c b/fs/reiserfs.c
index 04d3315..fb4f1bc 100644
--- a/fs/reiserfs.c
+++ b/fs/reiserfs.c
@@ -1077,9 +1077,6 @@ grub_reiserfs_read (grub_file_t file, char *buf,
grub_size_t len)
grub_disk_addr_t block;
grub_off_t offset;
- if (file->offset >= file->size)
- return 0;
-
key.directory_id = node->header.key.directory_id;
key.object_id = node->header.key.object_id;
key.u.v2.offset_type = 0;
diff --git a/fs/ufs.c b/fs/ufs.c
index 797a45d..c94ad99 100644
--- a/fs/ufs.c
+++ b/fs/ufs.c
@@ -290,8 +290,8 @@ grub_ufs_read_file (struct grub_ufs_data *data,
int blockcnt;
/* Adjust len so it we can't read past the end of the file. */
- if (len > INODE_SIZE (data))
- len = INODE_SIZE (data);
+ if (len + pos > INODE_SIZE (data))
+ len = INODE_SIZE (data) - pos;
blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock);
diff --git a/kern/file.c b/kern/file.c
index 9b56b88..85092b8 100644
--- a/kern/file.c
+++ b/kern/file.c
@@ -112,6 +112,12 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t
len)
{
grub_ssize_t res;
+ if (file->offset > file->size)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "Bad offset");
+ return -1;
+ }
+
if (len == 0 || len > file->size - file->offset)
len = file->size - file->offset;
_______________________________________________
Grub-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel