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

Commit 81228268 authored by Randall Huang's avatar Randall Huang Committed by Jaegeuk Kim
Browse files

f2fs: fix to avoid memory leakage in f2fs_listxattr



In f2fs_listxattr, there is no boundary check before
memcpy e_name to buffer.
If the e_name_len is corrupted,
unexpected memory contents may be returned to the buffer.

Signed-off-by: default avatarRandall Huang <huangrandall@google.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 8ab6cfa6
Loading
Loading
Loading
Loading
+13 −1
Original line number Original line Diff line number Diff line
@@ -539,8 +539,9 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name,
ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
{
{
	struct inode *inode = d_inode(dentry);
	struct inode *inode = d_inode(dentry);
	nid_t xnid = F2FS_I(inode)->i_xattr_nid;
	struct f2fs_xattr_entry *entry;
	struct f2fs_xattr_entry *entry;
	void *base_addr;
	void *base_addr, *last_base_addr;
	int error = 0;
	int error = 0;
	size_t rest = buffer_size;
	size_t rest = buffer_size;


@@ -550,6 +551,8 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
	if (error)
	if (error)
		return error;
		return error;


	last_base_addr = (void *)base_addr + XATTR_SIZE(xnid, inode);

	list_for_each_xattr(entry, base_addr) {
	list_for_each_xattr(entry, base_addr) {
		const struct xattr_handler *handler =
		const struct xattr_handler *handler =
			f2fs_xattr_handler(entry->e_name_index);
			f2fs_xattr_handler(entry->e_name_index);
@@ -557,6 +560,15 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
		size_t prefix_len;
		size_t prefix_len;
		size_t size;
		size_t size;


		if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
			(void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
			f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
						inode->i_ino);
			set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
			error = -EFSCORRUPTED;
			goto cleanup;
		}

		if (!handler || (handler->list && !handler->list(dentry)))
		if (!handler || (handler->list && !handler->list(dentry)))
			continue;
			continue;