[PR #2922] fix(filesystem): PRoot compatibility for sameRegularFileState #5495

Open
opened 2026-10-31 01:07:05 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2922
Author: @DaRedT
Created: 10/13/2026
Status: 🔄 Open

Base: main ← Head: fix/proot-sameregularfilestate


📝 Commits (10+)

  • ab200b2 fix(filesystem): PRoot compatibility for sameRegularFileState
  • aefa454 refactor(filesystem): clean up PRoot detection and add tests
  • 8f6e1a1 fix(filesystem): handle BigIntStats and cache PRoot detection
  • 55c4a45 test(filesystem): clean regular file temporary fixtures
  • 841483a fix(filesystem): detect proot-distro identity
  • b83c018 fix(filesystem): inspect actual proot mount field
  • c60e285 fix(filesystem): limit proot metadata tolerance to path checks
  • 5f5cedb test(filesystem): exercise proot comparison policy
  • 4afac1c test(filesystem): exercise PRoot path descriptor compatibility
  • e5c64fc fix(filesystem): normalize mixed mode masks safely

📊 Changes

12 files changed (+343 additions, -28 deletions)

View changed files

📝 src/android/AndroidTargetSnapshot.ts (+2 -1)
📝 src/application/BinaryTargetResolver.ts (+2 -1)
📝 src/application/RegularFileRead.ts (+2 -1)
📝 src/artifacts/MachOSliceArtifactReader.ts (+2 -1)
📝 src/artifacts/inventory/classify.ts (+5 -2)
📝 src/artifacts/inventory/hashStableRootArtifact.ts (+2 -1)
📝 src/filesystem/RegularFile.ts (+127 -16)
📝 src/filesystem/StableFileHash.ts (+2 -1)
📝 src/flutter/FlutterBuildProvider.ts (+2 -1)
📝 src/ghidra/GhidraPspExtension.ts (+2 -1)
📝 src/pcap/PcapSnapshot.ts (+3 -2)
➕ tests/process-global/regularFileProotCompatibility.test.ts (+192 -0)

📄 Description

Problem

Under PRoot (Termux on Android), stat() and fstat() return different values for the mode permission bits and ctime of the same file. Specifically:

  • mode: fstat() reports 0100400 while stat() reports 0100640 (permission bits differ)
  • ctime: timestamps differ by a few milliseconds due to PRoot's asynchronous inode updates

This causes sameRegularFileState() in StableFileHash.ts to return false incorrectly, which throws RegularFileChangedError and breaks all jadx-based Android analysis:

  • inspect_android_package
  • inspect_android_class
  • inspect_android_method

Error: Selected JADX input bytes changed during admission at .../ReaJadxBridge.java

Fix

Under PRoot (detected via /proc/version and /proc/self/mountinfo):

  1. Compare only the file-type bits of mode (S_IFMT mask 0o170000) instead of the full mode — permission bits are unreliable under PRoot
  2. Skip ctime comparison entirely — it is unstable between stat() and fstat() under PRoot

On non-PRoot hosts, behavior is unchanged — all fields including ctime and full mode are still compared.

dev, ino, size and mtime remain stable under PRoot and are always verified.

Testing

Tested with inspect-android-package on a 106MB APK under PRoot-Distro on Android:

  • Before: capability_unavailable error after ~7 seconds
  • After: Full analysis in ~2 seconds, 159 classes detected, manifest decoded

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/2922 **Author:** [@DaRedT](https://github.com/DaRedT) **Created:** 10/13/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/proot-sameregularfilestate` --- ### 📝 Commits (10+) - [`ab200b2`](https://github.com/morluto/rea/commit/ab200b2c8a0e987bd3919a53e8dd6c49cdc442f2) fix(filesystem): PRoot compatibility for sameRegularFileState - [`aefa454`](https://github.com/morluto/rea/commit/aefa454f0d56cc8965728539ea2babf20ad5ceab) refactor(filesystem): clean up PRoot detection and add tests - [`8f6e1a1`](https://github.com/morluto/rea/commit/8f6e1a130d227d6116de113ac4234164aa91aa09) fix(filesystem): handle BigIntStats and cache PRoot detection - [`55c4a45`](https://github.com/morluto/rea/commit/55c4a45afcc22687aa5af634d59ef17f47f7e4c1) test(filesystem): clean regular file temporary fixtures - [`841483a`](https://github.com/morluto/rea/commit/841483a2e8873febbdcfe8717c1e4fc8edb825e9) fix(filesystem): detect proot-distro identity - [`b83c018`](https://github.com/morluto/rea/commit/b83c018dc11b01e5ca7eda8a25917222dec46435) fix(filesystem): inspect actual proot mount field - [`c60e285`](https://github.com/morluto/rea/commit/c60e2854a7a9c3dc22954255a78d3e6b069e2eb2) fix(filesystem): limit proot metadata tolerance to path checks - [`5f5cedb`](https://github.com/morluto/rea/commit/5f5cedb39776ea4d54060bd5f03aaee86cd797a0) test(filesystem): exercise proot comparison policy - [`4afac1c`](https://github.com/morluto/rea/commit/4afac1cfcc9c84d1ae078ed4f7326dc82ec2d585) test(filesystem): exercise PRoot path descriptor compatibility - [`e5c64fc`](https://github.com/morluto/rea/commit/e5c64fc44a3943a1f2bb575c57ceeba6d66cc968) fix(filesystem): normalize mixed mode masks safely ### 📊 Changes **12 files changed** (+343 additions, -28 deletions) <details> <summary>View changed files</summary> 📝 `src/android/AndroidTargetSnapshot.ts` (+2 -1) 📝 `src/application/BinaryTargetResolver.ts` (+2 -1) 📝 `src/application/RegularFileRead.ts` (+2 -1) 📝 `src/artifacts/MachOSliceArtifactReader.ts` (+2 -1) 📝 `src/artifacts/inventory/classify.ts` (+5 -2) 📝 `src/artifacts/inventory/hashStableRootArtifact.ts` (+2 -1) 📝 `src/filesystem/RegularFile.ts` (+127 -16) 📝 `src/filesystem/StableFileHash.ts` (+2 -1) 📝 `src/flutter/FlutterBuildProvider.ts` (+2 -1) 📝 `src/ghidra/GhidraPspExtension.ts` (+2 -1) 📝 `src/pcap/PcapSnapshot.ts` (+3 -2) ➕ `tests/process-global/regularFileProotCompatibility.test.ts` (+192 -0) </details> ### 📄 Description ## Problem Under PRoot (Termux on Android), `stat()` and `fstat()` return different values for the `mode` permission bits and `ctime` of the same file. Specifically: - `mode`: `fstat()` reports `0100400` while `stat()` reports `0100640` (permission bits differ) - `ctime`: timestamps differ by a few milliseconds due to PRoot's asynchronous inode updates This causes `sameRegularFileState()` in `StableFileHash.ts` to return `false` incorrectly, which throws `RegularFileChangedError` and breaks all jadx-based Android analysis: - `inspect_android_package` - `inspect_android_class` - `inspect_android_method` Error: `Selected JADX input bytes changed during admission at .../ReaJadxBridge.java` ## Fix Under PRoot (detected via `/proc/version` and `/proc/self/mountinfo`): 1. Compare only the file-type bits of `mode` (`S_IFMT` mask `0o170000`) instead of the full `mode` — permission bits are unreliable under PRoot 2. Skip `ctime` comparison entirely — it is unstable between `stat()` and `fstat()` under PRoot On non-PRoot hosts, behavior is unchanged — all fields including `ctime` and full `mode` are still compared. `dev`, `ino`, `size` and `mtime` remain stable under PRoot and are always verified. ## Testing Tested with `inspect-android-package` on a 106MB APK under PRoot-Distro on Android: - Before: `capability_unavailable` error after ~7 seconds - After: Full analysis in ~2 seconds, 159 classes detected, manifest decoded --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5495
No description provided.