Commit 5369a762 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

ext4: add corruption check in ext4_xattr_set_entry()

In theory this should have been caught earlier when the xattr list was
verified, but in case it got missed, it's simple enough to add check
to make sure we don't overrun the xattr buffer.

This addresses CVE-2018-10879.

https://bugzilla.kernel.org/show_bug.cgi?id=200001



Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Reviewed-by: default avatarAndreas Dilger <adilger@dilger.ca>
Cc: stable@kernel.org
parent 327eaf73
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -1560,7 +1560,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
				handle_t *handle, struct inode *inode,
				handle_t *handle, struct inode *inode,
				bool is_block)
				bool is_block)
{
{
	struct ext4_xattr_entry *last;
	struct ext4_xattr_entry *last, *next;
	struct ext4_xattr_entry *here = s->here;
	struct ext4_xattr_entry *here = s->here;
	size_t min_offs = s->end - s->base, name_len = strlen(i->name);
	size_t min_offs = s->end - s->base, name_len = strlen(i->name);
	int in_inode = i->in_inode;
	int in_inode = i->in_inode;
@@ -1595,7 +1595,13 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,


	/* Compute min_offs and last. */
	/* Compute min_offs and last. */
	last = s->first;
	last = s->first;
	for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
	for (; !IS_LAST_ENTRY(last); last = next) {
		next = EXT4_XATTR_NEXT(last);
		if ((void *)next >= s->end) {
			EXT4_ERROR_INODE(inode, "corrupted xattr entries");
			ret = -EFSCORRUPTED;
			goto out;
		}
		if (!last->e_value_inum && last->e_value_size) {
		if (!last->e_value_inum && last->e_value_size) {
			size_t offs = le16_to_cpu(last->e_value_offs);
			size_t offs = le16_to_cpu(last->e_value_offs);
			if (offs < min_offs)
			if (offs < min_offs)