Skip to content

fix: avoid first stage bootloop when blocking kernel modules - #3889

Closed
HSSkyBoy wants to merge 1 commit into
tiann:mainfrom
HSSkyBoy:fix/module-blacklist-first-stage
Closed

HSSkyBoy wants to merge 1 commit into
tiann:mainfrom
HSSkyBoy:fix/module-blacklist-first-stage

Conversation

@HSSkyBoy

Copy link
Copy Markdown

Follow-up to #3881 / #3883.

Problem

block_modules is merged into the kernel's module_blacklist in kernelsu_init, so a blocked module fails to load with EPERM. First stage init loads the vendor_boot modules listed in modules.load with LoadListedModules(strict) and calls LOG(FATAL) << "Failed to load kernel modules" on any failure, unless the module is in modules.blocklist:

  • system/core/init/first_stage_init.cpp: LoadKernelModules() → m.LoadListedModules(!want_console), then LOG(FATAL) if it returns false
  • libmodprobe/libmodprobe.cpp: LoadListedModules() only tolerates a failure when IsBlocklisted(module)

So blocking any module that first stage init loads bootloops the device, regardless of whether the system needs it. This is likely what happened on the Redmi K60 Ultra with mkp (#3883), and it applies equally to vendor_boot vr / vklp.

Fix

  • kernel: install the blacklist when /system/bin/init second_stage is executed instead of in kernelsu_init. Second stage loaders (vendor_dlkm modprobe, init insmod) only log a failed module.
  • ksuinit: before handing over to first stage init, append the names from block_modules= in /ksu_config to modules.blocklist in /lib/modules and its subdirectories (first stage init picks one of them by kernel release). The ramdisk is still writable at this point. modprobe then skips these modules without failing.
    • modprobe also skips every module that depends on a blocklisted one, so a name is left out (and logged to kmsg) if a module that would load otherwise depends on it. Unit tests cover the dependency handling.
  • manager: only pre-fill known modules that no other module uses (the "used by" column of /proc/modules), and reword the warning.

boot-patch-v2 and built-in kernels have no ksuinit. There only second stage loads are blocked, and first stage is never at risk.

Testing

A module in the kernel's module_blacklist fails to load with EPERM.
First stage init loads the vendor_boot modules from modules.load with
LoadListedModules(strict) and LOG(FATAL)s on any failure unless the
module is in modules.blocklist (system/core/init/first_stage_init.cpp,
libmodprobe). So blocking a first stage module through block_modules,
e.g. MediaTek mkp or vendor_boot vr/vklp, bootloops the device.

- kernel: install the blacklist when second stage init starts instead
  of at kernelsu_init. Second stage loaders (vendor_dlkm modprobe, init
  insmod) only log a failed module.
- ksuinit: before handing over to first stage init, add the names to
  modules.blocklist in /lib/modules and its subdirectories, where
  modprobe skips them cleanly. A name is left out (and logged) if a
  module that would load otherwise depends on it, since modprobe would
  skip that module too.
- manager: only pre-fill known modules that no other module uses and
  reword the warning.

boot-patch-v2 and built-in kernels have no ksuinit, so there only
second stage loads are blocked; first stage is never at risk.
@Ylarod

Ylarod commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Thanks for working on this and for the dependency-aware planning, it's a careful design.

We've decided not to fix the first stage issue in KernelSU itself: the ksuinit approach doesn't cover boot-patch-v2 / built-in kernels, and it adds a fair amount of code for a niche feature. Instead, #3920 removes the option from the Manager and keeps block_modules as a developer-only feature (ksud boot-patch --block-module). Developers who use it are responsible for picking modules that are safe for their device, and for first stage modules they can edit modules.blocklist in vendor_boot directly.

Closing in favor of #3920.

@Ylarod Ylarod closed this Oct 19, 2026
Ylarod added a commit that referenced this pull request Oct 19, 2026
Blocking a module through the native `module_blacklist` (#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in #3883, `oplus_secure_guard_new` in
#3908). Install screen users cannot be expected to know which modules
are safe to block, and both proposed mitigations (#3908, #3889) only
cover part of the problem.

### Changes
- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

### Testing
- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.
pershoot pushed a commit to pershoot/KernelSU-Next that referenced this pull request Oct 19, 2026
…n/KernelSU#3920)

Blocking a module through the native `module_blacklist` (tiann/KernelSU#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in tiann/KernelSU#3883, `oplus_secure_guard_new` in
are safe to block, and both proposed mitigations (tiann/KernelSU#3908, tiann/KernelSU#3889) only
cover part of the problem.

- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.

-Adapt:
 -manager: drop block-modules UI -> Jetpack (Install.kt, Flash.kt)
pershoot pushed a commit to KernelSU-Next/KernelSU-Next that referenced this pull request Oct 19, 2026
…n/KernelSU#3920)

Blocking a module through the native `module_blacklist` (tiann/KernelSU#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in tiann/KernelSU#3883, `oplus_secure_guard_new` in
are safe to block, and both proposed mitigations (tiann/KernelSU#3908, tiann/KernelSU#3889) only
cover part of the problem.

- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.

-Adapt:
 -manager: drop block-modules UI -> Jetpack (Install.kt, Flash.kt)
pershoot pushed a commit to pershoot/KernelSU-Next that referenced this pull request Oct 19, 2026
…n/KernelSU#3920)

Blocking a module through the native `module_blacklist` (tiann/KernelSU#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in tiann/KernelSU#3883, `oplus_secure_guard_new` in tiann/KernelSU#3908).  Install screen users cannot be expected to know which modules
are safe to block, and both proposed mitigations (tiann/KernelSU#3908, tiann/KernelSU#3889) only
cover part of the problem.

- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.

-Adapt:
 -manager: drop block-modules UI -> Jetpack (Install.kt, Flash.kt)
pershoot pushed a commit to pershoot/KernelSU-Next that referenced this pull request Oct 19, 2026
…n/KernelSU#3920)

Blocking a module through the native `module_blacklist` (tiann/KernelSU#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in tiann/KernelSU#3883, `oplus_secure_guard_new` in tiann/KernelSU#3908).
Install screen users cannot be expected to know which modules
are safe to block, and both proposed mitigations (tiann/KernelSU#3908, tiann/KernelSU#3889) only
cover part of the problem.

- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.

-Adapt:
 -manager: drop block-modules UI -> Jetpack (Install.kt, Flash.kt)
chisewaguri pushed a commit to chisewaguri/KernelSU that referenced this pull request Oct 20, 2026
…n#3920)

Blocking a module through the native `module_blacklist` (tiann#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in tiann#3883, `oplus_secure_guard_new` in
are safe to block, and both proposed mitigations (tiann#3908, tiann#3889) only
cover part of the problem.

- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.

(cherry picked from commit 605e426)
Sliva4 pushed a commit to Sliva4/KernelSU that referenced this pull request Oct 23, 2026
…n#3920)

Blocking a module through the native `module_blacklist` (tiann#3881) makes it
fail with `EPERM`. First stage init treats that as fatal for anything in
`modules.load` / `modules.load.recovery` that is not in
`modules.blocklist`, so blocking the wrong module bootloops the device
or breaks recovery (MediaTek `mkp` in tiann#3883, `oplus_secure_guard_new` in
tiann#3908). Install screen users cannot be expected to know which modules
are safe to block, and both proposed mitigations (tiann#3908, tiann#3889) only
cover part of the problem.

### Changes
- Manager: remove the "Block kernel modules" option, its pre-fill from
`/proc/modules` and the `--block-module` flag from the install screen
(Material + Miuix), plus the strings (en / zh-rCN / in).
- ksud: keep `boot-patch --block-module`, mark it as developer only in
the help text and document the first stage risk.
- Kernel: unchanged apart from a comment; the blacklist is still
installed at init.

Developers who use it are responsible for choosing safe modules. Note
that `--block-module` clears the list when omitted, so re-patching from
the Manager drops a list set via the CLI.

### Testing
- `./gradlew :app:compileDebugKotlin` passes.
- ksud `cargo fmt --check` and `cargo check` pass.
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.

2 participants