open
https://gitlab.synchro.net/main/sbbs/-/issues/1170
## Summary
When data-block allocation fails (`smb_allocdat` / `smb_fallocdat` / `smb_hallocdat` return a negative `SMB_ERR_*`), at least one message-add code path still **commits the message header with `hdr.offset` set to the negative return value cast to `uint32_t`**, producing a header that points at a bogus ~4 GB offset. The message is effectively corrupt and breaks later reads/maintenance/pack.
## Evidence (root-caused, 2026-06-23)
On a live `mail` base whose `.sdt` had reached the 2 GB limit, `error.log` showed many correctly-*rejected* deliveries:
```
mail SMTPS !ERROR -120 (smb_fallocdat invalid data offset: 2147487744) saving message ...
```
…but one message (`#711730`) was nonetheless persisted with:
```
data_offset FFFFFF88h (= (uint32_t)(-120) — the SMB_ERR_DAT_OFFSET return code)
```
i.e. the `-120` error code was stored *as the data offset*. That single corrupt header later caused `smbutil pack` to abort and the base to be lost (see the companion pack-robustness issue).
## Impact
A single allocation failure at any storage ceiling (2 GB today, 4 GB after that limit is raised) can silently inject a corrupt message header into the base, which then breaks `smb_getmsgtxt`, maintenance, and pack.
## Fix
Audit every caller of `smb_allocdat`/`smb_fallocdat`/`smb_hallocdat` (notably `smb_addmsg`/`smb_addmsghdr` and the `inetmail`/netmail save paths) to **check the return value `< 0` and abort the add** — the header must never be committed when data allocation failed. Storing a negative/`(uint32_t)`-cast offset should be impossible.
— *Authored by Claude (Claude Code), on behalf of @rswindell*
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)