Fix statx byte order on big-endian guests by retrocpugeek · Pull Request #1634 · qilingframework/qiling · GitHub
Skip to content

Fix statx byte order on big-endian guests#1634

Open
retrocpugeek wants to merge 2 commits into
qilingframework:devfrom
retrocpugeek:fix/statx-bigendian
Open

Fix statx byte order on big-endian guests#1634
retrocpugeek wants to merge 2 commits into
qilingframework:devfrom
retrocpugeek:fix/statx-bigendian

Conversation

@retrocpugeek

Copy link
Copy Markdown

What

Fixes statx returning a byte-swapped struct statx on big-endian guests.

ql_syscall_statx always serialized the result with the little-endian Statx32 / Statx64 (ctypes.Structure), regardless of guest endianness. Every other stat-family struct in stat.py already has a big-endian variant selected via ql.arch.endian; statx was the only one missing it. On a big-endian guest this byte-swaps every field — most visibly stx_mode, which loses its S_IFDIR bit, so a directory looks like a plain file (e.g. busybox ls / prints the path name instead of listing it). Modern glibc routes stat/fstatat through statx, so this affects ordinary directory operations, not just direct statx callers.

Closes #1633.

How

  • Add Statx32EB / Statx64EB (and StatxTimestamp32EB / StatxTimestamp64EB) as ctypes.BigEndianStructure, reusing the little-endian field layouts.
  • Select the big-endian variants in ql_syscall_statx when ql.arch.endian == QL_ENDIAN.EB.
  • The little-endian path is byte-for-byte unchanged.

Test

test_elf.ELFTest.test_linux_statx_bigendian drives ql_syscall_statx on a big-endian MIPS context and checks that stx_mode, read back in the guest's byte order, still reports a directory. It is self-contained (no rootfs binary, runs on stock unicorn) and fails on dev (AssertionError), passes with this fix.

Checklist

  • This PR only contains minor fixes.
  • The new code conforms to Qiling Framework naming convention.
  • Essential comments are added.
  • I have added enough tests for this PR.
  • The target branch is dev branch.

retrocpugeek and others added 2 commits June 25, 2026 00:15
Statx32/Statx64 (and their StatxTimestamp structs) were defined only as
little-endian ctypes.Structure, and ql_syscall_statx used them regardless
of guest endianness. Every other stat-family struct already has an explicit
big-endian variant selected by ql.arch.endian; statx was the lone gap.

On a big-endian guest (e.g. MIPS/MIPS64 EB) this byte-swaps every statx
field. In particular stx_mode loses its S_IFDIR bit, so a directory looks
like a plain file and `busybox ls /` just echoes the argument instead of
listing the directory.

Add Statx{32,64}EB / StatxTimestamp{32,64}EB (ctypes.BigEndianStructure,
reusing the little-endian field layouts) and pick them when the guest is
big-endian. The little-endian path is byte-for-byte unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drives ql_syscall_statx on a big-endian MIPS context and checks that
stx_mode, read back in the guest's byte order, still reports a directory
(S_IFDIR). Before the fix the statx struct was emitted little-endian
regardless of guest endianness, so the type bits were byte-swapped and a
directory looked like a regular file. Self-contained (no rootfs binary,
runs on stock unicorn).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant