Skip to content

android-bundle: pad-run.sh — a lock-enforcing wrapper every NP02J script goes through, with a usage snapshot for after-the-fact contamination checks #52

Description

@dfattal

Why

Two pad collisions in three days, same shape both times: a session read /data/local/tmp/pad.lock, gated only the writing of its own lock (or a pad-lock.sh take whose exit status was not checked), and then ran its device commands anyway under another session's live measurement.

  • 2026-09-10 08:52Z: a chained prove-freeform run walked past a refused pad-lock.sh take (3 minutes of contamination, both runs discarded).
  • 2026-09-12 08:37Z: an ad-hoc script installed an APK, set debug props, pinned rotation and launched an app during an activity-thaw measurement (one side claim on runtime#1454 withdrawn because the window could not be separated from the launch; logcat had rolled by the time it was checked).

A check inside prove-* would have caught neither: the offending scripts were ad hoc. The lock is advisory today; the enforcement has to be the thing that runs commands.

What

android-bundle/scripts/pad-run.sh <handle> "<purpose/duration>" -- <cmd …>

  1. Refuse under a foreign lock. If pad.lock exists and its first token is not <handle>: print the holder line, exit 75, exec nothing. No --force.
  2. Take / release around the command. Write <handle> <ISO-8601 UTC> <purpose> (never truncate an existing lock), run the command with the lock held, rm the lock on exit (trap on EXIT/INT/TERM). Re-entrant for the same handle so a driver script can wrap several steps.
  3. Restore rotation on exit via the shared restore_rotation (auto-rotate 1 / user_rotation 1 / fixed-to-user-rotation disabled), regardless of what the command did.
  4. Snapshot for after-the-fact checks. At start and end: dumpsys usagestats (recent app launches/foreground events), dumpsys activity recents, and logcat -d -t 2000 filtered to ActivityTaskManager|ActivityManager: Start|Force stopping|am_proc_start into the caller's scratch dir ($PAD_RUN_OUT, default ./pad-run-<handle>-<ts>/). Print the delta at exit: which packages started/stopped/foregrounded inside the window. This is what lets a reading that was already taken be judged contaminated or clean once logcat has rolled.
  5. Refuse to force-stop the runtime service (org.freedesktop.monado.openxr_runtime.out_of_process) from inside the wrapper unless --allow-runtime-stop is passed; that is the other standing rule that gets broken by accident.

prove-3d.sh / prove-freeform.sh / the bundle install and gate scripts then call themselves through it, and the README's protocol section points at it as the only sanctioned way to touch the pad from a script.

Not in scope

Cross-machine locking (the lock file on the device already serialises every box), and any change to what the prove scripts measure.

Refs: runtime#1454 (the withdrawn claim), displayxr-demo-mediaplayer#71 (the second collision's run).

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions