Skip to content

fix(devel): close va_list on every path in homa_snprintf - #101

Open
randomizedcoder wants to merge 1 commit into
PlatformLab:mainfrom
randomizedcoder:fix/snprintf-va-end
Open

randomizedcoder wants to merge 1 commit into
PlatformLab:mainfrom
randomizedcoder:fix/snprintf-va-end

Conversation

@randomizedcoder

Copy link
Copy Markdown

Bug: va_list opened but never closed in homa_snprintf()

int homa_snprintf(char *buffer, int size, int used, const char *format, ...)
{
	int new_chars;
	va_list ap;

	va_start(ap, format);        /* opened here... */

	if (used >= (size - 1))
		return used;             /* ...but no va_end on this path */

	new_chars = vsnprintf(buffer + used, size - used, format, ap);
	if (new_chars < 0)
		return used;             /* ...or this one */
	...
}

va_start(ap, format) is executed at the top of the function, but none of the four return paths call va_end(ap). The C standard requires every va_start to be paired with a matching va_end before the function returns; omitting it is undefined behavior and leaks the va_list on ABIs where va_start allocates. It happens to be a no-op on the x86-64 SysV ABI, which is why nothing fails at runtime on this platform — but it is still a portability/correctness defect.

Fix

Open the va_list immediately before its only use and close it right after, so no early return can escape it:

-	va_start(ap, format);
-
 	if (used >= (size - 1))
 		return used;

+	va_start(ap, format);
 	new_chars = vsnprintf(buffer + used, size - used, format, ap);
+	va_end(ap);
 	if (new_chars < 0)
 		return used;

Verification (static gate + regression)

Before:  homa_devel.c:490:14: error: va_list 'ap' was opened but not closed
         by va_end(). [va_end_missing]
After:   (clean — finding gone)

cppcheck --enable=all homa_devel.c. There is no runtime gate for this one: a missing va_end is a no-op on the x86-64 SysV ABI, so no unit test can observe it failing on this host — the authoritative red→green signal is the cppcheck va_end_missing finding flipping from present to absent. The existing homa_snprintf behavior is unchanged; the homa_utils regression stays green (12/12).

homa_snprintf() called va_start(ap, format) at the top of the function
but never called va_end(ap) on any of its return paths. The C standard
requires each va_start to be paired with a va_end before the function
returns; skipping it is undefined behavior and leaks the va_list on ABIs
where va_start allocates (it is a no-op on the x86-64 SysV ABI, which is
why no runtime failure is observed on this platform).

Move va_start to just before the sole vsnprintf() call and va_end
immediately after, so the va_list is opened and closed in one place and
no early return can escape it.

Gate: cppcheck --enable=all flags this as va_end_missing at
homa_devel.c:490 before the fix and reports it clean after. The existing
homa_snprintf unit regression stays green (test/unit homa_utils: 12/12).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant