Skip to content

portal_sysctl: don't panic creating sysctls under non-existent dirs (old kernels)#76

Merged
lacraig2 merged 1 commit into
mainfrom
fix/sysctl-create-guard
Jun 9, 2026
Merged

portal_sysctl: don't panic creating sysctls under non-existent dirs (old kernels)#76
lacraig2 merged 1 commit into
mainfrom
fix/sysctl-create-guard

Conversation

@lacraig2

@lacraig2 lacraig2 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Problem

handle_op_sysctl_create_file() calls register_sysctl() for every new sysctl entry Penguin asks the guest to create. On pre-5.0 guest kernels this can panic the guest:

sysctl could not get directory: /fs/binfmt_misc//WSLInteropos -30
Unable to handle kernel NULL pointer dereference at virtual address 00000048
PC is at rb_erase+0x3c
  drop_sysctl_table <- __register_sysctl_table <- register_sysctl
  <- handle_op_sysctl_create_file [igloo] <- igloo_portal [igloo]
Kernel panic - not syncing: Attempted to kill init!

When register_sysctl() has to create a new directory hierarchy and an intermediate component can't be created — e.g. anything under the filesystem-backed /proc/sys/fs/binfmt_misc node, which returns -EROFS — the 4.10 kernel faults in its cleanup path (drop_sysctl_tablerb_erase) instead of returning an error. That kills init and panics the box. Newer kernels (5.x) return NULL from register_sysctl() and are already handled by the existing !entry->header path, so only old kernels are affected.

This reliably crashed aarch64 guests (4.10 kernel) ~5s into boot whenever Penguin modeled bogus /proc/sys/* entries (these come from auto-generated pseudofile models that scrape binary strings, e.g. /proc/sys/fs/binfmt_misc/WSLInteropos/signal).

Fix

Guard the creation path in handle_op_sysctl_create_file():

  1. Reject malformed paths up front (unconditional): empty leaf name, or a directory containing an empty component (embedded //).
  2. On kernels < 5.0, require the parent directory to already exist before creating a new entry. A new helper, igloo_sysctl_dir_exists(), walks the live sysctl tree using the same safe accessors as the existing igloo_find_sysctl_leaf(). If the parent dir isn't real, we log and return HYPER_RESP_WRITE_FAIL instead of handing the kernel a doomed registration. Scoped via LINUX_VERSION_CODE so 5.x+ keeps creating new directories exactly as before (no behavior change on modern kernels).

Mutating an existing sysctl leaf is unchanged.

Testing

Built igloo.ko for arm64/4.10 with this change and ran the GL.iNet Beryl AX (GL-MT3000) firmware under Penguin with stock pyplugins (so the bogus binfmt_misc sysctl is still sent to the guest):

  • Before: kernel panic at ~5s (Attempted to kill init!), 99-line console, no services.
  • After: no panic; boots normally past the sysctl stage, tracking kernel modules and proceeding to userspace (130+ line console and climbing). Identical image base, only igloo.ko changed.

x86-64 (5.15) is unaffected (guard is version-scoped).

Companion

rehosting/penguin filters the same unregisterable paths upstream (defense in depth) — see its fix/sysctl-create-guard PR. Either change alone prevents the panic; together they stop bogus models from being emitted and make the driver robust against any that slip through.

handle_op_sysctl_create_file() called register_sysctl() for every new
entry. On pre-5.0 kernels, when register_sysctl() has to create a new
directory hierarchy and an intermediate component cannot be created
(e.g. anything under the filesystem-backed /proc/sys/fs/binfmt_misc
node, which returns -EROFS), the kernel faults in its cleanup path
(drop_sysctl_table -> rb_erase) and panics, killing init. Newer kernels
return NULL and are already handled by the !entry->header path.

This reliably crashed aarch64 guests (4.10 kernel) ~5s into boot when
Penguin modeled bogus /proc/sys entries scraped from binaries.

Guard the creation path:
- Reject malformed paths up front (empty leaf name, embedded "//").
- On kernels < 5.0, refuse to create an entry whose parent sysctl
  directory does not already exist -- verified by walking the live
  sysctl tree with the existing safe accessors (igloo_sysctl_dir_exists)
  -- instead of handing the kernel a doomed registration. Scoped to
  affected versions so newer kernels keep creating new dirs as before.

Companion to rehosting/penguin, which also filters these paths upstream.
@lacraig2 lacraig2 merged commit b304603 into main Jun 9, 2026
1 check passed
@lacraig2 lacraig2 deleted the fix/sysctl-create-guard branch June 9, 2026 05:09
lacraig2 added a commit to rehosting/penguin that referenced this pull request Jun 9, 2026
0.0.78 includes the portal_sysctl create-guard (rehosting/igloo_driver#76),
the kernel-side backstop for the bogus-sysctl boot panic this PR also
guards against from the Python side.
lacraig2 added a commit to rehosting/penguin that referenced this pull request Jun 9, 2026
0.0.78 includes the portal_sysctl create-guard (rehosting/igloo_driver#76),
the kernel-side backstop for the bogus-sysctl boot panic this PR also
guards against from the Python side.
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