Actually maximum length of a valid entry value is not ->s_blocksize because header, last entry and entry name will also occupy some spaces. This patch strengthens the value length check and return -ERANGE when the length is larger than allowed maximum length. Signed-off-by: Chengguang Xu <cgxu519@xxxxxxxxxxx> --- fs/ext2/xattr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index f1f857b83b45..425c8e29d3cb 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -399,7 +399,7 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, struct buffer_head *bh = NULL; struct ext2_xattr_header *header = NULL; struct ext2_xattr_entry *here, *last; - size_t name_len, free, min_offs = sb->s_blocksize; + size_t name_len, free, min_offs = sb->s_blocksize, max_len; int not_found = 1, error; char *end; @@ -423,7 +423,10 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, if (name == NULL) return -EINVAL; name_len = strlen(name); - if (name_len > 255 || value_len > sb->s_blocksize) + max_len = sb->s_blocksize - sizeof(struct ext2_xattr_header) + - sizeof(__u32); + if (name_len > 255 || + EXT2_XATTR_LEN(name_len) + EXT2_XATTR_SIZE(value_len) > max_len) return -ERANGE; down_write(&EXT2_I(inode)->xattr_sem); if (EXT2_I(inode)->i_file_acl) { -- 2.20.1