summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/erofs-utils/files/0001-erofs-utils-fsck-don-t-allocate-read-too-large-exten.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/erofs-utils/files/0001-erofs-utils-fsck-don-t-allocate-read-too-large-exten.patch')
-rw-r--r--meta/recipes-devtools/erofs-utils/files/0001-erofs-utils-fsck-don-t-allocate-read-too-large-exten.patch126
1 files changed, 126 insertions, 0 deletions
diff --git a/meta/recipes-devtools/erofs-utils/files/0001-erofs-utils-fsck-don-t-allocate-read-too-large-exten.patch b/meta/recipes-devtools/erofs-utils/files/0001-erofs-utils-fsck-don-t-allocate-read-too-large-exten.patch
new file mode 100644
index 0000000000..52f475dc42
--- /dev/null
+++ b/meta/recipes-devtools/erofs-utils/files/0001-erofs-utils-fsck-don-t-allocate-read-too-large-exten.patch
@@ -0,0 +1,126 @@
1From c769805c79d5acede65d96e5786aa5ebb46c01e0 Mon Sep 17 00:00:00 2001
2From: Gao Xiang <hsiangkao@linux.alibaba.com>
3Date: Fri, 2 Jun 2023 11:05:19 +0800
4Subject: [PATCH 1/2] erofs-utils: fsck: don't allocate/read too large extents
5
6Since some crafted EROFS filesystem images could have insane large
7extents, which causes unexpected bahaviors when extracting data.
8
9Fix it by extracting large extents with a buffer of a reasonable
10maximum size limit and reading multiple times instead.
11
12Note that only `--extract` option is impacted.
13
14CVE: CVE-2023-33552
15Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-33552
16Reported-by: Chaoming Yang <lometsj@live.com>
17Fixes: 412c8f908132 ("erofs-utils: fsck: add --extract=X support to extract to path X")
18Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
19Link: https://lore.kernel.org/r/20230602030519.117071-1-hsiangkao@linux.alibaba.com
20
21Upstream-Status: Backport
22Signed-off-by: Ross Burton <ross.burton@arm.com>
23---
24 fsck/main.c | 63 +++++++++++++++++++++++++++++++++++++++++------------
25 1 file changed, 49 insertions(+), 14 deletions(-)
26
27diff --git a/fsck/main.c b/fsck/main.c
28index 6b42252..6689ad8 100644
29--- a/fsck/main.c
30+++ b/fsck/main.c
31@@ -392,6 +392,8 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
32 }
33
34 while (pos < inode->i_size) {
35+ unsigned int alloc_rawsize;
36+
37 map.m_la = pos;
38 if (compressed)
39 ret = z_erofs_map_blocks_iter(inode, &map,
40@@ -420,10 +422,28 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
41 if (!(map.m_flags & EROFS_MAP_MAPPED) || !fsckcfg.check_decomp)
42 continue;
43
44- if (map.m_plen > raw_size) {
45- raw_size = map.m_plen;
46- raw = realloc(raw, raw_size);
47- BUG_ON(!raw);
48+ if (map.m_plen > Z_EROFS_PCLUSTER_MAX_SIZE) {
49+ if (compressed) {
50+ erofs_err("invalid pcluster size %" PRIu64 " @ offset %" PRIu64 " of nid %" PRIu64,
51+ map.m_plen, map.m_la,
52+ inode->nid | 0ULL);
53+ ret = -EFSCORRUPTED;
54+ goto out;
55+ }
56+ alloc_rawsize = Z_EROFS_PCLUSTER_MAX_SIZE;
57+ } else {
58+ alloc_rawsize = map.m_plen;
59+ }
60+
61+ if (alloc_rawsize > raw_size) {
62+ char *newraw = realloc(raw, alloc_rawsize);
63+
64+ if (!newraw) {
65+ ret = -ENOMEM;
66+ goto out;
67+ }
68+ raw = newraw;
69+ raw_size = alloc_rawsize;
70 }
71
72 if (compressed) {
73@@ -434,18 +454,27 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
74 }
75 ret = z_erofs_read_one_data(inode, &map, raw, buffer,
76 0, map.m_llen, false);
77+ if (ret)
78+ goto out;
79+
80+ if (outfd >= 0 && write(outfd, buffer, map.m_llen) < 0)
81+ goto fail_eio;
82 } else {
83- ret = erofs_read_one_data(&map, raw, 0, map.m_plen);
84- }
85- if (ret)
86- goto out;
87+ u64 p = 0;
88
89- if (outfd >= 0 && write(outfd, compressed ? buffer : raw,
90- map.m_llen) < 0) {
91- erofs_err("I/O error occurred when verifying data chunk @ nid %llu",
92- inode->nid | 0ULL);
93- ret = -EIO;
94- goto out;
95+ do {
96+ u64 count = min_t(u64, alloc_rawsize,
97+ map.m_llen);
98+
99+ ret = erofs_read_one_data(&map, raw, p, count);
100+ if (ret)
101+ goto out;
102+
103+ if (outfd >= 0 && write(outfd, raw, count) < 0)
104+ goto fail_eio;
105+ map.m_llen -= count;
106+ p += count;
107+ } while (map.m_llen);
108 }
109 }
110
111@@ -460,6 +489,12 @@ out:
112 if (buffer)
113 free(buffer);
114 return ret < 0 ? ret : 0;
115+
116+fail_eio:
117+ erofs_err("I/O error occurred when verifying data chunk @ nid %llu",
118+ inode->nid | 0ULL);
119+ ret = -EIO;
120+ goto out;
121 }
122
123 static inline int erofs_extract_dir(struct erofs_inode *inode)
124--
1252.34.1
126