Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-126945

race condition restoring selinux labels

Linking RHIVOS CVEs to...Migration: Automation ...SWIFT: POC ConversionSync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Undefined Undefined
    • rhel-10.2
    • rhel-10.2
    • libvirt / General
    • None
    • None
    • Low
    • 1
    • rhel-virt-core-libvirt-1
    • None
    • False
    • False
    • Hide

      None

      Show
      None
    • No
    • Libvirt Bugs already in Sprint
    • None
    • None
    • Unspecified Release Note Type - Unknown
    • Unspecified
    • Unspecified
    • Unspecified
    • 11.10.0
    • None

      Until recently, libguestfs was accidentally disabling svirt for VMs quite often. We recently fixed that but then noticed that running `make -j8 check` with selinux enforcing would cause random failures.

      Setup to reproduce:
      + qemu:///session (qemu:///system with remember=on is unaffected)
      + selinux enforcing
      + vm1 and vm2 using kernel+initrd boot
      + put the kernel in $HOME/kernel
      + apply this patch to simulate a race condition

      diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
      index fa5d1568eb..d1665d3efe 100644
      --- a/src/security/security_selinux.c
      +++ b/src/security/security_selinux.c
      @@ -3383,10 +3383,18 @@ virSecuritySELinuxSetAllLabel(virSecurityManager *mgr,
                   return -1;
           }
       
      -    if (def->os.kernel &&
      -        virSecuritySELinuxSetFilecon(mgr, def->os.kernel,
      -                                     data->content_context, true) < 0)
      -        return -1;
      +    if (def->os.kernel) {
      +        if (virSecuritySELinuxSetFilecon(mgr, def->os.kernel,
      +                                         data->content_context, true) < 0)
      +            return -1;
      +        printf("kernel label set for vm=%s\n", def->name);
      +
      +        if STREQ(def->name, "v2") {
      +            printf("doing startup sleep for dom=v2\n");
      +            sleep(15);
      +            printf("sleep done\n");
      +        }
      +    }
       
           if (def->os.initrd &&
               virSecuritySELinuxSetFilecon(mgr, def->os.initrd,
      

      + build, run virtqemud
      + start vm1. confirm that kernel has expected label virt_content_t
      + start vm2 but it will hit the sleep
      + in another terminal, stop vm1 during the sleep. vm1 startup will actually hang until the sleep is over
      + when sleep expires, vm2 will fail to start, because the disk label changed underneath it to user_home_t, which qemu svirt can't access

      There's a bit of subtlety here. If you put the kernel in /tmp, things work, because the label restore step doesn't find any default label for /tmp/kernel (basically, `matchpathcon /tmp/kernel` returns `<<none>>`) so libvirt leaves the label untouched as virt_content_t. If you put the kernel in /var/lib/libvirt/images/, the label will be restored to svirt_image_t, which also works. But $HOME and some other locations have blanket policies to label everything unknown as user_home_t, which svirt policy rejects. libguestfs test suite is storing test kernel+initrd in tree in $HOME, so that's why we are seeing this.

      Note, this doesn't impact libguestfs in practice because where libguestfs stores its kernel/initrd is not affected by a blanket selinux file content policy like $HOME. But in some future scenario where selinux policy changes, suddenly real world libguestfs usage is susceptible.

      Some ideas after looking at the code:
      + Consider broadening the VM startup locking to protect the security driver until the VM has launched. Might be totally impractical, but it would eliminate the race condition entirely.
      + For the particular case of kernel/initrd and anything that is considered 'shared' and gets virt_content_t, we could skip label restore entirely. this is what is already done for disks marked as shared (grep for src->shared in security_selinux.c).

              rhn-engineering-colerobinson Cole Robinson
              rhn-engineering-colerobinson Cole Robinson
              Cole Robinson
              virt-maint virt-maint
              virt-bugs virt-bugs
              Votes:
              0 Vote for this issue
              Watchers:
              10 Start watching this issue

                Created:
                Updated: