From: Robert Marko Date: Mon, 21 Apr 2025 10:33:56 +0000 (+0200) Subject: apk: backport fix for GCC15 with LTO X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F18549%2Fhead;p=thirdparty%2Fopenwrt.git apk: backport fix for GCC15 with LTO APK is currently broken when built with GCC15 and LTO as it will then hang indefinitevely on the package/install step. Luckily, upstream was able to find the issue and fix it, so lets backport the fix as GCC15 is the default compiler on Fedora 42(And soon more distros) Link: https://github.com/openwrt/openwrt/pull/18549 Signed-off-by: Robert Marko --- diff --git a/package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch b/package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch new file mode 100644 index 00000000000..d32dd2541f7 --- /dev/null +++ b/package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch @@ -0,0 +1,67 @@ +From 55ab583de9a35ea79d63b8058a131ef260d407a9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Mon, 21 Apr 2025 12:22:04 +0300 +Subject: [PATCH] io: fix undefined behaviour in apk_istream_get_delim + +Arithmetics on null pointer are undefined, so leave is->ptr +pointing to is->buf always. Rewrite the function to be +a bit more readable. + +ref #11064, #11105 +--- + src/io.c | 38 +++++++++++++++++++++----------------- + 1 file changed, 21 insertions(+), 17 deletions(-) + +--- a/src/io.c ++++ b/src/io.c +@@ -191,29 +191,33 @@ int apk_istream_get_max(struct apk_istre + + int apk_istream_get_delim(struct apk_istream *is, apk_blob_t token, apk_blob_t *data) + { +- apk_blob_t ret = APK_BLOB_NULL, left = APK_BLOB_NULL; +- int r = 0; ++ int r; ++ ++ if (is->err && is->ptr == is->end) { ++ *data = APK_BLOB_NULL; ++ return is->err < 0 ? is->err : -APKE_EOF; ++ } + + do { +- if (apk_blob_split(APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr), token, &ret, &left)) +- break; ++ apk_blob_t left; ++ if (apk_blob_split(APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr), token, data, &left)) { ++ is->ptr = (uint8_t*)left.ptr; ++ is->end = (uint8_t*)left.ptr + left.len; ++ return 0; ++ } + r = __apk_istream_fill(is); + } while (r == 0); + +- /* Last segment before end-of-file. Return also zero length non-null +- * blob if eof comes immediately after the delimiter. */ +- if (is->ptr && r > 0) +- ret = APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr); +- +- if (!APK_BLOB_IS_NULL(ret)) { +- is->ptr = (uint8_t*)left.ptr; +- is->end = (uint8_t*)left.ptr + left.len; +- *data = ret; +- return 0; ++ if (r < 0) { ++ *data = APK_BLOB_NULL; ++ return apk_istream_error(is, r); + } +- if (r < 0) apk_istream_error(is, r); +- *data = APK_BLOB_NULL; +- return r < 0 ? r : -APKE_EOF; ++ ++ /* EOF received. Return the last buffered data or an empty ++ * blob if EOF came directly after last separator. */ ++ *data = APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr); ++ is->ptr = is->end = is->buf; ++ return 0; + } + + static void blob_get_meta(struct apk_istream *is, struct apk_file_meta *meta)