You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OpenIPC runs vendor-prebuilt .so libraries (from HiSilicon, Sigmastar, Ingenic, Goke, Rockchip, etc) that were compiled against uclibc or old glibc, but the firmware uses musl libc. Key ABI differences cause:
Link failures — vendor binary imports a symbol musl doesn't export (__ctype_b, __fgetc_unlocked, __assert, memcpy_s, etc.)
Silent data corruption — same function exists in both but struct layouts differ:
off_t: uclibc=4 bytes vs musl=8 bytes (breaks mmap calling convention on ARM — offset argument shifts registers)
struct timespec: uclibc=8 bytes vs musl=16 bytes (breaks nanosleep, clock_gettime)
The existing libhisicompat for hi3516cv100 was a narrow hack discovered by chance from a crash (only wrapped st_mode via a custom sTaT symbol). We need a systematic approach.
Audit tool
A new general/scripts/audit-vendor-abi.py performs two definitive checks (no guessing):
Symbol check: extracts every imported symbol from vendor .so files and checks whether the platform's actual musl libc.so exports it
Struct probe: compiles a C program with the platform's musl cross-compiler, runs it under qemu, and gets exact sizeof/offsetof for every struct that crosses the vendor-musl boundary
Scanned 492 binaries across 15 packages (platforms with available toolchains):
Package
Arch
Source libc
Missing symbols
Struct mismatches
fullhan-osdrv-fh8852v100
ARM
uclibc
8 (__assert, __fgetc_unlocked, __stdin, ...)
off_t, time_t
fullhan-osdrv-fh8852v200
ARM
uclibc
6 (__assert, __fgetc_unlocked, __stdin, ...)
off_t
goke-osdrv-gk7205v200
ARM
uclibc
8 (__ctype_b, memcpy_s, memset_s, ...)
off_t, timespec
goke-osdrv-gk7205v500
ARM
uclibc
8 (memcpy_s, memset_s, snprintf_s, ...)
off_t
hisilicon-osdrv-hi3516av100
ARM
uclibc
0
off_t, timespec
hisilicon-osdrv-hi3516cv100
ARM
uclibc
1 (__aeabi_d2iz)
struct stat, off_t
hisilicon-osdrv-hi3516cv200
ARM
uclibc
7 (__aeabi_f2d, __aeabi_fmul, ...)
off_t, timespec
hisilicon-osdrv-hi3516cv300
ARM
uclibc
0
off_t, timespec
hisilicon-osdrv-hi3516ev200
ARM
uclibc
11 (__ctype_b, memcpy_s, snprintf_s, ...)
off_t, timespec
hisilicon-osdrv-hi3519v101
ARM
uclibc
0
off_t, timespec, time_t
ingenic-osdrv-t20
MIPS
unknown
11 (__assert, __ctype_b, __fgetc_unlocked, ...)
(no qemu-mips)
ingenic-osdrv-t21
MIPS
unknown
11 (same)
(no qemu-mips)
ingenic-osdrv-t31
MIPS
unknown
5 (__assert, __fgetc_unlocked, ...)
(no qemu-mips)
ingenic-osdrv-t40
MIPS
unknown
5 (same)
(no qemu-mips)
xiongmai-osdrv-xm530
ARM
uclibc
0
off_t
Platforms with stat-family struct mismatch
15 vendor binaries across 8 packages import stat/fstat/stat64 — uclibc struct stat is 88 bytes, musl's is 152, with completely different field offsets. This causes stack corruption when musl writes 152 bytes into an 88-byte buffer:
Problem
OpenIPC runs vendor-prebuilt
.solibraries (from HiSilicon, Sigmastar, Ingenic, Goke, Rockchip, etc) that were compiled against uclibc or old glibc, but the firmware uses musl libc. Key ABI differences cause:__ctype_b,__fgetc_unlocked,__assert,memcpy_s, etc.)struct stat: uclibc=88 bytes vs musl=152 bytes (field offsets completely different)off_t: uclibc=4 bytes vs musl=8 bytes (breaksmmapcalling convention on ARM — offset argument shifts registers)struct timespec: uclibc=8 bytes vs musl=16 bytes (breaksnanosleep,clock_gettime)The existing
libhisicompatfor hi3516cv100 was a narrow hack discovered by chance from a crash (only wrappedst_modevia a customsTaTsymbol). We need a systematic approach.Audit tool
A new
general/scripts/audit-vendor-abi.pyperforms two definitive checks (no guessing):.sofiles and checks whether the platform's actual musllibc.soexports itsizeof/offsetoffor every struct that crosses the vendor-musl boundaryThe tool auto-downloads the correct per-platform toolchain from OpenIPC firmware releases.
Audit results
Scanned 492 binaries across 15 packages (platforms with available toolchains):
__assert,__fgetc_unlocked,__stdin, ...)off_t,time_t__assert,__fgetc_unlocked,__stdin, ...)off_t__ctype_b,memcpy_s,memset_s, ...)off_t,timespecmemcpy_s,memset_s,snprintf_s, ...)off_toff_t,timespec__aeabi_d2iz)struct stat,off_t__aeabi_f2d,__aeabi_fmul, ...)off_t,timespecoff_t,timespec__ctype_b,memcpy_s,snprintf_s, ...)off_t,timespecoff_t,timespec,time_t__assert,__ctype_b,__fgetc_unlocked, ...)__assert,__fgetc_unlocked, ...)off_tPlatforms with
stat-family struct mismatch15 vendor binaries across 8 packages import
stat/fstat/stat64— uclibcstruct statis 88 bytes, musl's is 152, with completely different field offsets. This causes stack corruption when musl writes 152 bytes into an 88-byte buffer:Reference: majestic's existing workaround
majestic/src/libc/uclibc.c already handles
mmap(raw SYS_mmap2 syscall),fcntl64,__ctype_b,__isnan/__isinf,__fgetc_unlocked/__fputc_unlocked,__assert, and_stdlib_mb_cur_max. The approach proven in production.Per-platform roadmap
Struct layout mismatches (silent corruption)
struct stat(uclibc=88B, musl=152B):off_t(uclibc=4B, musl=8B) — breaksmmapon ARM:Missing symbols (link failures)
__ctype_b,__fgetc_unlocked,_stdlib_mb_cur_max,memcpy_s/memset_s/snprintf_sfamily__ctype_b,__fgetc_unlocked,_stdlib_mb_cur_max,memcpy_sfamily__assert,__fgetc_unlocked,__stdin,__pthread_*__assert,__fgetc_unlocked,__stdin__assert,__ctype_b,__fgetc_unlocked,__pthread_*Call for testing
Maintainers with access to affected hardware: please run the audit tool on your platform and report results:
The tool will auto-download the correct toolchain (~100MB, cached in
~/.cache/openipc-audit-toolchains/).