From: Greg Kroah-Hartman Date: Wed, 9 Oct 2019 13:36:20 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.14.149~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d25278fa02e553f2e29198a0f89efd8b8e17fba4;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch cfg80211-use-const-more-consistently-in-for_each_element-macros.patch nl80211-validate-beacon-head.patch staging-erofs-add-two-missing-erofs_workgroup_put-for-corrupted-images.patch staging-erofs-detect-potential-multiref-due-to-corrupted-images.patch staging-erofs-fix-an-error-handling-in-erofs_readdir.patch staging-erofs-some-compressed-cluster-should-be-submitted-for-corrupted-images.patch --- diff --git a/queue-4.19/cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch b/queue-4.19/cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch new file mode 100644 index 00000000000..c018580401b --- /dev/null +++ b/queue-4.19/cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch @@ -0,0 +1,134 @@ +From 0f3b07f027f87a38ebe5c436490095df762819be Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 7 Feb 2019 21:44:41 +0100 +Subject: cfg80211: add and use strongly typed element iteration macros + +From: Johannes Berg + +commit 0f3b07f027f87a38ebe5c436490095df762819be upstream. + +Rather than always iterating elements from frames with pure +u8 pointers, add a type "struct element" that encapsulates +the id/datalen/data format of them. + +Then, add the element iteration macros + * for_each_element + * for_each_element_id + * for_each_element_extid + +which take, as their first 'argument', such a structure and +iterate through a given u8 array interpreting it as elements. + +While at it and since we'll need it, also add + * for_each_subelement + * for_each_subelement_id + * for_each_subelement_extid + +which instead of taking data/length just take an outer element +and use its data/datalen. + +Also add for_each_element_completed() to determine if any of +the loops above completed, i.e. it was able to parse all of +the elements successfully and no data remained. + +Use for_each_element_id() in cfg80211_find_ie_match() as the +first user of this. + +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ieee80211.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++ + net/wireless/scan.c | 14 +++++------- + 2 files changed, 59 insertions(+), 8 deletions(-) + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3185,4 +3185,57 @@ static inline bool ieee80211_action_cont + return true; + } + ++struct element { ++ u8 id; ++ u8 datalen; ++ u8 data[]; ++}; ++ ++/* element iteration helpers */ ++#define for_each_element(element, _data, _datalen) \ ++ for (element = (void *)(_data); \ ++ (u8 *)(_data) + (_datalen) - (u8 *)element >= \ ++ sizeof(*element) && \ ++ (u8 *)(_data) + (_datalen) - (u8 *)element >= \ ++ sizeof(*element) + element->datalen; \ ++ element = (void *)(element->data + element->datalen)) ++ ++#define for_each_element_id(element, _id, data, datalen) \ ++ for_each_element(element, data, datalen) \ ++ if (element->id == (_id)) ++ ++#define for_each_element_extid(element, extid, data, datalen) \ ++ for_each_element(element, data, datalen) \ ++ if (element->id == WLAN_EID_EXTENSION && \ ++ element->datalen > 0 && \ ++ element->data[0] == (extid)) ++ ++#define for_each_subelement(sub, element) \ ++ for_each_element(sub, (element)->data, (element)->datalen) ++ ++#define for_each_subelement_id(sub, id, element) \ ++ for_each_element_id(sub, id, (element)->data, (element)->datalen) ++ ++#define for_each_subelement_extid(sub, extid, element) \ ++ for_each_element_extid(sub, extid, (element)->data, (element)->datalen) ++ ++/** ++ * for_each_element_completed - determine if element parsing consumed all data ++ * @element: element pointer after for_each_element() or friends ++ * @data: same data pointer as passed to for_each_element() or friends ++ * @datalen: same data length as passed to for_each_element() or friends ++ * ++ * This function returns %true if all the data was parsed or considered ++ * while walking the elements. Only use this if your for_each_element() ++ * loop cannot be broken out of, otherwise it always returns %false. ++ * ++ * If some data was malformed, this returns %false since the last parsed ++ * element will not fill the whole remaining data. ++ */ ++static inline bool for_each_element_completed(const struct element *element, ++ const void *data, size_t datalen) ++{ ++ return (u8 *)element == (u8 *)data + datalen; ++} ++ + #endif /* LINUX_IEEE80211_H */ +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -484,6 +484,8 @@ const u8 *cfg80211_find_ie_match(u8 eid, + const u8 *match, int match_len, + int match_offset) + { ++ const struct element *elem; ++ + /* match_offset can't be smaller than 2, unless match_len is + * zero, in which case match_offset must be zero as well. + */ +@@ -491,14 +493,10 @@ const u8 *cfg80211_find_ie_match(u8 eid, + (!match_len && match_offset))) + return NULL; + +- while (len >= 2 && len >= ies[1] + 2) { +- if ((ies[0] == eid) && +- (ies[1] + 2 >= match_offset + match_len) && +- !memcmp(ies + match_offset, match, match_len)) +- return ies; +- +- len -= ies[1] + 2; +- ies += ies[1] + 2; ++ for_each_element_id(elem, eid, ies, len) { ++ if (elem->datalen >= match_offset - 2 + match_len && ++ !memcmp(elem->data + match_offset - 2, match, match_len)) ++ return (void *)elem; + } + + return NULL; diff --git a/queue-4.19/cfg80211-use-const-more-consistently-in-for_each_element-macros.patch b/queue-4.19/cfg80211-use-const-more-consistently-in-for_each_element-macros.patch new file mode 100644 index 00000000000..c1ec7c7304a --- /dev/null +++ b/queue-4.19/cfg80211-use-const-more-consistently-in-for_each_element-macros.patch @@ -0,0 +1,59 @@ +From 7388afe09143210f555bdd6c75035e9acc1fab96 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 11 Feb 2019 16:29:04 +0200 +Subject: cfg80211: Use const more consistently in for_each_element macros + +From: Jouni Malinen + +commit 7388afe09143210f555bdd6c75035e9acc1fab96 upstream. + +Enforce the first argument to be a correct type of a pointer to struct +element and avoid unnecessary typecasts from const to non-const pointers +(the change in validate_ie_attr() is needed to make this part work). In +addition, avoid signed/unsigned comparison within for_each_element() and +mark struct element packed just in case. + +Signed-off-by: Jouni Malinen +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ieee80211.h | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3189,16 +3189,16 @@ struct element { + u8 id; + u8 datalen; + u8 data[]; +-}; ++} __packed; + + /* element iteration helpers */ +-#define for_each_element(element, _data, _datalen) \ +- for (element = (void *)(_data); \ +- (u8 *)(_data) + (_datalen) - (u8 *)element >= \ +- sizeof(*element) && \ +- (u8 *)(_data) + (_datalen) - (u8 *)element >= \ +- sizeof(*element) + element->datalen; \ +- element = (void *)(element->data + element->datalen)) ++#define for_each_element(_elem, _data, _datalen) \ ++ for (_elem = (const struct element *)(_data); \ ++ (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \ ++ (int)sizeof(*_elem) && \ ++ (const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \ ++ (int)sizeof(*_elem) + _elem->datalen; \ ++ _elem = (const struct element *)(_elem->data + _elem->datalen)) + + #define for_each_element_id(element, _id, data, datalen) \ + for_each_element(element, data, datalen) \ +@@ -3235,7 +3235,7 @@ struct element { + static inline bool for_each_element_completed(const struct element *element, + const void *data, size_t datalen) + { +- return (u8 *)element == (u8 *)data + datalen; ++ return (const u8 *)element == (const u8 *)data + datalen; + } + + #endif /* LINUX_IEEE80211_H */ diff --git a/queue-4.19/nl80211-validate-beacon-head.patch b/queue-4.19/nl80211-validate-beacon-head.patch new file mode 100644 index 00000000000..b7c298594f9 --- /dev/null +++ b/queue-4.19/nl80211-validate-beacon-head.patch @@ -0,0 +1,82 @@ +From f88eb7c0d002a67ef31aeb7850b42ff69abc46dc Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 20 Sep 2019 21:54:17 +0200 +Subject: nl80211: validate beacon head + +From: Johannes Berg + +commit f88eb7c0d002a67ef31aeb7850b42ff69abc46dc upstream. + +We currently don't validate the beacon head, i.e. the header, +fixed part and elements that are to go in front of the TIM +element. This means that the variable elements there can be +malformed, e.g. have a length exceeding the buffer size, but +most downstream code from this assumes that this has already +been checked. + +Add the necessary checks to the netlink policy. + +Cc: stable@vger.kernel.org +Fixes: ed1b6cc7f80f ("cfg80211/nl80211: add beacon settings") +Link: https://lore.kernel.org/r/1569009255-I7ac7fbe9436e9d8733439eab8acbbd35e55c74ef@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -200,6 +200,38 @@ cfg80211_get_dev_from_info(struct net *n + return __cfg80211_rdev_from_attrs(netns, info->attrs); + } + ++static int validate_beacon_head(const struct nlattr *attr, ++ struct netlink_ext_ack *extack) ++{ ++ const u8 *data = nla_data(attr); ++ unsigned int len = nla_len(attr); ++ const struct element *elem; ++ const struct ieee80211_mgmt *mgmt = (void *)data; ++ unsigned int fixedlen = offsetof(struct ieee80211_mgmt, ++ u.beacon.variable); ++ ++ if (len < fixedlen) ++ goto err; ++ ++ if (ieee80211_hdrlen(mgmt->frame_control) != ++ offsetof(struct ieee80211_mgmt, u.beacon)) ++ goto err; ++ ++ data += fixedlen; ++ len -= fixedlen; ++ ++ for_each_element(elem, data, len) { ++ /* nothing */ ++ } ++ ++ if (for_each_element_completed(elem, data, len)) ++ return 0; ++ ++err: ++ NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head"); ++ return -EINVAL; ++} ++ + /* policy for the attributes */ + static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, +@@ -4016,6 +4048,12 @@ static int nl80211_parse_beacon(struct n + memset(bcn, 0, sizeof(*bcn)); + + if (attrs[NL80211_ATTR_BEACON_HEAD]) { ++ int ret = validate_beacon_head(attrs[NL80211_ATTR_BEACON_HEAD], ++ NULL); ++ ++ if (ret) ++ return ret; ++ + bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]); + bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]); + if (!bcn->head_len) diff --git a/queue-4.19/series b/queue-4.19/series index fd265c98536..8669e943057 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -105,3 +105,10 @@ arm64-use-firmware-to-detect-cpus-that-are-not-affected-by-spectre-v2.patch arm64-speculation-support-mitigations-cmdline-option.patch vfs-fix-eoverflow-testing-in-put_compat_statfs64.patch coresight-etm4x-use-explicit-barriers-on-enable-disable.patch +staging-erofs-fix-an-error-handling-in-erofs_readdir.patch +staging-erofs-some-compressed-cluster-should-be-submitted-for-corrupted-images.patch +staging-erofs-add-two-missing-erofs_workgroup_put-for-corrupted-images.patch +staging-erofs-detect-potential-multiref-due-to-corrupted-images.patch +cfg80211-add-and-use-strongly-typed-element-iteration-macros.patch +cfg80211-use-const-more-consistently-in-for_each_element-macros.patch +nl80211-validate-beacon-head.patch diff --git a/queue-4.19/staging-erofs-add-two-missing-erofs_workgroup_put-for-corrupted-images.patch b/queue-4.19/staging-erofs-add-two-missing-erofs_workgroup_put-for-corrupted-images.patch new file mode 100644 index 00000000000..e3ae6876829 --- /dev/null +++ b/queue-4.19/staging-erofs-add-two-missing-erofs_workgroup_put-for-corrupted-images.patch @@ -0,0 +1,48 @@ +From foo@baz Wed 09 Oct 2019 03:26:06 PM CEST +From: Gao Xiang +Date: Wed, 9 Oct 2019 18:12:38 +0800 +Subject: staging: erofs: add two missing erofs_workgroup_put for corrupted images +To: Greg Kroah-Hartman , , Chao Yu +Cc: , Miao Xie , Gao Xiang +Message-ID: <20191009101239.195587-3-gaoxiang25@huawei.com> + +From: Gao Xiang + +commit 138e1a0990e80db486ab9f6c06bd5c01f9a97999 upstream. + +As reported by erofs-utils fuzzer, these error handling +path will be entered to handle corrupted images. + +Lack of erofs_workgroup_puts will cause unmounting +unsuccessfully. + +Fix these return values to EFSCORRUPTED as well. + +Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") +Cc: # 4.19+ +Signed-off-by: Gao Xiang +Reviewed-by: Chao Yu +Link: https://lore.kernel.org/r/20190819103426.87579-4-gaoxiang25@huawei.com +[ Gao Xiang: Older kernel versions don't have length validity check + and EFSCORRUPTED, thus backport pageofs check for now. ] +Signed-off-by: Gao Xiang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/erofs/unzip_vle.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/staging/erofs/unzip_vle.c ++++ b/drivers/staging/erofs/unzip_vle.c +@@ -311,7 +311,11 @@ z_erofs_vle_work_lookup(struct super_blo + /* if multiref is disabled, `primary' is always true */ + primary = true; + +- DBG_BUGON(work->pageofs != pageofs); ++ if (work->pageofs != pageofs) { ++ DBG_BUGON(1); ++ erofs_workgroup_put(egrp); ++ return ERR_PTR(-EIO); ++ } + + /* + * lock must be taken first to avoid grp->next == NIL between diff --git a/queue-4.19/staging-erofs-detect-potential-multiref-due-to-corrupted-images.patch b/queue-4.19/staging-erofs-detect-potential-multiref-due-to-corrupted-images.patch new file mode 100644 index 00000000000..4a390ac77d3 --- /dev/null +++ b/queue-4.19/staging-erofs-detect-potential-multiref-due-to-corrupted-images.patch @@ -0,0 +1,80 @@ +From foo@baz Wed 09 Oct 2019 03:26:06 PM CEST +From: Gao Xiang +Date: Wed, 9 Oct 2019 18:12:39 +0800 +Subject: staging: erofs: detect potential multiref due to corrupted images +To: Greg Kroah-Hartman , , Chao Yu +Cc: , Miao Xie , Gao Xiang +Message-ID: <20191009101239.195587-4-gaoxiang25@huawei.com> + +From: Gao Xiang + +commit e12a0ce2fa69798194f3a8628baf6edfbd5c548f upstream. + +As reported by erofs-utils fuzzer, currently, multiref +(ondisk deduplication) hasn't been supported for now, +we should forbid it properly. + +Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") +Cc: # 4.19+ +Signed-off-by: Gao Xiang +Reviewed-by: Chao Yu +Link: https://lore.kernel.org/r/20190821140152.229648-1-gaoxiang25@huawei.com +[ Gao Xiang: Since earlier kernels don't define EFSCORRUPTED, + let's use EIO instead. ] +Signed-off-by: Gao Xiang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/erofs/unzip_vle.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/staging/erofs/unzip_vle.c ++++ b/drivers/staging/erofs/unzip_vle.c +@@ -857,6 +857,7 @@ repeat: + for (i = 0; i < nr_pages; ++i) + pages[i] = NULL; + ++ err = 0; + z_erofs_pagevec_ctor_init(&ctor, + Z_EROFS_VLE_INLINE_PAGEVECS, work->pagevec, 0); + +@@ -878,8 +879,17 @@ repeat: + pagenr = z_erofs_onlinepage_index(page); + + DBG_BUGON(pagenr >= nr_pages); +- DBG_BUGON(pages[pagenr]); + ++ /* ++ * currently EROFS doesn't support multiref(dedup), ++ * so here erroring out one multiref page. ++ */ ++ if (pages[pagenr]) { ++ DBG_BUGON(1); ++ SetPageError(pages[pagenr]); ++ z_erofs_onlinepage_endio(pages[pagenr]); ++ err = -EIO; ++ } + pages[pagenr] = page; + } + sparsemem_pages = i; +@@ -889,7 +899,6 @@ repeat: + overlapped = false; + compressed_pages = grp->compressed_pages; + +- err = 0; + for (i = 0; i < clusterpages; ++i) { + unsigned pagenr; + +@@ -915,7 +924,12 @@ repeat: + pagenr = z_erofs_onlinepage_index(page); + + DBG_BUGON(pagenr >= nr_pages); +- DBG_BUGON(pages[pagenr]); ++ if (pages[pagenr]) { ++ DBG_BUGON(1); ++ SetPageError(pages[pagenr]); ++ z_erofs_onlinepage_endio(pages[pagenr]); ++ err = -EIO; ++ } + ++sparsemem_pages; + pages[pagenr] = page; + diff --git a/queue-4.19/staging-erofs-fix-an-error-handling-in-erofs_readdir.patch b/queue-4.19/staging-erofs-fix-an-error-handling-in-erofs_readdir.patch new file mode 100644 index 00000000000..36ec1edad2a --- /dev/null +++ b/queue-4.19/staging-erofs-fix-an-error-handling-in-erofs_readdir.patch @@ -0,0 +1,59 @@ +From foo@baz Wed 09 Oct 2019 03:26:06 PM CEST +From: Gao Xiang +Date: Wed, 9 Oct 2019 18:12:36 +0800 +Subject: staging: erofs: fix an error handling in erofs_readdir() +To: Greg Kroah-Hartman , , Chao Yu +Cc: , Miao Xie , Gao Xiang +Message-ID: <20191009101239.195587-1-gaoxiang25@huawei.com> + +From: Gao Xiang + +commit acb383f1dcb4f1e79b66d4be3a0b6f519a957b0d upstream. + +Richard observed a forever loop of erofs_read_raw_page() [1] +which can be generated by forcely setting ->u.i_blkaddr +to 0xdeadbeef (as my understanding block layer can +handle access beyond end of device correctly). + +After digging into that, it seems the problem is highly +related with directories and then I found the root cause +is an improper error handling in erofs_readdir(). + +Let's fix it now. + +[1] https://lore.kernel.org/r/1163995781.68824.1566084358245.JavaMail.zimbra@nod.at/ + +Reported-by: Richard Weinberger +Fixes: 3aa8ec716e52 ("staging: erofs: add directory operations") +Cc: # 4.19+ +Reviewed-by: Chao Yu +Signed-off-by: Gao Xiang +Link: https://lore.kernel.org/r/20190818125457.25906-1-hsiangkao@aol.com +[ Gao Xiang: Since earlier kernels don't define EFSCORRUPTED, + let's use original error code instead. ] +Signed-off-by: Gao Xiang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/erofs/dir.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/staging/erofs/dir.c ++++ b/drivers/staging/erofs/dir.c +@@ -100,8 +100,15 @@ static int erofs_readdir(struct file *f, + unsigned nameoff, maxsize; + + dentry_page = read_mapping_page(mapping, i, NULL); +- if (IS_ERR(dentry_page)) +- continue; ++ if (dentry_page == ERR_PTR(-ENOMEM)) { ++ err = -ENOMEM; ++ break; ++ } else if (IS_ERR(dentry_page)) { ++ errln("fail to readdir of logical block %u of nid %llu", ++ i, EROFS_V(dir)->nid); ++ err = PTR_ERR(dentry_page); ++ break; ++ } + + lock_page(dentry_page); + de = (struct erofs_dirent *)kmap(dentry_page); diff --git a/queue-4.19/staging-erofs-some-compressed-cluster-should-be-submitted-for-corrupted-images.patch b/queue-4.19/staging-erofs-some-compressed-cluster-should-be-submitted-for-corrupted-images.patch new file mode 100644 index 00000000000..10a5f760651 --- /dev/null +++ b/queue-4.19/staging-erofs-some-compressed-cluster-should-be-submitted-for-corrupted-images.patch @@ -0,0 +1,61 @@ +From foo@baz Wed 09 Oct 2019 03:26:06 PM CEST +From: Gao Xiang +Date: Wed, 9 Oct 2019 18:12:37 +0800 +Subject: staging: erofs: some compressed cluster should be submitted for corrupted images +To: Greg Kroah-Hartman , , Chao Yu +Cc: , Miao Xie , Gao Xiang +Message-ID: <20191009101239.195587-2-gaoxiang25@huawei.com> + +From: Gao Xiang + +commit ee45197c807895e156b2be0abcaebdfc116487c8 upstream. + +As reported by erofs_utils fuzzer, a logical page can belong +to at most 2 compressed clusters, if one compressed cluster +is corrupted, but the other has been ready in submitting chain. + +The chain needs to submit anyway in order to keep the page +working properly (page unlocked with PG_error set, PG_uptodate +not set). + +Let's fix it now. + +Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") +Cc: # 4.19+ +Signed-off-by: Gao Xiang +Reviewed-by: Chao Yu +Link: https://lore.kernel.org/r/20190819103426.87579-2-gaoxiang25@huawei.com +[ Gao Xiang: Manually backport to v4.19.y stable. ] +Signed-off-by: Gao Xiang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/erofs/unzip_vle.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/drivers/staging/erofs/unzip_vle.c ++++ b/drivers/staging/erofs/unzip_vle.c +@@ -1335,19 +1335,18 @@ static int z_erofs_vle_normalaccess_read + err = z_erofs_do_read_page(&f, page, &pagepool); + (void)z_erofs_vle_work_iter_end(&f.builder); + +- if (err) { ++ /* if some compressed cluster ready, need submit them anyway */ ++ z_erofs_submit_and_unzip(&f, &pagepool, true); ++ ++ if (err) + errln("%s, failed to read, err [%d]", __func__, err); +- goto out; +- } + +- z_erofs_submit_and_unzip(&f, &pagepool, true); +-out: + if (f.m_iter.mpage != NULL) + put_page(f.m_iter.mpage); + + /* clean up the remaining free pages */ + put_pages_list(&pagepool); +- return 0; ++ return err; + } + + static inline int __z_erofs_vle_normalaccess_readpages(