From: Darrick J. Wong <djwong@xxxxxxxxxx> Fix numerous problems in the function that reads data from an inlinedata file: - Reads starting after isize should be returned as short reads. - Reads past the end of the inline data should return zeroes. - Reads from the inline data buffer must not exceed isize. Cc: <linux-ext4@xxxxxxxxxxxxxxx> # v1.43 Fixes: 54e880b870f7fe ("libext2fs: handle inline data in read/write function") Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- lib/ext2fs/fileio.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/ext2fs/fileio.c b/lib/ext2fs/fileio.c index 818f7f05420029..900002c5295682 100644 --- a/lib/ext2fs/fileio.c +++ b/lib/ext2fs/fileio.c @@ -255,18 +255,26 @@ ext2fs_file_read_inline_data(ext2_file_t file, void *buf, unsigned int wanted, unsigned int *got) { ext2_filsys fs; - errcode_t retval; + errcode_t retval = 0; unsigned int count = 0; + uint64_t isize = EXT2_I_SIZE(&file->inode); size_t size; + if (file->pos >= isize) + goto out; + fs = file->fs; retval = ext2fs_inline_data_get(fs, file->ino, &file->inode, file->buf, &size); if (retval) return retval; - if (file->pos >= size) - goto out; + /* + * size is the number of bytes available for inline data storage, which + * means it can exceed isize. + */ + if (size > isize) + size = isize; count = size - file->pos; if (count > wanted) @@ -275,6 +283,14 @@ ext2fs_file_read_inline_data(ext2_file_t file, void *buf, file->pos += count; buf = (char *) buf + count; + /* zero-fill the rest of the buffer */ + wanted -= count; + if (wanted > 0) { + memset(buf, 0, wanted); + file->pos += wanted; + count += wanted; + } + out: if (got) *got = count;