]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
apk: backport fix for GCC15 with LTO 18549/head
authorRobert Marko <robimarko@gmail.com>
Mon, 21 Apr 2025 10:33:56 +0000 (12:33 +0200)
committerRobert Marko <robimarko@gmail.com>
Mon, 21 Apr 2025 12:21:10 +0000 (14:21 +0200)
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 <robimarko@gmail.com>
package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch [new file with mode: 0644]

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 (file)
index 0000000..d32dd25
--- /dev/null
@@ -0,0 +1,67 @@
+From 55ab583de9a35ea79d63b8058a131ef260d407a9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+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)