From 216947a4d415ba626cbd1c4193aedd5e9c3d4d6d Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 12 Nov 2026 15:29:13 +0000 Subject: [PATCH] tools: mkcapsule builds warning-free -- the truncations impossible or handled (#143) The kernel build's only warnings were five -Wformat-truncation in mkcapsule's --resolve: two snprintf copies of a capsule name into the claim registry, and the capsule's path built from base_dir and its name. - The names: both are char[CAPSULE_NAME_MAX], and names are checked to fit when read (line 335) -- copied whole with memcpy, nothing to truncate. - The path: base_dir may be up to 4095 bytes, so it can be cut, and a cut path names another file -- now refused, the capsule left unchanged and counted rejected, with the reason. Seen to fail first: built with -Werror=format-truncation, 5 errors. After: 0, and 0 warnings with the kernel's flags; the manifest it writes is byte-identical, --lint passes. The too-long-path refusal is on --resolve's interactive conflict path and was not driven by a test. CLAUDE.md's count of open warnings corrected. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm --- .claude/CLAUDE.md | 5 +++-- tools/mkcapsule.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 5c2d482c..7c088bb6 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -466,8 +466,9 @@ status for kernel work. `TestCase.contract`/`WordTestSuite.suite_contract` trailing field, ~3,010 instances). Fixed in place across all 20 files (mechanical: added the missing `{0}` initializer, semantically a no-op since C99 already zero-fills unlisted trailing fields — the fix only silences the - diagnostic). Verified clean on all three architectures. Remaining, still-open warnings as of 2026-11-10: **5 `-Wformat-truncation`** in - `tools/mkcapsule.c` — corrected 2026-11-10; this file said 26 `-Wunused-parameter`, + diagnostic). Verified clean on all three architectures. Remaining, still-open warnings: **none** (2026-11-12, #143 -- the + 5 `-Wformat-truncation` in `tools/mkcapsule.c`, still open on 2026-11-10, are fixed: + same-sized name arrays copied whole, a path too long refused instead of cut) — corrected 2026-11-10; this file said 26 `-Wunused-parameter`, 2 `-Wsign-compare`, and 2 `-Wstringop-truncation` (the -Wunused-parameter and -Wsign-compare diagnostics were resolved since that audit). `tools/mkcapsule.c` is a host build tool compiled via plain `cc -Wall -Wextra -O2` (no `-Werror`). diff --git a/tools/mkcapsule.c b/tools/mkcapsule.c index 09329028..54f384fd 100644 --- a/tools/mkcapsule.c +++ b/tools/mkcapsule.c @@ -1272,7 +1272,7 @@ static int cmd_resolve(const char *dir) { if (!collides) { ClaimEntry *dest = prior ? prior : &claim_registry[claim_count++]; - snprintf(dest->name, CAPSULE_NAME_MAX, "%s", m->name); + memcpy(dest->name, m->name, CAPSULE_NAME_MAX); /* same-sized arrays: a whole copy, no truncation (#143) */ dest->hash = m->hash; dest->block_count = m->block_count; memcpy(dest->blocks, m->blocks, (size_t)m->block_count * sizeof(int)); @@ -1308,7 +1308,13 @@ static int cmd_resolve(const char *dir) { fprintf(stderr, " %d -> %d\n", m->blocks[j], m->blocks[j] + delta); } char fpath[MAX_PATH_LEN]; - snprintf(fpath, sizeof(fpath), "%s/%s", base_dir, m->name); + int flen = snprintf(fpath, sizeof(fpath), "%s/%s", base_dir, m->name); + if (flen < 0 || (size_t)flen >= sizeof(fpath)) { /* a cut path names another file (#143) */ + fprintf(stderr, " ERROR: the path of %s is longer than %d bytes -- left unchanged\n", + m->name, MAX_PATH_LEN - 1); + rejected++; + continue; + } /* capsule name uses ':' for subdirectories; the real path uses '/' */ for (char *p = fpath; *p; p++) if (*p == ':') *p = '/'; @@ -1321,7 +1327,7 @@ static int cmd_resolve(const char *dir) { delta, reason); for (int j = 0; j < m->block_count; j++) m->blocks[j] += delta; ClaimEntry *dest = prior ? prior : &claim_registry[claim_count++]; - snprintf(dest->name, CAPSULE_NAME_MAX, "%s", m->name); + memcpy(dest->name, m->name, CAPSULE_NAME_MAX); /* as below: same-sized arrays (#143) */ dest->hash = m->hash; dest->block_count = m->block_count; memcpy(dest->blocks, m->blocks, (size_t)m->block_count * sizeof(int));