From 243b6848a33a8fd40d8963df287bdc4b2f9ed722 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 28 Oct 2025 20:33:52 +0800 Subject: [PATCH 1/2] udf: Preserve link count of system files stable inclusion from stable-v4.19.278 commit ec852375bb9766b0c205fb95fb19b28319655644 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID33EV CVE: CVE-2023-53695 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ec852375bb9766b0c205fb95fb19b28319655644 -------------------------------- [ Upstream commit fc8033a34a3ca7d23353e645e6dde5d364ac5f12 ] System files in UDF filesystem have link count 0. To not confuse VFS we fudge the link count to be 1 when reading such inodes however we forget to restore the link count of 0 when writing such inodes. Fix that. CC: stable@vger.kernel.org Signed-off-by: Jan Kara Signed-off-by: Sasha Levin Conflicts: fs/udf/inode.c fs/udf/super.c fs/udf/udf_i.h [Context conflicts in fs/udf/inode.c due to missing commit 6a1d712b43811 ('udf: Fix BUG on corrupted inode'). Conflicts in fs/udf/super.c and fs/udf/udf_i.h caused by missing commit 6da42219d24fb ('udf: reduce leakage of blocks related to named streams').] Signed-off-by: Zhao Yipeng --- fs/udf/inode.c | 9 +++++++-- fs/udf/super.c | 1 + fs/udf/udf_i.h | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 11f104931254..698c369b9224 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1374,6 +1374,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) ret = -EIO; goto out; } + iinfo->i_hidden = hidden_inode; iinfo->i_unique = 0; iinfo->i_lenEAttr = 0; iinfo->i_lenExtents = 0; @@ -1681,8 +1682,12 @@ static int udf_update_inode(struct inode *inode, int do_sync) if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); - else - fe->fileLinkCount = cpu_to_le16(inode->i_nlink); + else { + if (iinfo->i_hidden) + fe->fileLinkCount = cpu_to_le16(0); + else + fe->fileLinkCount = cpu_to_le16(inode->i_nlink); + } fe->informationLength = cpu_to_le64(inode->i_size); diff --git a/fs/udf/super.c b/fs/udf/super.c index 699cda7f89f9..5c2d7a97df9a 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -154,6 +154,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb) ei->i_next_alloc_block = 0; ei->i_next_alloc_goal = 0; ei->i_strat4096 = 0; + ei->i_hidden = 0; init_rwsem(&ei->i_data_sem); ei->cached_extent.lstart = -1; spin_lock_init(&ei->i_extent_cache_lock); diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index 2ef0e212f08a..c6acbc7c1c85 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h @@ -42,7 +42,8 @@ struct udf_inode_info { unsigned i_efe : 1; /* extendedFileEntry */ unsigned i_use : 1; /* unallocSpaceEntry */ unsigned i_strat4096 : 1; - unsigned reserved : 26; + unsigned i_hidden : 1; /* hidden system inode */ + unsigned reserved : 25; union { struct short_ad *i_sad; struct long_ad *i_lad; -- Gitee From a487c1855e0f5a2307576aa73ed749ce32c60d18 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 28 Oct 2025 20:33:53 +0800 Subject: [PATCH 2/2] udf: Detect system inodes linked into directory hierarchy stable inclusion from stable-v4.19.278 commit 1dc71eeb198a8daa17d0c995998a53b0b749a158 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID33EV CVE: CVE-2023-53695 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1dc71eeb198a8daa17d0c995998a53b0b749a158 -------------------------------- [ Upstream commit 85a37983ec69cc9fcd188bc37c4de15ee326355a ] When UDF filesystem is corrupted, hidden system inodes can be linked into directory hierarchy which is an avenue for further serious corruption of the filesystem and kernel confusion as noticed by syzbot fuzzed images. Refuse to access system inodes linked into directory hierarchy and vice versa. CC: stable@vger.kernel.org Reported-by: syzbot+38695a20b8addcbc1084@syzkaller.appspotmail.com Signed-off-by: Jan Kara Signed-off-by: Sasha Levin Signed-off-by: Zhao Yipeng --- fs/udf/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 698c369b9224..48be49cffbc0 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1848,8 +1848,13 @@ struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino, if (!inode) return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) + if (!(inode->i_state & I_NEW)) { + if (UDF_I(inode)->i_hidden != hidden_inode) { + iput(inode); + return ERR_PTR(-EFSCORRUPTED); + } return inode; + } memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); err = udf_read_inode(inode, hidden_inode); -- Gitee