[BUG] libhoudini built-in license expiry (Sept 2026 wave): ARM apps (Arknights etc.) crash on launch / hang at splash on x86_64 Waydroid; system rollback does not help; rolling back the date reproduces and fixes it #285

Closed
opened 2026-09-02 02:14:29 -04:00 by lycegg · 3 comments
lycegg commented 2026-09-02 02:14:29 -04:00 (Migrated from github.com)

Environment

  • Arch Linux / KDE Plasma, x86_64 (i9-14900)
  • Waydroid Android 13 (ro.build.version.release=13, sdk=33), image lineage-20.0 VANILLA (system.img build 20260403)
  • Translation layer: waydroid_script's libhoudini (WSA build) — stable for 2 months; later replaced with hpe-14 (14.0.0b_y.GoogleGame_com1.2, extracted from Google Play Games image UKW1.251130.001)
  • Test app: Arknights 2.7.61 (arm64-only, installed via adb install --abi arm64-v8a)

Symptom

Since 2026-09-02, ARM apps fail at launch on a setup that had been running fine for 2 months:

  • Old WSA houdini build: hangs at the splash screen (process alive but unresponsive)
  • hpe-14: process disappears within seconds of launch (crash; stale window frame remains)
  • Waydroid itself and x86 apps work normally

Key experiment: the failure follows the DATE, not any system state

  1. Rolled back host / and /home subvolumes to two days prior → no effect (rules out system/config/container-data changes)
  2. Booted the LTS kernel → no effect (rules out /boot, kernel, binder-related regressions)
  3. Set host date back to 2026-08-30 → game launches and works. Restored real date (09-02) → crashes again at launch
    • Repro: sudo timedatectl set-ntp false && sudo date -s "2026-08-30 12:00:00" → sudo waydroid container restart → launch app → works
  4. Conclusion: nothing is corrupted — the failure is purely that the clock crossed a built-in deadline

Diagnosis: libhoudini built-in license expiry (ibt_get_expire_date)

Binary inspection of hpe-14's /system/lib64/libhoudini.so (9,323,480 bytes):

  • Symbol table contains ibt_get_expire_date (Intel Binary Translator's expiry query function)
  • The file contains the little-endian constant 1788134400 = 2026-08-31 00:00:00 UTC (appears twice), matching the observed boundary (works on 08-30, fails on/after 09-01)

Historical comparison (same mechanism, different per-build dates):

  • Jan 2026: a wave of identical reports — waydroid/waydroid#2091, waydroid-helper#78; reverse engineering found an expire_date function with timestamp 1767227429 = 2026-01-01 (chrhasse)
  • This old WSA build (~Dec 2025) expires at ≈ 2026-09-02 00:00 UTC, exactly matching "worked all of Sep 1, broken on the morning of Sep 2"
  • Hypothesis: Intel embeds an ~9-month license window in every libhoudini build; every build is effectively a time bomb
  • chromeos_octopus(39598) also contains ibt_get_expire_date — not a clean alternative

Lesson learned (already reverted on my side)

Attempting to patch the constant directly (4 bytes × 2 sites → 2030) caused Waydroid to hang in an infinite boot animation — the expiry check sits in code executed when zygote loads the native bridge early at boot. Blind binary patching is not viable; it needs disassembly-guided patching (as chrhasse did) or an official expiry-free build.

Request

  • An expiry-free patched build of libhoudini (like wsa11-patched / brya-patched, but current enough for Android 13 + recent game versions)
  • Or libhoudini extracted from a newer Google Play Games (HPE) image (newer build = newer license window)
  • Or confirmation of whether any build (e.g. ChromeOS-derived) actually has no expiry check

Impact: all x86_64 Waydroid users still running libhoudini builds whose embedded expiry date has passed since 2026-09-02 (this should already be hitting many users worldwide this month).

https://github.com/waydroid-helper/waydroid-helper/issues/127 has the same problem.

## Environment - Arch Linux / KDE Plasma, x86_64 (i9-14900) - Waydroid Android 13 (ro.build.version.release=13, sdk=33), image lineage-20.0 VANILLA (system.img build 20260403) - Translation layer: waydroid_script's libhoudini (WSA build) — stable for 2 months; later replaced with hpe-14 (14.0.0b_y.GoogleGame_com1.2, extracted from Google Play Games image UKW1.251130.001) - Test app: Arknights 2.7.61 (arm64-only, installed via `adb install --abi arm64-v8a`) ## Symptom Since 2026-09-02, ARM apps fail at launch on a setup that had been running fine for 2 months: - Old WSA houdini build: hangs at the splash screen (process alive but unresponsive) - hpe-14: process disappears within seconds of launch (crash; stale window frame remains) - Waydroid itself and x86 apps work normally ## Key experiment: the failure follows the DATE, not any system state 1. Rolled back host `/` and `/home` subvolumes to two days prior → no effect (rules out system/config/container-data changes) 2. Booted the LTS kernel → no effect (rules out /boot, kernel, binder-related regressions) 3. **Set host date back to 2026-08-30 → game launches and works.** Restored real date (09-02) → crashes again at launch - Repro: `sudo timedatectl set-ntp false && sudo date -s "2026-08-30 12:00:00"` → `sudo waydroid container restart` → launch app → works 4. Conclusion: nothing is corrupted — the failure is purely that **the clock crossed a built-in deadline** ## Diagnosis: libhoudini built-in license expiry (`ibt_get_expire_date`) Binary inspection of hpe-14's `/system/lib64/libhoudini.so` (9,323,480 bytes): - Symbol table contains **`ibt_get_expire_date`** (Intel Binary Translator's expiry query function) - The file contains the little-endian constant **`1788134400 = 2026-08-31 00:00:00 UTC`** (appears twice), matching the observed boundary (works on 08-30, fails on/after 09-01) Historical comparison (same mechanism, different per-build dates): - Jan 2026: a wave of identical reports — waydroid/waydroid#2091, waydroid-helper#78; reverse engineering found an `expire_date` function with timestamp `1767227429 = 2026-01-01` (chrhasse) - This old WSA build (~Dec 2025) expires at ≈ 2026-09-02 00:00 UTC, exactly matching "worked all of Sep 1, broken on the morning of Sep 2" - Hypothesis: Intel embeds an ~9-month license window in every libhoudini build; every build is effectively a time bomb - chromeos_octopus(39598) also contains `ibt_get_expire_date` — not a clean alternative ## Lesson learned (already reverted on my side) Attempting to patch the constant directly (4 bytes × 2 sites → 2030) caused **Waydroid to hang in an infinite boot animation** — the expiry check sits in code executed when zygote loads the native bridge early at boot. Blind binary patching is not viable; it needs disassembly-guided patching (as chrhasse did) or an official expiry-free build. ## Request - An **expiry-free patched build** of libhoudini (like wsa11-patched / brya-patched, but current enough for Android 13 + recent game versions) - Or libhoudini extracted from a **newer Google Play Games (HPE) image** (newer build = newer license window) - Or confirmation of whether any build (e.g. ChromeOS-derived) actually has no expiry check Impact: all x86_64 Waydroid users still running libhoudini builds whose embedded expiry date has passed since 2026-09-02 (this should already be hitting many users worldwide this month). https://github.com/waydroid-helper/waydroid-helper/issues/127 has the same problem.
lycegg commented 2026-09-02 02:29:09 -04:00 (Migrated from github.com)

This was diagnosed by AI, and the reason given might not necessarily be correct. However, in my opinion, this indeed has something to do with time, because I successfully launched the game after adjusting the date

This was diagnosed by AI, and the reason given might not necessarily be correct. However, in my opinion, this indeed has something to do with time, because I successfully launched the game after adjusting the date
lycegg commented 2026-09-02 03:00:27 -04:00 (Migrated from github.com)

by the way, https://github.com/casualsnek/waydroid_script/issues/277 just need one line,and AI tell me to change /opt/waydroid-script/main.py around 148–150 to

if not container.use_overlayfs():
    copy_dir = "/tmp/waydroid"
    container.stop()
    mount("system", copy_dir)
    mount("vendor", copy_dir)

for item in remove_list:
    item.uninstall()

just add two lines.If it is fixed, I will be very grateful.

by the way, https://github.com/casualsnek/waydroid_script/issues/277 just need one line,and AI tell me to change /opt/waydroid-script/main.py around 148–150 to if not container.use_overlayfs(): copy_dir = "/tmp/waydroid" container.stop() mount("system", copy_dir) mount("vendor", copy_dir) for item in remove_list: item.uninstall() just add two lines.If it is fixed, I will be very grateful.
caffeinepx commented 2026-09-02 04:16:58 -04:00 (Migrated from github.com)
https://github.com/waydroid-helper/waydroid-helper/issues/127#issuecomment-5506441807 There's a patch :3
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wbruno/waydroid_script#285