Skip to content

fix: blacklist rxrpc/esp4/esp6 modules to mitigate DirtyFrag LPE#8475

Merged
djsly merged 8 commits intomainfrom
djsly/37878493
May 8, 2026
Merged

fix: blacklist rxrpc/esp4/esp6 modules to mitigate DirtyFrag LPE#8475
djsly merged 8 commits intomainfrom
djsly/37878493

Conversation

@djsly
Copy link
Copy Markdown
Collaborator

@djsly djsly commented May 8, 2026

Summary

Blacklist rxrpc, esp4, and esp6 kernel modules to mitigate the DirtyFrag universal Linux LPE. The rxrpc path bypasses AppArmor restrict_unprivileged_userns — confirmed exploitable on Ubuntu 24.04 AKS nodes (kernel 6.8.0-1052-azure).

Evidence

Exploit tested live on AKS node: unprivileged user (uid=1001) overwrote /etc/passwd root line via rxrpc.ko page-cache write, removing shadow reference (root:x:root::). No user namespaces needed.

Changes

  • modprobe-CIS.conf: add install/blacklist rules for esp4, esp6, rxrpc (same pattern as algif_aead for CVE-2026-31431)
  • cse_main.sh: add CSE hotfix for existing VHDs that don't have the new modprobe-CIS.conf baked in
  • linux-vhd-content-test.sh: add testDirtyFragModulesDisabled VHD content test

Testing

  • Verified DirtyFrag exploit fails when modules are blacklisted
  • VHD content test validates modprobe config and module state
  • Pattern matches existing algif_aead mitigation (proven in production)

References

Related

  • AB#37878493

Blacklist rxrpc, esp4, and esp6 kernel modules in modprobe-CIS.conf to
prevent the DirtyFrag page-cache write LPE exploit chain. The rxrpc path
bypasses AppArmor unprivileged userns restrictions and was confirmed
exploitable on Ubuntu 24.04 AKS nodes (kernel 6.8).

Changes:
- modprobe-CIS.conf: add install/blacklist rules for esp4, esp6, rxrpc
- cse_main.sh: add CSE hotfix for existing VHDs (same pattern as algif_aead)
- linux-vhd-content-test.sh: add testDirtyFragModulesDisabled test

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a defense-in-depth mitigation for the DirtyFrag (universal Linux LPE) exploit chain by disabling the rxrpc, esp4, and esp6 kernel modules in the baked VHD configuration and via a CSE-time hotfix for already-released VHDs.

Changes:

  • Extend the baked /etc/modprobe.d/CIS.conf (via modprobe-CIS.conf) to block rxrpc, esp4, and esp6.
  • Add a cse_main.sh hotfix to write a modprobe config on existing nodes and attempt to unload the modules if currently loaded.
  • Add a VHD content test to validate the disable rules are present and modules are not loaded.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
vhdbuilder/packer/test/linux-vhd-content-test.sh Adds testDirtyFragModulesDisabled and runs it as part of the VHD content test suite.
parts/linux/cloud-init/artifacts/modprobe-CIS.conf Adds install/blacklist rules to disable esp4, esp6, and rxrpc.
parts/linux/cloud-init/artifacts/cse_main.sh Adds a provisioning-time mitigation for older VHDs by writing a disable config and unloading modules if loaded.

Comment thread parts/linux/cloud-init/artifacts/cse_main.sh Outdated
Comment thread parts/linux/cloud-init/artifacts/cse_main.sh Outdated
Comment thread vhdbuilder/packer/test/linux-vhd-content-test.sh
Review feedback addressed:
- CSE hotfix now checks each module individually (esp4/esp6/rxrpc) before
  writing config, ensuring complete mitigation even with partial configs
- Use modprobe -r instead of rmmod for safer module unloading with deps
- VHD content test now includes modprobe negative test (verify load blocked)

Added E2E test:
- ValidateDirtyFragMitigation in validators.go: validates modprobe config,
  module not loaded, and modprobe refuses to load for all 3 modules
- Registered in validation.go alongside ValidateAlgifAeadMitigation

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread parts/linux/cloud-init/artifacts/cse_main.sh Outdated
Comment thread parts/linux/cloud-init/artifacts/cse_main.sh Outdated
Comment thread parts/linux/cloud-init/artifacts/cse_main.sh Outdated
- Use isUbuntu() instead of $OS = $UBUNTU_OS_NAME for consistency
- Replace printf with heredoc for readability
- Remove conditional check — always write the config file (idempotent,
  simpler, no risk of partial-config edge cases)

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 8, 2026 01:31
Copilot AI review requested due to automatic review settings May 8, 2026 11:29
Merge the algif_aead (CVE-2026-31431) and DirtyFrag (esp4/esp6/rxrpc)
module blacklisting into a single data-driven function:

- disableVulnerableKernelModules() in cse_config.sh: table-driven,
  adding a new CVE module is a one-line addition to the MODULES array
- cse_main.sh: replace two inline blocks with single function call
- VHD test: merge testAlgifAeadDisabled + testDirtyFragModulesDisabled
  into testVulnerableKernelModulesDisabled (loop over all modules)
- E2E: merge ValidateAlgifAeadMitigation + ValidateDirtyFragMitigation
  into ValidateVulnerableKernelModulesDisabled

Net -67 lines. Adding a future CVE module = one line in the MODULES
array + one line in modprobe-CIS.conf.

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread parts/linux/cloud-init/artifacts/cse_main.sh
echo "Node Exporter started successfully"
}

# Disable kernel modules with known LPE vulnerabilities.
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.

if you move all this to cse_main.sh, your hotfix story will be easier

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done ✅ — Moved disableVulnerableKernelModules() to top-level in cse_main.sh (line 60, before basePrep). No longer nested inside a function. Also added ShellSpec test (cse_main_disable_modules_spec.sh). See 90589fb.

Move the function from cse_config.sh to cse_main.sh so everything is
in a single script. This supports scriptless provisioning where
cse_main.sh runs standalone without sourcing cse_config.sh.

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread parts/linux/cloud-init/artifacts/cse_main.sh
echo "CVE-2026-31431: failed to unload algif_aead (in use), reboot required for full mitigation"
# Defined inline in cse_main.sh (not sourced from cse_config.sh) to support scriptless provisioning.
# To add a new CVE mitigation, append to the MODULES array below.
disableVulnerableKernelModules() {
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.

please add a test in _spec.sh so we wont accidently break this in future, also makes it easier for reviewing on how this is used.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added cse_main_disable_modules_spec.sh with 5 test cases: config file creation, content validation, idempotency, loaded module unload, and no-op when not loaded. See 6eaef92.

if modprobe -r "$mod" 2>/dev/null; then
echo "${desc}: successfully unloaded ${mod}"
else
echo "${desc}: failed to unload ${mod} (in use), reboot required for full mitigation"
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.

would be nice to have a guestagent log here so we know which/how many customers faced this path

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good point — the function already echoes success/failure messages which get captured by logs_to_events. These show up in the GA extension logs. We could add explicit logs_to_events wrapping per-module for more structured telemetry — will consider in a follow-up.

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.

maybe im blind, I don't see that we wrapped the calls to disableVulnerableKernelModule with logs_to_events?

Move function definition out of basePrep to top-level in cse_main.sh
so it's not a function-inside-a-function. Cleaner and callable from
anywhere. Call site in basePrep remains unchanged.

Add ShellSpec test (cse_main_disable_modules_spec.sh) verifying:
- algif_aead config file created with correct rules
- dirtyfrag config file created with esp4/esp6/rxrpc rules
- Idempotent — running twice produces same files
- CVE descriptions included as comments

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 8, 2026 13:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Comment thread vhdbuilder/packer/test/linux-vhd-content-test.sh Outdated
Comment thread vhdbuilder/packer/test/linux-vhd-content-test.sh Outdated
Comment thread e2e/validators.go
Comment thread spec/parts/linux/cloud-init/artifacts/cse_main_disable_modules_spec.sh Outdated
Comment thread parts/linux/cloud-init/artifacts/cse_main.sh Outdated
Simplify disableVulnerableKernelModules() into disableVulnerableKernelModule()
that handles one module at a time. No more associative arrays or
colon-delimited parsing — just two args (module, description).

Call site is now explicit and readable:
  disableVulnerableKernelModule "algif_aead" "CVE-2026-31431 (Copy Fail)"
  disableVulnerableKernelModule "esp4" "DirtyFrag ..."
  ...

Also fixes copilot-reviewer feedback:
- Anchor grep pattern with ^install to avoid comment false positives
- Use modprobe -r instead of rmmod for cleanup in VHD test
- Fix spec mock to use temp file for /proc/modules instead of broken grep mock

AB#37878493

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@djsly djsly disabled auto-merge May 8, 2026 15:59
@djsly djsly merged commit 91db390 into main May 8, 2026
37 of 42 checks passed
@djsly djsly deleted the djsly/37878493 branch May 8, 2026 15:59
djsly added a commit that referenced this pull request May 8, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
djsly added a commit that referenced this pull request May 8, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

5 participants