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;