Bug 296515 - devel/tbox: fix data corruption in tb_ralloc() crossing the 128 KiB mmap threshold
Summary: devel/tbox: fix data corruption in tb_ralloc() crossing the 128 KiB mmap thre...
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Robert Clausecker
URL: https://github.com/tboox/tbox/pull/315
Keywords:
Depends on:
Blocks:
 
Reported: 2026-07-04 14:12 UTC by Lin
Modified: 2026-07-05 14:59 UTC (History)
1 user (show)

See Also:
bugzilla: maintainer-feedback? (fuz)
lin: merge-quarterly?


Attachments
devel/tbox: fix + PORTREVISION bump (2.72 KB, patch)
2026-07-04 14:14 UTC, Lin
no flags Details | Diff
standalone reproducer (1001 bytes, text/plain)
2026-07-04 14:15 UTC, Lin
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Lin 2026-07-04 14:12:36 UTC
devel/tbox 1.8.0's tb_native_large_allocator_ralloc() corrupts data when a
reallocation crosses TB_VIRTUAL_MEMORY_DATA_MINN (128 KiB) in either
direction. In the malloc<->mmap crossover paths the block is copied with

    tb_memcpy_(data, data_head, base_head->size);

The copy starts at the block header (data_head) but the length is the payload
size only. On grow, the last sizeof(tb_native_large_data_head_t) (24) bytes
of user data are silently lost; on shrink, the copy overruns the smaller
destination allocation (heap buffer overflow).

User-visible fallout: devel/xmake-io is completely broken — its Lua loader
reads script files through a tb_buffer, and for any file > 64 KiB the growth
rallocs 65536 -> 131072 across the threshold. The tail of interpreter.lua
comes back corrupted and every xmake invocation fails with a bogus
"syntax error" at the line spanning byte 65536.

Also reproduced on Linux/amd64 with a full tbox build (--small=no): identical
corruption at bytes 65512..65535. Small-mode builds are unaffected because
tb_init() selects tb_native_allocator() instead of the pooled allocator,
which is why xmake's bundled tbox never hits this path and the bug went
unnoticed upstream.

Fix: copy the header plus min(old, new) payload in both crossover paths.
Accepted upstream as https://github.com/tboox/tbox/pull/315

Testing on 15.1-RELEASE amd64: minimal repro (attached) fails before /
passes after; with the patched library the unmodified xmake-io package works
(xmake --version, project create/build/run). PORTREVISION bumped.
Comment 1 Lin 2026-07-04 14:14:12 UTC
Created attachment 272487 [details]
devel/tbox: fix + PORTREVISION bump
Comment 2 Lin 2026-07-04 14:15:44 UTC
Created attachment 272488 [details]
standalone reproducer
Comment 3 Robert Clausecker freebsd_committer freebsd_triage 2026-07-04 14:16:28 UTC
Thank you for the report.
This seems like a sensible thing to fix.

Instead of taking your patch, I'll directly apply upstream's patch from here:

    https://github.com/tboox/tbox/commit/d9e08d25be440062b30c4fe31bf602fd048ab354

This is generally preferred
Comment 4 commit-hook freebsd_committer freebsd_triage 2026-07-05 08:14:06 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/ports/commit/?id=93314da38421ae41249ec9bd3b265afecbf1b48d

commit 93314da38421ae41249ec9bd3b265afecbf1b48d
Author:     Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2026-07-04 14:18:23 +0000
Commit:     Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2026-07-05 08:12:50 +0000

    devel/tbox: fix data corruption in tb_ralloc() crossing the 128 KiB mmap threshold

    devel/tbox 1.8.0's tb_native_large_allocator_ralloc() corrupts data when a
    reallocation crosses TB_VIRTUAL_MEMORY_DATA_MINN (128 KiB) in either
    direction. In the malloc<->mmap crossover paths the block is copied with

        tb_memcpy_(data, data_head, base_head->size);

    The copy starts at the block header (data_head) but the length is the payload
    size only. On grow, the last sizeof(tb_native_large_data_head_t) (24) bytes
    of user data are silently lost; on shrink, the copy overruns the smaller
    destination allocation (heap buffer overflow).

    User-visible fallout: devel/xmake-io is completely broken — its Lua loader
    reads script files through a tb_buffer, and for any file > 64 KiB the growth
    rallocs 65536 -> 131072 across the threshold. The tail of interpreter.lua
    comes back corrupted and every xmake invocation fails with a bogus
    "syntax error" at the line spanning byte 65536.

    Also reproduced on Linux/amd64 with a full tbox build (--small=no): identical
    corruption at bytes 65512..65535. Small-mode builds are unaffected because
    tb_init() selects tb_native_allocator() instead of the pooled allocator,
    which is why xmake's bundled tbox never hits this path and the bug went
    unnoticed upstream.

    Fix: copy the header plus min(old, new) payload in both crossover paths.
    Accepted upstream as https://github.com/tboox/tbox/pull/315

    See also:       https://github.com/tboox/tbox/pull/315
    Reported by:    Lin <lin@sz.cn.eu.org>
    PR:             296515
    MFH:            2026Q2

 devel/tbox/Makefile | 4 ++++
 devel/tbox/distinfo | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)
Comment 5 commit-hook freebsd_committer freebsd_triage 2026-07-05 08:15:07 UTC
A commit in branch 2026Q2 references this bug:

URL: https://cgit.FreeBSD.org/ports/commit/?id=4ae1270edfd60e399d5eac2d09cdd9c57b1223c5

commit 4ae1270edfd60e399d5eac2d09cdd9c57b1223c5
Author:     Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2026-07-04 14:18:23 +0000
Commit:     Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2026-07-05 08:13:45 +0000

    devel/tbox: fix data corruption in tb_ralloc() crossing the 128 KiB mmap threshold

    devel/tbox 1.8.0's tb_native_large_allocator_ralloc() corrupts data when a
    reallocation crosses TB_VIRTUAL_MEMORY_DATA_MINN (128 KiB) in either
    direction. In the malloc<->mmap crossover paths the block is copied with

        tb_memcpy_(data, data_head, base_head->size);

    The copy starts at the block header (data_head) but the length is the payload
    size only. On grow, the last sizeof(tb_native_large_data_head_t) (24) bytes
    of user data are silently lost; on shrink, the copy overruns the smaller
    destination allocation (heap buffer overflow).

    User-visible fallout: devel/xmake-io is completely broken — its Lua loader
    reads script files through a tb_buffer, and for any file > 64 KiB the growth
    rallocs 65536 -> 131072 across the threshold. The tail of interpreter.lua
    comes back corrupted and every xmake invocation fails with a bogus
    "syntax error" at the line spanning byte 65536.

    Also reproduced on Linux/amd64 with a full tbox build (--small=no): identical
    corruption at bytes 65512..65535. Small-mode builds are unaffected because
    tb_init() selects tb_native_allocator() instead of the pooled allocator,
    which is why xmake's bundled tbox never hits this path and the bug went
    unnoticed upstream.

    Fix: copy the header plus min(old, new) payload in both crossover paths.
    Accepted upstream as https://github.com/tboox/tbox/pull/315

    See also:       https://github.com/tboox/tbox/pull/315
    Reported by:    Lin <lin@sz.cn.eu.org>
    PR:             296515
    MFH:            2026Q2

    (cherry picked from commit 93314da38421ae41249ec9bd3b265afecbf1b48d)

 devel/tbox/Makefile | 4 ++++
 devel/tbox/distinfo | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)
Comment 6 Robert Clausecker freebsd_committer freebsd_triage 2026-07-05 08:16:05 UTC
Thank you for your report!