diff options
Diffstat (limited to 'poky/meta/recipes-devtools/erofs-utils/erofs-utils/CVE-2023-33552-1.patch')
-rw-r--r-- | poky/meta/recipes-devtools/erofs-utils/erofs-utils/CVE-2023-33552-1.patch | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/poky/meta/recipes-devtools/erofs-utils/erofs-utils/CVE-2023-33552-1.patch b/poky/meta/recipes-devtools/erofs-utils/erofs-utils/CVE-2023-33552-1.patch new file mode 100644 index 0000000000..011ca1cd5e --- /dev/null +++ b/poky/meta/recipes-devtools/erofs-utils/erofs-utils/CVE-2023-33552-1.patch @@ -0,0 +1,221 @@ +From 8aef6015a03242a7d13467d23ad52b5427bf5247 Mon Sep 17 00:00:00 2001 +From: Yue Hu <huyue2@coolpad.com> +Date: Wed, 11 Jan 2023 09:49:26 +0800 +Subject: [PATCH] erofs-utils: lib: export parts of erofs_pread() + +Export parts of erofs_pread() to avoid duplicated code in +erofs_verify_inode_data(). Let's make two helpers for this. + +Signed-off-by: Yue Hu <huyue2@coolpad.com> +Link: https://lore.kernel.org/r/ff560da9c798b2ca1f1a663a000501486d865487.1673401718.git.huyue2@coolpad.com +Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> + +CVE: CVE-2023-33552 +Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git/commit/?id=4c0fb15a5d85378debe9d10d96cd643d167300ca] +Signed-off-by: Changqing Li <changqing.li@windriver.com> +--- + include/erofs/internal.h | 5 ++ + lib/data.c | 108 ++++++++++++++++++++++++--------------- + 2 files changed, 71 insertions(+), 42 deletions(-) + +diff --git a/include/erofs/internal.h b/include/erofs/internal.h +index d3b2986..28d0e68 100644 +--- a/include/erofs/internal.h ++++ b/include/erofs/internal.h +@@ -335,6 +335,11 @@ int erofs_pread(struct erofs_inode *inode, char *buf, + int erofs_map_blocks(struct erofs_inode *inode, + struct erofs_map_blocks *map, int flags); + int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map); ++int erofs_read_one_data(struct erofs_map_blocks *map, char *buffer, u64 offset, ++ size_t len); ++int z_erofs_read_one_data(struct erofs_inode *inode, ++ struct erofs_map_blocks *map, char *raw, char *buffer, ++ erofs_off_t skip, erofs_off_t length, bool trimmed); + + static inline int erofs_get_occupied_size(const struct erofs_inode *inode, + erofs_off_t *size) +diff --git a/lib/data.c b/lib/data.c +index 6bc554d..2a7fdd5 100644 +--- a/lib/data.c ++++ b/lib/data.c +@@ -158,19 +158,38 @@ int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map) + return 0; + } + ++int erofs_read_one_data(struct erofs_map_blocks *map, char *buffer, u64 offset, ++ size_t len) ++{ ++ struct erofs_map_dev mdev; ++ int ret; ++ ++ mdev = (struct erofs_map_dev) { ++ .m_deviceid = map->m_deviceid, ++ .m_pa = map->m_pa, ++ }; ++ ret = erofs_map_dev(&sbi, &mdev); ++ if (ret) ++ return ret; ++ ++ ret = dev_read(mdev.m_deviceid, buffer, mdev.m_pa + offset, len); ++ if (ret < 0) ++ return -EIO; ++ return 0; ++} ++ + static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer, + erofs_off_t size, erofs_off_t offset) + { + struct erofs_map_blocks map = { + .index = UINT_MAX, + }; +- struct erofs_map_dev mdev; + int ret; + erofs_off_t ptr = offset; + + while (ptr < offset + size) { + char *const estart = buffer + ptr - offset; +- erofs_off_t eend; ++ erofs_off_t eend, moff = 0; + + map.m_la = ptr; + ret = erofs_map_blocks(inode, &map, 0); +@@ -179,14 +198,6 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer, + + DBG_BUGON(map.m_plen != map.m_llen); + +- mdev = (struct erofs_map_dev) { +- .m_deviceid = map.m_deviceid, +- .m_pa = map.m_pa, +- }; +- ret = erofs_map_dev(&sbi, &mdev); +- if (ret) +- return ret; +- + /* trim extent */ + eend = min(offset + size, map.m_la + map.m_llen); + DBG_BUGON(ptr < map.m_la); +@@ -204,19 +215,54 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer, + } + + if (ptr > map.m_la) { +- mdev.m_pa += ptr - map.m_la; ++ moff = ptr - map.m_la; + map.m_la = ptr; + } + +- ret = dev_read(mdev.m_deviceid, estart, mdev.m_pa, +- eend - map.m_la); +- if (ret < 0) +- return -EIO; ++ ret = erofs_read_one_data(&map, estart, moff, eend - map.m_la); ++ if (ret) ++ return ret; + ptr = eend; + } + return 0; + } + ++int z_erofs_read_one_data(struct erofs_inode *inode, ++ struct erofs_map_blocks *map, char *raw, char *buffer, ++ erofs_off_t skip, erofs_off_t length, bool trimmed) ++{ ++ struct erofs_map_dev mdev; ++ int ret = 0; ++ ++ /* no device id here, thus it will always succeed */ ++ mdev = (struct erofs_map_dev) { ++ .m_pa = map->m_pa, ++ }; ++ ret = erofs_map_dev(&sbi, &mdev); ++ if (ret) { ++ DBG_BUGON(1); ++ return ret; ++ } ++ ++ ret = dev_read(mdev.m_deviceid, raw, mdev.m_pa, map->m_plen); ++ if (ret < 0) ++ return ret; ++ ++ ret = z_erofs_decompress(&(struct z_erofs_decompress_req) { ++ .in = raw, ++ .out = buffer, ++ .decodedskip = skip, ++ .inputsize = map->m_plen, ++ .decodedlength = length, ++ .alg = map->m_algorithmformat, ++ .partial_decoding = trimmed ? true : ++ !(map->m_flags & EROFS_MAP_FULL_MAPPED) ++ }); ++ if (ret < 0) ++ return ret; ++ return 0; ++} ++ + static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, + erofs_off_t size, erofs_off_t offset) + { +@@ -224,8 +270,7 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, + struct erofs_map_blocks map = { + .index = UINT_MAX, + }; +- struct erofs_map_dev mdev; +- bool partial; ++ bool trimmed; + unsigned int bufsize = 0; + char *raw = NULL; + int ret = 0; +@@ -238,27 +283,17 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, + if (ret) + break; + +- /* no device id here, thus it will always succeed */ +- mdev = (struct erofs_map_dev) { +- .m_pa = map.m_pa, +- }; +- ret = erofs_map_dev(&sbi, &mdev); +- if (ret) { +- DBG_BUGON(1); +- break; +- } +- + /* + * trim to the needed size if the returned extent is quite + * larger than requested, and set up partial flag as well. + */ + if (end < map.m_la + map.m_llen) { + length = end - map.m_la; +- partial = true; ++ trimmed = true; + } else { + DBG_BUGON(end != map.m_la + map.m_llen); + length = map.m_llen; +- partial = !(map.m_flags & EROFS_MAP_FULL_MAPPED); ++ trimmed = false; + } + + if (map.m_la < offset) { +@@ -283,19 +318,8 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, + break; + } + } +- ret = dev_read(mdev.m_deviceid, raw, mdev.m_pa, map.m_plen); +- if (ret < 0) +- break; +- +- ret = z_erofs_decompress(&(struct z_erofs_decompress_req) { +- .in = raw, +- .out = buffer + end - offset, +- .decodedskip = skip, +- .inputsize = map.m_plen, +- .decodedlength = length, +- .alg = map.m_algorithmformat, +- .partial_decoding = partial +- }); ++ ret = z_erofs_read_one_data(inode, &map, raw, ++ buffer + end - offset, skip, length, trimmed); + if (ret < 0) + break; + } +-- +2.25.1 + |