Skip to content

Fix the build and make check on 32bit platforms - #548

Open
nook24 wants to merge 5 commits into
naemon:masterfrom
nook24:fix-32bit
Open

nook24 wants to merge 5 commits into
naemon:masterfrom
nook24:fix-32bit

Conversation

@nook24

@nook24 nook24 commented Sep 29, 2026

Copy link
Copy Markdown
Member

The Debian 11/12 i386 packages build with -Werror, but make check has not passed on 32 bit for a while: two tests did not compile, which hid three failures behind them. Two of those were real bugs, not test problems.

With this PR make check passes on Debian 11 and 12 i386 and still passes on amd64.

Bugs

libnaemon replaced asprintf()/vasprintf() on every platform. configure never checked for them, so lib/snprintf.c always compiled its replacements, and libnaemon exported them ahead of libc. They are built on an old vsnprintf() that has no z, j or t modifier and, without HAVE_LONG_LONG, reads %ll as long. nm_asprintf(), nm_log() and nsock_printf() all go through it:

glibc libnaemon i386 libnaemon amd64
%llu;%llu ok second value 0 ok
%lld ok garbage ok
%zd ok fails, returns -1 fails, returns -1

On i386 this sent SCHEDULE_HOST_DOWNTIME with an end time of 0 in test_commands. On every platform, nm_log() silently drops any message that uses %z, such as the wproc parse error in workers.c, and nm_asprintf() would exit(2) on one. Builds with -D_FORTIFY_SOURCE=2 call __vasprintf_chk() and skip the replacement, which is why the Debian packages (hardening=+all) never showed it. Unfortified builds, and NEB modules built without FORTIFY that call asprintf(), are affected. The fix adds asprintf and vasprintf to AC_CHECK_FUNCS. smb_snprintf()/smb_vsnprintf() stay exported so the library ABI does not shrink.

Timeperiod searches ran past the end of time_t. A 24x7 exclusion appears to end at every DST change. For a timeperiod that is never valid, _get_next_valid_time() therefore hops half a year at a time until max_depth. With a 32 bit time_t that goes past 2038, midnight + SECS_PER_DAY wraps to 1901, and the search returns that as the next valid time. That is a check scheduled in 1901, i.e. immediately. Both searches now stop a day before time_t runs out.

Tests

  • test-bufferqueue: used unsigned long for a size_t * and %ld for size_t. It did not compile on i386.
  • test-event-heap: runnable_delays held values that do not fit a 32 bit time_t, so it did not compile. event_timespec_msdiff expected an exact value where timespec_msdiff() correctly saturates a 32 bit long.
  • test-arith: on overflow it asserted dest != a + b. But a + b overflows too, and the builtins store exactly that value. With a 64 bit long the branch never ran. It now compares against the long long result.

The first two commits are also part of #547, with the same SHAs, so whichever PR is merged first, the other just drops them.

Not fixed here

t-tap/test_commands fails now and then on every platform in the SCHEDULE_*_CHECK(S) next_check assertions (about 2 in 40 runs, on amd64 as well as i386). It is unrelated to 32 bit and has been left alone

nook24 and others added 5 commits September 29, 2026 11:07
nm_bufferqueue_unshift_to_delim() takes a size_t *, but the test passed
an unsigned long * and printed size_t values with %ld. Both only happen
to match on 64 bit Linux; on i386 the test fails to compile with -Werror.

Signed-off-by: nook24 <info@nook24.eu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WY8mbGLNkt5eQfc57cTnZ5
runnable_delays held values that do not fit a 32 bit time_t, which
fails the -Werror build; those are now skipped. event_timespec_msdiff
expected 2^31 seconds to come back exactly, but in milliseconds that
saturates a 32 bit long, as timespec_msdiff() is meant to.

Signed-off-by: nook24 <info@nook24.eu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WY8mbGLNkt5eQfc57cTnZ5
configure never checked for them, so lib/snprintf.c always compiled its
replacements and libnaemon exported them, ahead of libc in the symbol
lookup order. They sit on an old vsnprintf() that does not know the z,
j and t modifiers and, without HAVE_LONG_LONG, reads %ll as long.

nm_asprintf(), nm_log() and nsock_printf() all went through it. On i386
%llu printed garbage, which is why SCHEDULE_HOST_DOWNTIME got an end
time of 0 in test_commands. On every platform %z makes it fail, so
nm_log() drops the wproc parse error in workers.c and nm_asprintf()
would exit(2). Builds with _FORTIFY_SOURCE=2, like
the Debian packages, call __vasprintf_chk() instead and never noticed.

smb_snprintf() and smb_vsnprintf() are still exported, just unused.

Signed-off-by: nook24 <info@nook24.eu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WY8mbGLNkt5eQfc57cTnZ5
The random loops asserted that on overflow the result differs from a + b,
but a + b overflows there too, and the builtins store exactly that
wrapped value. With a 64 bit long random() never overflows, so the
branch only ran on 32 bit, where it failed. Compare against the long
long result instead, which checks that overflow is detected at all.

Signed-off-by: nook24 <info@nook24.eu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WY8mbGLNkt5eQfc57cTnZ5
A 24x7 exclusion looks like it ends at every DST change, so for a
timeperiod that is never valid _get_next_valid_time() hops from one
change to the next, half a year at a time, until max_depth. With a 32
bit time_t that runs past 2038, midnight + SECS_PER_DAY wraps to 1901
and the search returns that as the next valid time; test_timeperiods
failed on i386 because of it.

Both searches now stop a day before time_t runs out: nothing valid is
found, and a period still valid there stays valid to the end.

Signed-off-by: nook24 <info@nook24.eu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WY8mbGLNkt5eQfc57cTnZ5
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.

2 participants