summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens2026-05-31 15:21:48 +0000
committerHauke Mehrtens2026-06-03 23:19:40 +0000
commit4fbd48515d6a0c3d8908ce70a09eaac1fb8f7615 (patch)
tree9c878df852434ce6d28596f077d6472a4e69d7d0
parentdc091afa58602e487cc72e3fe631cf97bec220d7 (diff)
downloadrpcd-4fbd48515d6a0c3d8908ce70a09eaac1fb8f7615.tar.gz
rpc-sys: packagelist: avoid size_t underflow when stripping ABI version
When an entry in /lib/apk/db/installed carries an "g:openwrt:abiversion=" tag, the code strips that suffix from the package name via: pkg[strlen(pkg) - strlen(abi)] = '\0'; This assumes the ABI version is always a suffix of (and thus no longer than) the package name. A malformed or crafted status file can violate that assumption, making the unsigned subtraction wrap around to a huge index and write a NUL byte far out of bounds of the 128-byte pkg buffer. Only perform the strip when the ABI string is no longer than the package name. Assisted-by: Claude:claude-opus-4-8 Link: https://github.com/openwrt/rpcd/pull/34 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-rw-r--r--sys.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sys.c b/sys.c
index 5e1cc18..71af834 100644
--- a/sys.c
+++ b/sys.c
@@ -327,8 +327,13 @@ rpc_sys_packagelist(struct ubus_context *ctx, struct ubus_object *obj,
if (pkg[0] && ver[0]) {
/* Need to check both ABI-versioned and non-versioned pkg */
bool keep = is_all_or_world(pkg, world);
- if (abi[0]) {
- pkg[strlen(pkg)-strlen(abi)] = '\0';
+ size_t plen = strlen(pkg), alen = strlen(abi);
+ /* The ABI version is expected to be a suffix of the
+ * package name. Guard against a malformed status file
+ * where it is longer, which would underflow the
+ * unsigned subtraction and write out of bounds. */
+ if (abi[0] && alen <= plen) {
+ pkg[plen - alen] = '\0';
if (!keep)
keep = is_all_or_world(pkg, world);
}