From: Jan Kara jack@suse.cz
mainline inclusion from mainline-v6.9-rc1 commit 8208c41c43ad5e9b63dce6c45a73e326109ca658 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAD03M CVE: CVE-2024-40972
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
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 Conflicts: fs/ext4/xattr.c [context differences] Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- send-patches.sh | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/xattr.c | 49 +++++++++++++------------ 2 files changed, 120 insertions(+), 25 deletions(-) create mode 100644 send-patches.sh
diff --git a/send-patches.sh b/send-patches.sh new file mode 100644 index 000000000000..aee16d7adc2c --- /dev/null +++ b/send-patches.sh @@ -0,0 +1,96 @@ +patchwork=(patchwork@huawei.com) +me=(qiaoyifan4@huawei.com) +pl=(yangerkun@huawei.com) +se=( + yi.zhang@huawei.com + houtao1@huawei.com +) +group=( + chengzhihao1@huawei.com + qiaoyifan4@huawei.com +) +release=( + 'me qiaoyifan4@huawei.com' + 'hulk-4.19 liuyongqiang13@huawei.com kernel@openeuler.org' + 'hulk-4.1 gongruiqi1@huawei.com xiangyang3@huawei.com' + 'hulk-4.4 zhengyejian1@huawei.com' + 'hulk-5.10-next chenjun102@huawei.com' + 'hulk-5.10 wanghai38@huawei.com' + 'rh7.2 tongtiangen@huawei.com' + 'rh7.3 wanghai38@huawei.com' + 'rh7.5 yebin10@huawei.com' + 'rh8.1 zhangchangzhong@huawei.com' + 'hulk-3.10 xiujianfeng@huawei.com' + 'OLK-5.10 zhangjialin11@huawei.com kernel@openeuler.org' + 'OLK-6.6 zhengzengkai@huawei.com kernel@openeuler.org' + 'next miaoxie@huawei.com weiyongjun1@huawei.com guohanjun@huawei.com huawei.libin@huawei.com yuehaibing@huawei.com johnny.chenyi@huawei.com' + 'SP1 zhangjialin11@huawei.com kernel@openeuler.org' +) + +usage() +{ + echo "----- send patch or patchset ------" + echo "$0 release_versionxxx -p patch/-d patchset dir" + echo "availiable release:" + for r in "${release[@]}"; do + echo " $r" + done +} + +if [ $# != 3 ]; then + echo "wrong input" + usage + exit 1 +fi + +# which release to send +for r in "${release[@]}"; do + tmp=($r) + i=0 + for t in ${tmp[@]}; do + if [ $i -eq 0 ]; then + if [ $1 == $t ]; then + echo "will send to $r" + let i++ + else + break + fi + elif [ $i -eq 1 ]; then + cmd="$cmd-to $t" + let i++ + else + cmd="$cmd -to $t" + fi + done + if [ $i -ne 0 ]; then + break + fi +done + +# always cc me pl and se +cmd="$cmd -cc $me -cc $pl" +for j in ${se[@]}; do + cmd="$cmd -cc $j" +done + +# if send to patchwork +if [ $1 != me ]; then + cmd="$cmd -to $patchwork" + for g in ${group[@]}; do + cmd="$cmd -cc $g" + done +fi + +cmd="$cmd --suppress-cc=all" +# -p : xxx.patch +# -d : xxx/*.patch +if [ $2 == "-p" ]; then + cmd="git send-email $cmd $3" +elif [ $2 == "-d" ]; then + cmd="git send-email $cmd $3/*.patch" +else + echo "unknow patch" +fi + +echo "$cmd" +$cmd diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b2483b3b382e..2185a37070ff 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1508,45 +1508,49 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, /* * Add value of the EA in an inode. */ -static int ext4_xattr_inode_lookup_create(handle_t *handle, struct inode *inode, - const void *value, size_t value_len, - struct inode **ret_inode) +static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle, + struct inode *inode, const void *value, size_t value_len) { struct inode *ea_inode; u32 hash; int err;
+ /* Account inode & space to quota even if sharing... */ + err = ext4_xattr_inode_alloc_quota(inode, value_len); + if (err) + return ERR_PTR(err); + hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len); ea_inode = ext4_xattr_inode_cache_find(inode, value, value_len, hash); if (ea_inode) { err = ext4_xattr_inode_inc_ref(handle, ea_inode); - if (err) { - iput(ea_inode); - return err; - } - - *ret_inode = ea_inode; - return 0; + if (err) + goto out_err; + return ea_inode; }
/* Create an inode for the EA value */ ea_inode = ext4_xattr_inode_create(handle, inode, hash); - if (IS_ERR(ea_inode)) - return PTR_ERR(ea_inode); + if (IS_ERR(ea_inode)) { + ext4_xattr_inode_free_quota(inode, NULL, value_len); + return ea_inode; + }
err = ext4_xattr_inode_write(handle, ea_inode, value, value_len); if (err) { ext4_xattr_inode_dec_ref(handle, ea_inode); - iput(ea_inode); - return err; + goto out_err; }
if (EA_INODE_CACHE(inode)) mb_cache_entry_create(EA_INODE_CACHE(inode), GFP_NOFS, hash, ea_inode->i_ino, true /* reusable */);
- *ret_inode = ea_inode; - return 0; + return ea_inode; +out_err: + iput(ea_inode); + ext4_xattr_inode_free_quota(inode, NULL, value_len); + return ERR_PTR(err); }
/* @@ -1654,16 +1658,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, if (i->value && in_inode) { WARN_ON_ONCE(!i->value_len);
- ret = ext4_xattr_inode_alloc_quota(inode, i->value_len); - if (ret) - goto out; - - ret = ext4_xattr_inode_lookup_create(handle, inode, i->value, - i->value_len, - &new_ea_inode); - if (ret) { + new_ea_inode = ext4_xattr_inode_lookup_create(handle, inode, + i->value, i->value_len); + if (IS_ERR(new_ea_inode)) { + ret = PTR_ERR(new_ea_inode); new_ea_inode = NULL; - ext4_xattr_inode_free_quota(inode, NULL, i->value_len); goto out; } }