* FAILED: patch "[PATCH] erofs: fix the out-of-bounds nameoff handling for trailing" failed to apply to 5.10-stable tree
@ 2026-05-01 10:58 gregkh
2026-05-01 19:11 ` [PATCH 5.10.y] erofs: fix the out-of-bounds nameoff handling for trailing dirents Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2026-05-01 10:58 UTC (permalink / raw)
To: xiang, chao, danisjiang, hsiangkao, moonafterrain; +Cc: stable
The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x d18a3b5d337fa412a38e776e6b4b857a58836575
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026050132-spender-underfoot-6d7b@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d18a3b5d337fa412a38e776e6b4b857a58836575 Mon Sep 17 00:00:00 2001
From: Gao Xiang <xiang@kernel.org>
Date: Tue, 21 Apr 2026 15:59:52 +0800
Subject: [PATCH] erofs: fix the out-of-bounds nameoff handling for trailing
dirents
Currently we already have boundary-checks for nameoffs, but the trailing
dirents are special since the namelens are calculated with strnlen()
with unchecked nameoffs.
If a crafted EROFS has a trailing dirent with nameoff >= maxsize,
maxsize - nameoff can underflow, causing strnlen() to read past the
directory block.
nameoff0 should also be verified to be a multiple of
`sizeof(struct erofs_dirent)` as well [1].
[1] https://sashiko.dev/#/patchset/20260416063511.3173774-1-hsiangkao%40linux.alibaba.com
Fixes: 3aa8ec716e52 ("staging: erofs: add directory operations")
Fixes: 33bac912840f ("staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir()")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Reported-by: Junrui Luo <moonafterrain@outlook.com>
Closes: https://lore.kernel.org/r/A0FD7E0F-7558-49B0-8BC8-EB1ECDB2479A@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Chao Yu <chao@kernel.org>
diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c
index e5132575b9d3..4aa52a5f204a 100644
--- a/fs/erofs/dir.c
+++ b/fs/erofs/dir.c
@@ -19,20 +19,18 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
const char *de_name = (char *)dentry_blk + nameoff;
unsigned int de_namelen;
- /* the last dirent in the block? */
- if (de + 1 >= end)
- de_namelen = strnlen(de_name, maxsize - nameoff);
- else
+ /* non-trailing dirent in the directory block? */
+ if (de + 1 < end)
de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;
+ else if (maxsize <= nameoff)
+ goto err_bogus;
+ else
+ de_namelen = strnlen(de_name, maxsize - nameoff);
- /* a corrupted entry is found */
- if (nameoff + de_namelen > maxsize ||
- de_namelen > EROFS_NAME_LEN) {
- erofs_err(dir->i_sb, "bogus dirent @ nid %llu",
- EROFS_I(dir)->nid);
- DBG_BUGON(1);
- return -EFSCORRUPTED;
- }
+ /* a corrupted entry is found (including negative namelen) */
+ if (!in_range32(de_namelen, 1, EROFS_NAME_LEN) ||
+ nameoff + de_namelen > maxsize)
+ goto err_bogus;
if (!dir_emit(ctx, de_name, de_namelen,
erofs_nid_to_ino64(EROFS_SB(dir->i_sb),
@@ -42,6 +40,10 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
ctx->pos += sizeof(struct erofs_dirent);
}
return 0;
+err_bogus:
+ erofs_err(dir->i_sb, "bogus dirent @ nid %llu", EROFS_I(dir)->nid);
+ DBG_BUGON(1);
+ return -EFSCORRUPTED;
}
static int erofs_readdir(struct file *f, struct dir_context *ctx)
@@ -88,7 +90,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
}
nameoff = le16_to_cpu(de->nameoff);
- if (nameoff < sizeof(struct erofs_dirent) || nameoff >= bsz) {
+ if (!nameoff || nameoff >= bsz || (nameoff % sizeof(*de))) {
erofs_err(sb, "invalid de[0].nameoff %u @ nid %llu",
nameoff, EROFS_I(dir)->nid);
err = -EFSCORRUPTED;
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 5.10.y] erofs: fix the out-of-bounds nameoff handling for trailing dirents
2026-05-01 10:58 FAILED: patch "[PATCH] erofs: fix the out-of-bounds nameoff handling for trailing" failed to apply to 5.10-stable tree gregkh
@ 2026-05-01 19:11 ` Sasha Levin
2026-05-04 10:28 ` Gao Xiang
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2026-05-01 19:11 UTC (permalink / raw)
To: stable; +Cc: Gao Xiang, Yuhao Jiang, Junrui Luo, Chao Yu, Sasha Levin
From: Gao Xiang <hsiangkao@linux.alibaba.com>
[ Upstream commit d18a3b5d337fa412a38e776e6b4b857a58836575 ]
Currently we already have boundary-checks for nameoffs, but the trailing
dirents are special since the namelens are calculated with strnlen()
with unchecked nameoffs.
If a crafted EROFS has a trailing dirent with nameoff >= maxsize,
maxsize - nameoff can underflow, causing strnlen() to read past the
directory block.
nameoff0 should also be verified to be a multiple of
`sizeof(struct erofs_dirent)` as well [1].
[1] https://sashiko.dev/#/patchset/20260416063511.3173774-1-hsiangkao%40linux.alibaba.com
Fixes: 3aa8ec716e52 ("staging: erofs: add directory operations")
Fixes: 33bac912840f ("staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir()")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Reported-by: Junrui Luo <moonafterrain@outlook.com>
Closes: https://lore.kernel.org/r/A0FD7E0F-7558-49B0-8BC8-EB1ECDB2479A@outlook.com
Cc: stable@vger.kernel.org
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Chao Yu <chao@kernel.org>
[ replaced upstream `bsz` with `PAGE_SIZE` and `sizeof(*de)` with `sizeof(struct erofs_dirent)` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/dir.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c
index 2776bb832127d..79c83218e9560 100644
--- a/fs/erofs/dir.c
+++ b/fs/erofs/dir.c
@@ -38,20 +38,18 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
nameoff = le16_to_cpu(de->nameoff);
de_name = (char *)dentry_blk + nameoff;
- /* the last dirent in the block? */
- if (de + 1 >= end)
- de_namelen = strnlen(de_name, maxsize - nameoff);
- else
+ /* non-trailing dirent in the directory block? */
+ if (de + 1 < end)
de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;
+ else if (maxsize <= nameoff)
+ goto err_bogus;
+ else
+ de_namelen = strnlen(de_name, maxsize - nameoff);
- /* a corrupted entry is found */
- if (nameoff + de_namelen > maxsize ||
- de_namelen > EROFS_NAME_LEN) {
- erofs_err(dir->i_sb, "bogus dirent @ nid %llu",
- EROFS_I(dir)->nid);
- DBG_BUGON(1);
- return -EFSCORRUPTED;
- }
+ /* a corrupted entry is found (including negative namelen) */
+ if (!in_range32(de_namelen, 1, EROFS_NAME_LEN) ||
+ nameoff + de_namelen > maxsize)
+ goto err_bogus;
debug_one_dentry(d_type, de_name, de_namelen);
if (!dir_emit(ctx, de_name, de_namelen,
@@ -63,6 +61,10 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
}
*ofs = maxsize;
return 0;
+err_bogus:
+ erofs_err(dir->i_sb, "bogus dirent @ nid %llu", EROFS_I(dir)->nid);
+ DBG_BUGON(1);
+ return -EFSCORRUPTED;
}
static int erofs_readdir(struct file *f, struct dir_context *ctx)
@@ -96,8 +98,8 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
nameoff = le16_to_cpu(de->nameoff);
- if (nameoff < sizeof(struct erofs_dirent) ||
- nameoff >= PAGE_SIZE) {
+ if (!nameoff || nameoff >= PAGE_SIZE ||
+ (nameoff % sizeof(struct erofs_dirent))) {
erofs_err(dir->i_sb,
"invalid de[0].nameoff %u @ nid %llu",
nameoff, EROFS_I(dir)->nid);
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 5.10.y] erofs: fix the out-of-bounds nameoff handling for trailing dirents
2026-05-01 19:11 ` [PATCH 5.10.y] erofs: fix the out-of-bounds nameoff handling for trailing dirents Sasha Levin
@ 2026-05-04 10:28 ` Gao Xiang
0 siblings, 0 replies; 3+ messages in thread
From: Gao Xiang @ 2026-05-04 10:28 UTC (permalink / raw)
To: Sasha Levin, stable; +Cc: Yuhao Jiang, Junrui Luo, Chao Yu
On 2026/5/2 03:11, Sasha Levin wrote:
> From: Gao Xiang <hsiangkao@linux.alibaba.com>
>
> [ Upstream commit d18a3b5d337fa412a38e776e6b4b857a58836575 ]
>
> Currently we already have boundary-checks for nameoffs, but the trailing
> dirents are special since the namelens are calculated with strnlen()
> with unchecked nameoffs.
>
> If a crafted EROFS has a trailing dirent with nameoff >= maxsize,
> maxsize - nameoff can underflow, causing strnlen() to read past the
> directory block.
>
> nameoff0 should also be verified to be a multiple of
> `sizeof(struct erofs_dirent)` as well [1].
>
> [1] https://sashiko.dev/#/patchset/20260416063511.3173774-1-hsiangkao%40linux.alibaba.com
>
> Fixes: 3aa8ec716e52 ("staging: erofs: add directory operations")
> Fixes: 33bac912840f ("staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir()")
> Reported-by: Yuhao Jiang <danisjiang@gmail.com>
> Reported-by: Junrui Luo <moonafterrain@outlook.com>
> Closes: https://lore.kernel.org/r/A0FD7E0F-7558-49B0-8BC8-EB1ECDB2479A@outlook.com
> Cc: stable@vger.kernel.org
> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
> Reviewed-by: Chao Yu <chao@kernel.org>
> [ replaced upstream `bsz` with `PAGE_SIZE` and `sizeof(*de)` with `sizeof(struct erofs_dirent)` ]
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Looks good to me.
Thanks,
Gao Xiang
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-04 10:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-01 10:58 FAILED: patch "[PATCH] erofs: fix the out-of-bounds nameoff handling for trailing" failed to apply to 5.10-stable tree gregkh
2026-05-01 19:11 ` [PATCH 5.10.y] erofs: fix the out-of-bounds nameoff handling for trailing dirents Sasha Levin
2026-05-04 10:28 ` Gao Xiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox