From: Lukas Czerner lczerner@redhat.com
mainline inclusion from mainline-v6.0-rc1 commit 65f8ea4cd57dbd46ea13b41dc8bac03176b04233 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I58WSQ CVE: CVE-2022-1184
--------------------------------
Currently ext4 directory handling code implicitly assumes that the directory blocks are always within the i_size. In fact ext4_append() will attempt to allocate next directory block based solely on i_size and the i_size is then appropriately increased after a successful allocation.
However, for this to work it requires i_size to be correct. If, for any reason, the directory inode i_size is corrupted in a way that the directory tree refers to a valid directory block past i_size, we could end up corrupting parts of the directory tree structure by overwriting already used directory blocks when modifying the directory.
Fix it by catching the corruption early in __ext4_read_dirblock().
Addresses Red-Hat-Bugzilla: #2070205 CVE: CVE-2022-1184 Signed-off-by: Lukas Czerner lczerner@redhat.com Cc: stable@vger.kernel.org Reviewed-by: Andreas Dilger adilger@dilger.ca Link: https://lore.kernel.org/r/20220704142721.157985-1-lczerner@redhat.com Signed-off-by: Theodore Ts'o tytso@mit.edu
Conflicts: fs/ext4/namei.c
Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- fs/ext4/namei.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index b2d4fb82e8f4..1a9eda144c7a 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -124,6 +124,13 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, struct ext4_dir_entry *dirent; int is_dx_block = 0;
+ if (block >= inode->i_size) { + ext4_error_inode(inode, func, line, block, + "Attempting to read directory block (%u) that is past i_size (%llu)", + block, inode->i_size); + return ERR_PTR(-EFSCORRUPTED); + } + bh = ext4_bread(NULL, inode, block, 0); if (IS_ERR(bh)) { __ext4_warning(inode->i_sb, func, line,
From: Jan Kara jack@suse.cz
mainline inclusion from mainline-v6.1-rc1 commit 61a1d87a324ad5e3ed27c6699dfc93218fcf3201 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I58WSQ CVE: CVE-2022-1184
--------------------------------
The check in __ext4_read_dirblock() for block being outside of directory size was wrong because it compared block number against directory size in bytes. Fix it.
Fixes: 65f8ea4cd57d ("ext4: check if directory block is within i_size") CVE: CVE-2022-1184 CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Lukas Czerner lczerner@redhat.com Link: https://lore.kernel.org/r/20220822114832.1482-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- fs/ext4/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 1a9eda144c7a..72160354496d 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -124,7 +124,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, struct ext4_dir_entry *dirent; int is_dx_block = 0;
- if (block >= inode->i_size) { + if (block >= inode->i_size >> inode->i_blkbits) { ext4_error_inode(inode, func, line, block, "Attempting to read directory block (%u) that is past i_size (%llu)", block, inode->i_size);
From: David Leadbeater dgl@dgl.cx
stable inclusion from stable-v4.19.258 commit 3275f7804f40de3c578d2253232349b07c25f146 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5OWZ7 CVE: CVE-2022-2663
---------------------------
[ Upstream commit 0efe125cfb99e6773a7434f3463f7c2fa28f3a43 ]
Ensure the match happens in the right direction, previously the destination used was the server, not the NAT host, as the comment shows the code intended.
Additionally nf_nat_irc uses port 0 as a signal and there's no valid way it can appear in a DCC message, so consider port 0 also forged.
Fixes: 869f37d8e48f ("[NETFILTER]: nf_conntrack/nf_nat: add IRC helper port") Signed-off-by: David Leadbeater dgl@dgl.cx Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Liu Jian liujian56@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Reviewed-by: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- net/netfilter/nf_conntrack_irc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 819fc0df233f..23ead02c6aa5 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c @@ -209,8 +209,9 @@ static int help(struct sk_buff *skb, unsigned int protoff,
/* dcc_ip can be the internal OR external (NAT'ed) IP */ tuple = &ct->tuplehash[dir].tuple; - if (tuple->src.u3.ip != dcc_ip && - tuple->dst.u3.ip != dcc_ip) { + if ((tuple->src.u3.ip != dcc_ip && + ct->tuplehash[!dir].tuple.dst.u3.ip != dcc_ip) || + dcc_port == 0) { net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n", &tuple->src.u3.ip, &dcc_ip, dcc_port);