Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90966693 authored by Tahsin Erdogan's avatar Tahsin Erdogan Committed by Theodore Ts'o
Browse files

ext4: clean up ext4_xattr_inode_get()



The input and output values of *size parameter are equal on successful
return from ext4_xattr_inode_get().  On error return, the callers ignore
the output value so there is no need to update it.

Also check for NULL return from ext4_bread().  If the actual xattr inode
size happens to be smaller than the expected size, ext4_bread() may
return NULL which would indicate data corruption.

Signed-off-by: default avatarTahsin Erdogan <tahsin@google.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent bab79b04
Loading
Loading
Loading
Loading
+13 −22
Original line number Original line Diff line number Diff line
@@ -278,37 +278,28 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
/*
/*
 * Read the EA value from an inode.
 * Read the EA value from an inode.
 */
 */
static int
static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size)
{
{
	unsigned long block = 0;
	unsigned long block = 0;
	struct buffer_head *bh = NULL;
	struct buffer_head *bh = NULL;
	int blocksize;
	int blocksize = ea_inode->i_sb->s_blocksize;
	size_t csize, ret_size = 0;
	size_t csize, copied = 0;

	if (*size == 0)
		return 0;


	blocksize = ea_inode->i_sb->s_blocksize;
	while (copied < size) {

		csize = (size - copied) > blocksize ? blocksize : size - copied;
	while (ret_size < *size) {
		csize = (*size - ret_size) > blocksize ? blocksize :
							*size - ret_size;
		bh = ext4_bread(NULL, ea_inode, block, 0);
		bh = ext4_bread(NULL, ea_inode, block, 0);
		if (IS_ERR(bh)) {
		if (IS_ERR(bh))
			*size = ret_size;
			return PTR_ERR(bh);
			return PTR_ERR(bh);
		}
		if (!bh)
			return -EFSCORRUPTED;

		memcpy(buf, bh->b_data, csize);
		memcpy(buf, bh->b_data, csize);
		brelse(bh);
		brelse(bh);


		buf += csize;
		buf += csize;
		block += 1;
		block += 1;
		ret_size += csize;
		copied += csize;
	}
	}

	*size = ret_size;

	return 0;
	return 0;
}
}


@@ -360,7 +351,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
 */
 */
static int
static int
ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer,
ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer,
		     size_t *size)
		     size_t size)
{
{
	struct inode *ea_inode;
	struct inode *ea_inode;
	int ret;
	int ret;
@@ -417,7 +408,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
		if (entry->e_value_inum) {
		if (entry->e_value_inum) {
			error = ext4_xattr_inode_get(inode,
			error = ext4_xattr_inode_get(inode,
					     le32_to_cpu(entry->e_value_inum),
					     le32_to_cpu(entry->e_value_inum),
					     buffer, &size);
					     buffer, size);
			if (error)
			if (error)
				goto cleanup;
				goto cleanup;
		} else {
		} else {
@@ -467,7 +458,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
		if (entry->e_value_inum) {
		if (entry->e_value_inum) {
			error = ext4_xattr_inode_get(inode,
			error = ext4_xattr_inode_get(inode,
					     le32_to_cpu(entry->e_value_inum),
					     le32_to_cpu(entry->e_value_inum),
					     buffer, &size);
					     buffer, size);
			if (error)
			if (error)
				goto cleanup;
				goto cleanup;
		} else {
		} else {