|
|
Message-ID: <20260805141033.841558-6-matthias.goergens@gmail.com>
Date: Wed, 5 Aug 2026 22:10:28 +0800
From: Matthias Goergens <matthias.goergens@...il.com>
To: musl@...ts.openwall.com
Cc: Matthias Goergens <matthias.goergens@...il.com>
Subject: [PATCH 05/10] regression: test glob GLOB_DOOFFS vector overflow
gl_offs near SIZE_MAX must be rejected with GLOB_NOSPACE without
touching the caller's fields instead of wrapping the result-vector
allocation into out-of-bounds pointer writes.
Covered by the musl patch "regex: avoid overflow sizing glob
result vector".
---
src/regression/glob-dooffs-overflow.c | 54 +++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100644 src/regression/glob-dooffs-overflow.c
diff --git a/src/regression/glob-dooffs-overflow.c b/src/regression/glob-dooffs-overflow.c
new file mode 100644
index 0000000..d30e7ba
--- /dev/null
+++ b/src/regression/glob-dooffs-overflow.c
@@ -0,0 +1,54 @@
+// GLOB_DOOFFS makes the caller's gl_offs part of the result-vector
+// size. musl used it in unchecked allocation arithmetic, so gl_offs
+// near SIZE_MAX wrapped the allocation to a small buffer followed by
+// out-of-bounds pointer writes. The oversized vector must be rejected
+// with GLOB_NOSPACE without touching the caller's fields.
+#include <glob.h>
+#include <stdint.h>
+#include <string.h>
+#include "test.h"
+
+int main(void)
+{
+ glob_t g = { .gl_offs = SIZE_MAX };
+ int r;
+
+ r = glob("no-such-file-expected-glob-dooffs-overflow",
+ GLOB_DOOFFS | GLOB_NOCHECK, 0, &g);
+ if (r != GLOB_NOSPACE)
+ t_error("glob with gl_offs == SIZE_MAX returned %d, want GLOB_NOSPACE (%d)\n",
+ r, GLOB_NOSPACE);
+ if (g.gl_pathc != 0 || g.gl_pathv != 0)
+ t_error("failed glob left pathc %zu pathv %p, want 0, NULL\n",
+ g.gl_pathc, (void *)g.gl_pathv);
+ if (g.gl_offs != SIZE_MAX)
+ t_error("failed glob changed gl_offs from %zu to %zu\n",
+ (size_t)SIZE_MAX, g.gl_offs);
+ globfree(&g);
+
+ /* ordinary GLOB_DOOFFS control: reserved slots and the match */
+ g = (glob_t){ .gl_offs = 2 };
+ r = glob("first-no-such-file-expected-glob-dooffs-overflow",
+ GLOB_DOOFFS | GLOB_NOCHECK, 0, &g);
+ if (r != 0 || g.gl_pathc != 1 || !g.gl_pathv ||
+ g.gl_pathv[0] || g.gl_pathv[1] ||
+ !g.gl_pathv[2] ||
+ strcmp(g.gl_pathv[2], "first-no-such-file-expected-glob-dooffs-overflow") ||
+ g.gl_pathv[3])
+ t_error("ordinary GLOB_DOOFFS glob failed: r %d pathc %zu\n",
+ r, g.gl_pathc);
+
+ /* GLOB_APPEND control: the existing result is extended in place */
+ r = glob("second-no-such-file-expected-glob-dooffs-overflow",
+ GLOB_DOOFFS | GLOB_NOCHECK | GLOB_APPEND, 0, &g);
+ if (r != 0 || g.gl_pathc != 2 || !g.gl_pathv ||
+ !g.gl_pathv[2] ||
+ strcmp(g.gl_pathv[2], "first-no-such-file-expected-glob-dooffs-overflow") ||
+ !g.gl_pathv[3] ||
+ strcmp(g.gl_pathv[3], "second-no-such-file-expected-glob-dooffs-overflow") ||
+ g.gl_pathv[4])
+ t_error("GLOB_APPEND glob failed: r %d pathc %zu\n", r, g.gl_pathc);
+ globfree(&g);
+
+ return t_status;
+}
--
2.55.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.