
Offering: HULK HULK inclusion category: feature bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QTE -------------------------------- The community reported a `BUG_ON` caused by a roughly raw disk write that failed to retrieve the xattr in inode. Although this is not a real file system error, we can add some checks to intercept such errors. Here, we have restored the check paths that were removed in the mainline commit 5701875f9609, to enhance the robustness of the code. Signed-off-by: Yongjian Sun <sunyongjian1@huawei.com> --- fs/ext4/xattr.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 68619adb7792..b44726015c21 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -647,6 +647,9 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name, raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); end = ITAIL(inode, raw_inode); + error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; entry = IFIRST(header); error = xattr_find_entry(inode, &entry, end, name_index, name, 0); if (error) @@ -777,6 +780,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size) struct ext4_xattr_ibody_header *header; struct ext4_inode *raw_inode; struct ext4_iloc iloc; + void *end; int error; if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR)) @@ -786,9 +790,14 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size) return error; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); + end = ITAIL(inode, raw_inode); + error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; error = ext4_xattr_list_entries(dentry, IFIRST(header), buffer, buffer_size); +cleanup: brelse(iloc.bh); return error; } @@ -856,6 +865,7 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) struct ext4_xattr_ibody_header *header; struct ext4_xattr_entry *entry; qsize_t ea_inode_refs = 0; + void *end; int ret; lockdep_assert_held_read(&EXT4_I(inode)->xattr_sem); @@ -866,6 +876,10 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) goto out; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); + end = ITAIL(inode, raw_inode); + ret = xattr_check_inode(inode, header, end); + if (ret) + goto out; for (entry = IFIRST(header); !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) @@ -2215,6 +2229,9 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i, is->s.here = is->s.first; is->s.end = ITAIL(inode, raw_inode); if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { + error = xattr_check_inode(inode, header, is->s.end); + if (error) + return error; /* Find the named attribute. */ error = xattr_find_entry(inode, &is->s.here, is->s.end, i->name_index, i->name, 0); @@ -2765,6 +2782,10 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, min_offs = end - base; total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32); + error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; + ifree = ext4_xattr_free_space(base, &min_offs, base, &total_ino); if (ifree >= isize_diff) goto shift; -- 2.39.2