Skip to content

Commit f41753f

Browse files
committed
ext4: fold quota accounting into ext4_xattr_inode_lookup_create()
JIRA: https://issues.redhat.com/browse/RHEL-48282 Tested: With xfstests CVE: CVE-2024-40972 When allocating EA inode, quota accounting is done just before ext4_xattr_inode_lookup_create(). Logically these two operations belong together so just fold quota accounting into ext4_xattr_inode_lookup_create(). We also make ext4_xattr_inode_lookup_create() return the looked up / created inode to convert the function to a more standard calling convention. Signed-off-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20240209112107.10585-1-jack@suse.cz Signed-off-by: Theodore Ts'o <tytso@mit.edu> (cherry picked from commit 8208c41) Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
1 parent 8dd1ed2 commit f41753f

File tree

1 file changed

+24
-26
lines changed

1 file changed

+24
-26
lines changed

fs/ext4/xattr.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,46 +1566,49 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value,
15661566
/*
15671567
* Add value of the EA in an inode.
15681568
*/
1569-
static int ext4_xattr_inode_lookup_create(handle_t *handle, struct inode *inode,
1570-
const void *value, size_t value_len,
1571-
struct inode **ret_inode)
1569+
static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle,
1570+
struct inode *inode, const void *value, size_t value_len)
15721571
{
15731572
struct inode *ea_inode;
15741573
u32 hash;
15751574
int err;
15761575

1576+
/* Account inode & space to quota even if sharing... */
1577+
err = ext4_xattr_inode_alloc_quota(inode, value_len);
1578+
if (err)
1579+
return ERR_PTR(err);
1580+
15771581
hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len);
15781582
ea_inode = ext4_xattr_inode_cache_find(inode, value, value_len, hash);
15791583
if (ea_inode) {
15801584
err = ext4_xattr_inode_inc_ref(handle, ea_inode);
1581-
if (err) {
1582-
iput(ea_inode);
1583-
return err;
1584-
}
1585-
1586-
*ret_inode = ea_inode;
1587-
return 0;
1585+
if (err)
1586+
goto out_err;
1587+
return ea_inode;
15881588
}
15891589

15901590
/* Create an inode for the EA value */
15911591
ea_inode = ext4_xattr_inode_create(handle, inode, hash);
1592-
if (IS_ERR(ea_inode))
1593-
return PTR_ERR(ea_inode);
1592+
if (IS_ERR(ea_inode)) {
1593+
ext4_xattr_inode_free_quota(inode, NULL, value_len);
1594+
return ea_inode;
1595+
}
15941596

15951597
err = ext4_xattr_inode_write(handle, ea_inode, value, value_len);
15961598
if (err) {
15971599
if (ext4_xattr_inode_dec_ref(handle, ea_inode))
15981600
ext4_warning_inode(ea_inode, "cleanup dec ref error %d", err);
1599-
iput(ea_inode);
1600-
return err;
1601+
goto out_err;
16011602
}
16021603

16031604
if (EA_INODE_CACHE(inode))
16041605
mb_cache_entry_create(EA_INODE_CACHE(inode), GFP_NOFS, hash,
16051606
ea_inode->i_ino, true /* reusable */);
1606-
1607-
*ret_inode = ea_inode;
1608-
return 0;
1607+
return ea_inode;
1608+
out_err:
1609+
iput(ea_inode);
1610+
ext4_xattr_inode_free_quota(inode, NULL, value_len);
1611+
return ERR_PTR(err);
16091612
}
16101613

16111614
/*
@@ -1713,16 +1716,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
17131716
if (i->value && in_inode) {
17141717
WARN_ON_ONCE(!i->value_len);
17151718

1716-
ret = ext4_xattr_inode_alloc_quota(inode, i->value_len);
1717-
if (ret)
1718-
goto out;
1719-
1720-
ret = ext4_xattr_inode_lookup_create(handle, inode, i->value,
1721-
i->value_len,
1722-
&new_ea_inode);
1723-
if (ret) {
1719+
new_ea_inode = ext4_xattr_inode_lookup_create(handle, inode,
1720+
i->value, i->value_len);
1721+
if (IS_ERR(new_ea_inode)) {
1722+
ret = PTR_ERR(new_ea_inode);
17241723
new_ea_inode = NULL;
1725-
ext4_xattr_inode_free_quota(inode, NULL, i->value_len);
17261724
goto out;
17271725
}
17281726
}

0 commit comments

Comments
 (0)