|
@@ -1560,7 +1560,7 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
|
|
|
handle_t *handle, struct inode *inode,
|
|
|
bool is_block)
|
|
|
{
|
|
|
- struct ext4_xattr_entry *last;
|
|
|
+ struct ext4_xattr_entry *last, *next;
|
|
|
struct ext4_xattr_entry *here = s->here;
|
|
|
size_t min_offs = s->end - s->base, name_len = strlen(i->name);
|
|
|
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. */
|
|
|
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) {
|
|
|
size_t offs = le16_to_cpu(last->e_value_offs);
|
|
|
if (offs < min_offs)
|