Patrick Williams | 520786c | 2023-06-25 16:20:36 -0500 | [diff] [blame] | 1 | From 6cebfbb79b1d5d8feb48801e1008eea5bfa8b599 Mon Sep 17 00:00:00 2001 |
| 2 | From: Gao Xiang <hsiangkao@linux.alibaba.com> |
| 3 | Date: Fri, 2 Jun 2023 13:52:56 +0800 |
| 4 | Subject: [PATCH 2/2] erofs-utils: fsck: block insane long paths when |
| 5 | extracting images |
| 6 | |
| 7 | Since some crafted EROFS filesystem images could have insane deep |
| 8 | hierarchy (or may form directory loops) which triggers the |
| 9 | PATH_MAX-sized path buffer OR stack overflow. |
| 10 | |
| 11 | Actually some crafted images cannot be deemed as real corrupted |
| 12 | images but over-PATH_MAX paths are not something that we'd like to |
| 13 | support for now. |
| 14 | |
| 15 | CVE: CVE-2023-33551 |
| 16 | Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-33551 |
| 17 | Reported-by: Chaoming Yang <lometsj@live.com> |
| 18 | Fixes: f44043561491 ("erofs-utils: introduce fsck.erofs") |
| 19 | Fixes: b11f84f593f9 ("erofs-utils: fsck: convert to use erofs_iterate_dir()") |
| 20 | Fixes: 412c8f908132 ("erofs-utils: fsck: add --extract=X support to extract to path X") |
| 21 | Signeo-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> |
| 22 | Link: https://lore.kernel.org/r/20230602055256.18061-1-hsiangkao@linux.alibaba.com |
| 23 | |
| 24 | Upstream-Status: Backport |
| 25 | Signed-off-by: Ross Burton <ross.burton@arm.com> |
| 26 | --- |
| 27 | fsck/main.c | 23 +++++++++++++++-------- |
| 28 | 1 file changed, 15 insertions(+), 8 deletions(-) |
| 29 | |
| 30 | diff --git a/fsck/main.c b/fsck/main.c |
| 31 | index 6689ad8..28d95ec 100644 |
| 32 | --- a/fsck/main.c |
| 33 | +++ b/fsck/main.c |
| 34 | @@ -680,28 +680,35 @@ again: |
| 35 | static int erofsfsck_dirent_iter(struct erofs_dir_context *ctx) |
| 36 | { |
| 37 | int ret; |
| 38 | - size_t prev_pos = fsckcfg.extract_pos; |
| 39 | + size_t prev_pos, curr_pos; |
| 40 | |
| 41 | if (ctx->dot_dotdot) |
| 42 | return 0; |
| 43 | |
| 44 | - if (fsckcfg.extract_path) { |
| 45 | - size_t curr_pos = prev_pos; |
| 46 | + prev_pos = fsckcfg.extract_pos; |
| 47 | + curr_pos = prev_pos; |
| 48 | + |
| 49 | + if (prev_pos + ctx->de_namelen >= PATH_MAX) { |
| 50 | + erofs_err("unable to fsck since the path is too long (%u)", |
| 51 | + curr_pos + ctx->de_namelen); |
| 52 | + return -EOPNOTSUPP; |
| 53 | + } |
| 54 | |
| 55 | + if (fsckcfg.extract_path) { |
| 56 | fsckcfg.extract_path[curr_pos++] = '/'; |
| 57 | strncpy(fsckcfg.extract_path + curr_pos, ctx->dname, |
| 58 | ctx->de_namelen); |
| 59 | curr_pos += ctx->de_namelen; |
| 60 | fsckcfg.extract_path[curr_pos] = '\0'; |
| 61 | - fsckcfg.extract_pos = curr_pos; |
| 62 | + } else { |
| 63 | + curr_pos += ctx->de_namelen; |
| 64 | } |
| 65 | - |
| 66 | + fsckcfg.extract_pos = curr_pos; |
| 67 | ret = erofsfsck_check_inode(ctx->dir->nid, ctx->de_nid); |
| 68 | |
| 69 | - if (fsckcfg.extract_path) { |
| 70 | + if (fsckcfg.extract_path) |
| 71 | fsckcfg.extract_path[prev_pos] = '\0'; |
| 72 | - fsckcfg.extract_pos = prev_pos; |
| 73 | - } |
| 74 | + fsckcfg.extract_pos = prev_pos; |
| 75 | return ret; |
| 76 | } |
| 77 | |
| 78 | -- |
| 79 | 2.34.1 |
| 80 | |