Summary
dkimf_add_signrequest() (opendkim/opendkim.c:4886) allocates up to ~135 KB of stack locals:
char keydata[MAXBUFRSZ + 1]; // 65,537 bytes
char tmpdata[MAXBUFRSZ + 1]; // 65,537 bytes (conditional branch)
char domain[DKIM_MAXHOSTNAMELEN + 1]; // 257
char selector[BUFRSZ + 1]; // 1,025
char signalgstr[BUFRSZ + 1]; // 1,025
char err[BUFRSZ + 1]; // 1,025
This function is called from within a libmilter callback thread via mlfi_eoh() → dkimf_apply_signtable() → dkimf_add_signrequest(), and also from Lua hooks via dkimf_xs_signfor() → dkimf_apply_signtable() → dkimf_add_signrequest().
Impact
On Linux, pthread_create defaults to an 8 MB thread stack, so this is harmless. On macOS ARM64, libmilter threads use the system default of 512 KB. With libmilter's own frames plus mlfi_eoh plus dkimf_apply_signtable plus 135 KB of locals in dkimf_add_signrequest, the total stack usage can exceed 512 KB, causing a SIGBUS or silent stack smash.
The symptom would be a crash during sign-mode operation whenever a key table is active and a message arrives that triggers dkimf_apply_signtable — i.e., normal production signing. The ___chkstk_darwin symbol would appear in a crash trace on Apple Silicon.
Fix
Convert keydata and tmpdata to heap allocations in dkimf_add_signrequest:
char *keydata = malloc(MAXBUFRSZ + 1);
// ... use keydata ...
free(keydata);
The existing keydatasz tracking already knows how much of keydata is live, so the heap transition is mechanical.
Related
- Adding a macOS CI job (see separate issue) will surface this reliably via the
t-sign-rs-tables and t-sign-rs-lua tests.
Summary
dkimf_add_signrequest()(opendkim/opendkim.c:4886) allocates up to ~135 KB of stack locals:This function is called from within a libmilter callback thread via
mlfi_eoh()→dkimf_apply_signtable()→dkimf_add_signrequest(), and also from Lua hooks viadkimf_xs_signfor()→dkimf_apply_signtable()→dkimf_add_signrequest().Impact
On Linux,
pthread_createdefaults to an 8 MB thread stack, so this is harmless. On macOS ARM64, libmilter threads use the system default of 512 KB. With libmilter's own frames plusmlfi_eohplusdkimf_apply_signtableplus 135 KB of locals indkimf_add_signrequest, the total stack usage can exceed 512 KB, causing aSIGBUSor silent stack smash.The symptom would be a crash during sign-mode operation whenever a key table is active and a message arrives that triggers
dkimf_apply_signtable— i.e., normal production signing. The___chkstk_darwinsymbol would appear in a crash trace on Apple Silicon.Fix
Convert
keydataandtmpdatato heap allocations indkimf_add_signrequest:The existing
keydatasztracking already knows how much ofkeydatais live, so the heap transition is mechanical.Related
t-sign-rs-tablesandt-sign-rs-luatests.