uclibc-compat: fix struct stat overflow on old uClibc SoCs (hi3516cv100 VDA)#2194
Merged
Merged
Conversation
…ap; drop build outputs The static shim's stat() did a raw fstatat64, writing the 104-byte kernel struct stat64 into the caller's buffer. Vendor libmpi on the oldest HiSilicon SoCs (Hi3518 V100 / hi3516cv100, Hi3516A V100) was built against uClibc 0.9.32, where struct stat is the non-LFS 88-byte layout, so it reserves an 88-byte stack buffer. The 104-byte write overflowed it by 16 bytes and clobbered the adjacent VDA_CHN_ATTR_S pointer in HI_MPI_VDA_CreateChn's stat()+S_ISCHR() device probe -> ERR_VDA_NULL_PTR (0xa0098006); hardware motion detection never started. Fix stat/lstat/fstat to translate into the 88-byte uClibc layout for CHARACTER DEVICE nodes only (the device-identity fields the vendor reads -- st_mode, st_rdev -- share offsets across all layouts, and 88 <= 96/104 never overflows any vendor buffer). Regular-file and musl-internal stats keep the raw kernel layout, so nothing else changes on any SoC. Also make pick_offset() prefer the vendor slot (SP+4): the uClibc 32-bit offset is always page-aligned, so vendor register/MMZ mmaps are now deterministic. The previous "prefer SP+8" heuristic mis-mapped a register page whenever the SP+8 garbage was page-aligned, which reliably aborted VI/ISP init on hi3516cv100. musl callers still fall through to SP+8 when SP+4 is non-aligned padding, so the LVGL fbdev fix is preserved. Validated end-to-end on hi3516cv100: HI_MPI_VDA_CreateChn succeeds, VDA motion detection runs, no external abort. Stop tracking build outputs (*.o/*.a/*.so were left in src/); add a .gitignore. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On the oldest HiSilicon SoCs (Hi3518 V100 / hi3516cv100, Hi3516A V100) the vendor
libmpi.sowas built in 2015 against uClibc 0.9.32, wherestruct statis the non-LFS 88‑byte layout. Such code reserves an 88‑byte stack buffer.The
uclibc-compatstaticstat()shim did a rawfstatat64, writing the 104‑byte kernelstruct stat64straight into the caller's buffer. InHI_MPI_VDA_CreateChn'sstat()+S_ISCHR()probe of its register device node, that overflows the 88‑byte buffer by 16 bytes and clobbers the adjacentVDA_CHN_ATTR_Spointer →ERR_VDA_NULL_PTR(0xa0098006). Hardware (VDA) motion detection never started on these chips.Fix
stat/lstat/fstat: translate the kernel struct into the 88‑byte uClibc layout for character‑device nodes only. The device‑identity fields vendor code actually reads (st_mode@16,st_rdev@32) sit at identical offsets across the 88/96/104‑byte layouts, and88 <= 96/104never overflows any vendor buffer. Regular‑file and musl‑internal stats keep the raw kernel layout, so nothing else changes on any SoC.mmap:pick_offset()now prefers the vendor slot (SP+4) — the uClibc 32‑bit offset is always page‑aligned, so vendor register/MMZ mmaps are deterministic. The previous "prefer SP+8" heuristic mis‑mapped a register page whenever the SP+8 garbage was page‑aligned, which reliably aborted VI/ISP init on hi3516cv100 (external abort). musl callers still fall through to SP+8 when SP+4 is non‑aligned padding, so the LVGL fbdev fix is preserved.*.o/*.a/*.sowere left insrc/); add a.gitignore.Validation
Built with the hi3516cv100 toolchain and validated end‑to‑end on real hardware:
HI_MPI_VDA_CreateChnsucceeds, VDA motion detection runs (motion events + per‑MB metrics), and there is no external abort during VI/ISP init. Newer SoCs are unaffected (regular‑file stats and the dual‑ABI mmap path are unchanged for them).Refs: #1992
🤖 Generated with Claude Code