Page MenuHomeVyOS Platform

system option: commits fail under kernel lockdown - unconditional debugfs dynamic_debug write for wireguard
Open, NormalPublicBUG

Description

Version: 2026.11.08-0018-rolling (generic, x86_64)
Component: system_option.py (conf_mode)

Summary

system_option.py apply() writes to /sys/kernel/debug/dynamic_debug/control on every system option commit, also when system option kernel debug wireguard is not configured (it then writes module wireguard -p). With kernel lockdown in integrity (or confidentiality) mode, debugfs writes are denied, so every commit touching system option fails with PermissionError.
After boot the whole system option subtree can no longer be changed.

The failure also comes after earlier side effects of apply(): in the reproduction below vyos-beep.service gets enabled, the commit fails, and exit discard leaves the service enabled - running state and config disagree.

Code

src/conf_mode/system_option.py, apply() (line numbers from the 2026.11.08-0018-rolling image):

# Enable/disable dynamic debugging for kernel modules
modules = ['wireguard']
modules_enabled = dict_search('kernel.debug', options) or []
for module in modules:
    if module in modules_enabled:
        check_kmod(module)
        write_file(kernel_dynamic_debug, f'module {module} +p')
    else:
        write_file(kernel_dynamic_debug, f'module {module} -p')   # line 702

Every run of apply() - i.e. every commit that changes anything under system option, whatever the change - performs exactly one of the two writes: +p when kernel debug wireguard is set, -p otherwise. Neither depends on whether the debug setting changed, so both fail under lockdown. (Commits elsewhere are unaffected: config-mode-dependencies has no entry that calls system_option.)
The write came in with T3202.

Steps to reproduce

On a stock image (no other changes needed):

  1. Enable kernel lockdown (one-way until reboot): echo integrity | sudo tee /sys/kernel/security/lockdown
  2. configure
  3. set system option startup-beep
  4. commit

Actual result

Traceback (most recent call last):
  File "/usr/libexec/vyos/conf_mode/system_option.py", line 738, in <module>
    apply(c)
  File "/usr/libexec/vyos/conf_mode/system_option.py", line 702, in apply
    write_file(kernel_dynamic_debug, f'module {module} -p')
  File "/usr/lib/python3/dist-packages/vyos/utils/file.py", line 84, in write_file
    raise e
  File "/usr/lib/python3/dist-packages/vyos/utils/file.py", line 73, in write_file
    with open(fname, 'w' if not append else 'a') as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 1] Operation not permitted: '/sys/kernel/debug/dynamic_debug/control'
noteworthy:
cmd 'systemctl enable vyos-beep.service'
...
[[system option]] failed
Commit failed

After exit discard: systemctl is-enabled vyos-beep.service -> enabled.

Expected result

A system option change that doesn't involve kernel debug commits under lockdown. Suggested fixes, any of:

  • write to dynamic_debug/control only when kernel debug changed (or only +p when enabled, and -p only when it was enabled before);
  • tolerate EPERM/ENOENT on that write (lockdown, debugfs not mounted) with a warning instead of failing the commit;
  • if a hard failure is wanted, raise in verify() before apply() has side effects.

Context

We run kernel lockdown integrity from a post-config boot hook as hardening (VyOS modules are signed, nothing we run needs debugfs).

AI disclosure

This bug was found, diagnosed and written up by Claude Opus 5.5 (Anthropic, model claude-opus-5-5), running in Claude Code during a test run of our VyOS automation in a VM. Specifically, Claude:

  • hit the failed commit when our Ansible playbook re-applied system option on the rolling image,
  • traced it to the unconditional dynamic_debug write in system_option.py apply() and the lockdown denial,
  • reproduced it by hand on the VM (including the leftover vyos-beep.service side effect) and searched vyos.dev and the forum for an existing report,
  • drafted this report.

A human (the reporter) reviewed it and filed it.

Details

Version
Version: 2026.11.08-0018-rolling (generic, x86_64)
Is it a breaking change?
Behavior change
Issue type
Bug (incorrect behavior)