Skip to content

Commit 8450ca6

Browse files
committed
fix(prepare): surface deferred KVM nested-virt mitigation on already-loaded hosts
The modprobe.d drop-in only takes effect when the kvm module is (re)loaded. On a host where kvm_intel/kvm_amd is already loaded at boot, the parameter is not applied until the next reboot, leaving the CVE-2026-53359 mitigation silently inactive after a run. Add a read-only sysfs check that warns the operator when nested is still enabled and a reboot is required. Non-destructive: no automatic module unload. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
1 parent c80481f commit 8450ca6

3 files changed

Lines changed: 117 additions & 0 deletions

File tree

examples/rhel/prepare-rhel.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,45 @@
528528
- cozystack_enable_kubevirt | default(true) | bool
529529
- (_cozystack_kvm_module | default('')) | length > 0
530530

531+
# The modprobe.d drop-in above only takes effect when the kvm_*
532+
# module is (re)loaded. On a host where the module was already
533+
# loaded at boot (the common case — the kernel autoloads it on
534+
# KVM-capable CPUs) the best-effort modprobe above is a no-op and
535+
# nested keeps its boot value. Read the effective state back from
536+
# sysfs so a still-enabled nested is surfaced, not silently deferred
537+
# to the next reboot. Only the CPU vendor's module exposes the file,
538+
# so this is gated on _cozystack_kvm_module_stat and never reads a
539+
# path that is absent. Read-only on purpose: we do NOT `modprobe -r`
540+
# the module, which could disrupt a host whose /dev/kvm is in use.
541+
- name: Read back the effective KVM nested-virt state from sysfs
542+
ansible.builtin.slurp:
543+
src: "/sys/module/{{ _cozystack_kvm_module }}/parameters/nested"
544+
register: _cozystack_kvm_nested_state
545+
failed_when: false
546+
when:
547+
- cozystack_enable_kubevirt | default(true) | bool
548+
- cozystack_disable_kvm_nested | default(true) | bool
549+
- (_cozystack_kvm_module | default('')) | length > 0
550+
- _cozystack_kvm_module_stat is defined
551+
- _cozystack_kvm_module_stat.stat.exists | default(false)
552+
553+
- name: Warn that a reboot is required to apply the KVM nested-virt mitigation
554+
ansible.builtin.debug:
555+
msg: >-
556+
WARNING: the CVE-2026-53359 mitigation drop-in
557+
(/etc/modprobe.d/cozystack-kvm-nested.conf) is written, but
558+
{{ _cozystack_kvm_module }} is already loaded with nested
559+
virtualization ENABLED. A running kvm module cannot be
560+
re-parameterised while /dev/kvm may be in use, so the mitigation
561+
is NOT active yet. Reboot the host -- or, when no VMs are
562+
running, `modprobe -r {{ _cozystack_kvm_module }} && modprobe
563+
{{ _cozystack_kvm_module }}` -- to apply nested=0.
564+
when:
565+
- cozystack_enable_kubevirt | default(true) | bool
566+
- cozystack_disable_kvm_nested | default(true) | bool
567+
- _cozystack_kvm_nested_state.content is defined
568+
- (_cozystack_kvm_nested_state.content | b64decode | trim) in ['Y', '1']
569+
531570
- name: Persist KubeVirt kernel modules for boot
532571
ansible.builtin.copy:
533572
dest: /etc/modules-load.d/cozystack-kubevirt.conf

examples/suse/prepare-suse.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,45 @@
502502
- cozystack_enable_kubevirt | default(true) | bool
503503
- (_cozystack_kvm_module | default('')) | length > 0
504504

505+
# The modprobe.d drop-in above only takes effect when the kvm_*
506+
# module is (re)loaded. On a host where the module was already
507+
# loaded at boot (the common case — the kernel autoloads it on
508+
# KVM-capable CPUs) the best-effort modprobe above is a no-op and
509+
# nested keeps its boot value. Read the effective state back from
510+
# sysfs so a still-enabled nested is surfaced, not silently deferred
511+
# to the next reboot. Only the CPU vendor's module exposes the file,
512+
# so this is gated on _cozystack_kvm_module_stat and never reads a
513+
# path that is absent. Read-only on purpose: we do NOT `modprobe -r`
514+
# the module, which could disrupt a host whose /dev/kvm is in use.
515+
- name: Read back the effective KVM nested-virt state from sysfs
516+
ansible.builtin.slurp:
517+
src: "/sys/module/{{ _cozystack_kvm_module }}/parameters/nested"
518+
register: _cozystack_kvm_nested_state
519+
failed_when: false
520+
when:
521+
- cozystack_enable_kubevirt | default(true) | bool
522+
- cozystack_disable_kvm_nested | default(true) | bool
523+
- (_cozystack_kvm_module | default('')) | length > 0
524+
- _cozystack_kvm_module_stat is defined
525+
- _cozystack_kvm_module_stat.stat.exists | default(false)
526+
527+
- name: Warn that a reboot is required to apply the KVM nested-virt mitigation
528+
ansible.builtin.debug:
529+
msg: >-
530+
WARNING: the CVE-2026-53359 mitigation drop-in
531+
(/etc/modprobe.d/cozystack-kvm-nested.conf) is written, but
532+
{{ _cozystack_kvm_module }} is already loaded with nested
533+
virtualization ENABLED. A running kvm module cannot be
534+
re-parameterised while /dev/kvm may be in use, so the mitigation
535+
is NOT active yet. Reboot the host -- or, when no VMs are
536+
running, `modprobe -r {{ _cozystack_kvm_module }} && modprobe
537+
{{ _cozystack_kvm_module }}` -- to apply nested=0.
538+
when:
539+
- cozystack_enable_kubevirt | default(true) | bool
540+
- cozystack_disable_kvm_nested | default(true) | bool
541+
- _cozystack_kvm_nested_state.content is defined
542+
- (_cozystack_kvm_nested_state.content | b64decode | trim) in ['Y', '1']
543+
505544
- name: Persist KubeVirt kernel modules for boot
506545
ansible.builtin.copy:
507546
dest: /etc/modules-load.d/cozystack-kubevirt.conf

examples/ubuntu/prepare-ubuntu.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,45 @@
736736
- cozystack_enable_kubevirt | default(true) | bool
737737
- (_cozystack_kvm_module | default('')) | length > 0
738738

739+
# The modprobe.d drop-in above only takes effect when the kvm_*
740+
# module is (re)loaded. On a host where the module was already
741+
# loaded at boot (the common case — the kernel autoloads it on
742+
# KVM-capable CPUs) the best-effort modprobe above is a no-op and
743+
# nested keeps its boot value. Read the effective state back from
744+
# sysfs so a still-enabled nested is surfaced, not silently deferred
745+
# to the next reboot. Only the CPU vendor's module exposes the file,
746+
# so this is gated on _cozystack_kvm_module_stat and never reads a
747+
# path that is absent. Read-only on purpose: we do NOT `modprobe -r`
748+
# the module, which could disrupt a host whose /dev/kvm is in use.
749+
- name: Read back the effective KVM nested-virt state from sysfs
750+
ansible.builtin.slurp:
751+
src: "/sys/module/{{ _cozystack_kvm_module }}/parameters/nested"
752+
register: _cozystack_kvm_nested_state
753+
failed_when: false
754+
when:
755+
- cozystack_enable_kubevirt | default(true) | bool
756+
- cozystack_disable_kvm_nested | default(true) | bool
757+
- (_cozystack_kvm_module | default('')) | length > 0
758+
- _cozystack_kvm_module_stat is defined
759+
- _cozystack_kvm_module_stat.stat.exists | default(false)
760+
761+
- name: Warn that a reboot is required to apply the KVM nested-virt mitigation
762+
ansible.builtin.debug:
763+
msg: >-
764+
WARNING: the CVE-2026-53359 mitigation drop-in
765+
(/etc/modprobe.d/cozystack-kvm-nested.conf) is written, but
766+
{{ _cozystack_kvm_module }} is already loaded with nested
767+
virtualization ENABLED. A running kvm module cannot be
768+
re-parameterised while /dev/kvm may be in use, so the mitigation
769+
is NOT active yet. Reboot the host -- or, when no VMs are
770+
running, `modprobe -r {{ _cozystack_kvm_module }} && modprobe
771+
{{ _cozystack_kvm_module }}` -- to apply nested=0.
772+
when:
773+
- cozystack_enable_kubevirt | default(true) | bool
774+
- cozystack_disable_kvm_nested | default(true) | bool
775+
- _cozystack_kvm_nested_state.content is defined
776+
- (_cozystack_kvm_nested_state.content | b64decode | trim) in ['Y', '1']
777+
739778
- name: Persist KubeVirt kernel modules for boot
740779
ansible.builtin.copy:
741780
dest: /etc/modules-load.d/cozystack-kubevirt.conf

0 commit comments

Comments
 (0)