Skip to content

android: redirect init rc paths without overwriting buffers - #313

Merged
Admirepowered merged 1 commit into
bmax121:mainfrom
xeropresence:fix/init-rc-redirection
Sep 23, 2026
Merged

Admirepowered merged 1 commit into
bmax121:mainfrom
xeropresence:fix/init-rc-redirection

Conversation

@xeropresence

Copy link
Copy Markdown
Contributor

Summary

Redirect init's openat filename through temporary userspace stack storage instead of overwriting the caller's filename allocation. Restore the syscall argument afterward without copying into the original buffer.

Problem

The existing path tries to copy /dev/user_init.rc over init's supplied filename. That replacement does not necessarily fit: /init.rc is shorter. The after-hook then restores an entire 64-byte ORIGIN_RC_FILES table entry, even though that table-entry size says nothing about the capacity of init's allocation.

Those writes can corrupt userspace memory or fault on hardened configurations. The fallback also writes directly to args->arg1, which is not the filename argument when a syscall wrapper supplies pt_regs.

Changes

  • Copy the replacement path to 16-byte-aligned userspace stack storage and redirect only after the complete NUL-terminated path has been copied.
  • Save, replace, and restore the filename with syscall_argn / set_syscall_argn so wrapper-based syscall hooks are handled correctly.
  • Reject a truncated filename read before comparing it as a C string.
  • Close the replacement file if reading the original rc file fails.
  • Remove the redundant apd uid-listener & rc command. Init passes & as a literal argument rather than shell backgrounding syntax, and APatch's boot-completed handler already starts the listener.

The original filename buffer is never modified. A failed replacement-path copy leaves the original syscall argument in place, and the one-shot hook cleanup remains enabled. No GrapheneOS-specific feature disable or persistent preset-format change is introduced.

Verification

Built the Android ARM64 payload and kptools on this branch.

Device testing used all three fixes on KernelPatch 0.13.8, with a Pixel 8 running GrapheneOS 2026081300:

  • Init opened the replacement for /system/etc/init/hw/init.rc; the one-shot hook was removed.
  • APatch post-fs-data, services, and boot-completed exited with status 0.
  • One apd uid-listener process remained running.

"on property:sys.boot_completed=1\n"
" exec -- " SUPERCMD " su -Z " MAGISK_SCTX " exec " APD_PATH " -s %s boot-completed\n"
" exec -- " SUPERCMD " su event boot-completed\n"
" exec -- " SUPERCMD " su -Z " MAGISK_SCTX " exec " APD_PATH " uid-listener &\n"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APD already starts the UID listener from on_boot_completed() via
run_uid_monitor(). The rc block already invokes boot-completed, so
this separate startup command is redundant.

The trailing & is passed to APD as a literal argument here, not
interpreted by a shell. During the earlier GrapheneOS testing, replacing
this with exec_background produced two listeners. Removing the line
left one listener running—the one started by APD's boot-completed handler.

@Admirepowered

Copy link
Copy Markdown
Collaborator

updated when my commit

@xeropresence
xeropresence force-pushed the fix/init-rc-redirection branch from 0401fca to 7fb79fd Compare September 22, 2026 16:14
@xeropresence

Copy link
Copy Markdown
Contributor Author

updated when my commit

@Admirepowered rebased and updated for your commit

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Kernel syscall interception and userspace stack manipulation warrant final human review despite the focused, verified implementation.

Review effort: Balanced
Findings: None

What changed in this PR

Redirects init RC file opens through safe userspace stack storage, avoiding writes into caller-owned buffers.

Changes:

  • Validates filename reads and redirects openat via syscall helpers.
  • Closes replacement files on read failure.
  • Removes the redundant UID-listener command.
File Description
kernel/​patch/​android/​userd.c Safely redirects init RC paths and updates generated RC commands.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

3 participants