yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
6e7d01
From 181ed1777c3dd50b1ff9907b0a4199e845af1270 Mon Sep 17 00:00:00 2001
6e7d01
From: Max Reitz <mreitz@redhat.com>
6e7d01
Date: Fri, 18 Jun 2021 16:21:17 -0400
6e7d01
Subject: [PATCH 1/4] virtiofsd: Whitelist fchmod
6e7d01
MIME-Version: 1.0
6e7d01
Content-Type: text/plain; charset=UTF-8
6e7d01
Content-Transfer-Encoding: 8bit
6e7d01
6e7d01
RH-Author: Max Reitz <mreitz@redhat.com>
6e7d01
Message-id: <20210618162117.97775-2-mreitz@redhat.com>
6e7d01
Patchwork-id: 101719
6e7d01
O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] virtiofsd: Whitelist fchmod
6e7d01
Bugzilla: 1967914
6e7d01
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6e7d01
RH-Acked-by: Vivek Goyal <vgoyal@redhat.com>
6e7d01
RH-Acked-by: Connor Kuehl <ckuehl@redhat.com>
6e7d01
6e7d01
lo_setattr() invokes fchmod() in a rarely used code path, so it should
6e7d01
be whitelisted or virtiofsd will crash with EBADSYS.
6e7d01
6e7d01
Said code path can be triggered for example as follows:
6e7d01
6e7d01
On the host, in the shared directory, create a file with the sticky bit
6e7d01
set and a security.capability xattr:
6e7d01
(1) # touch foo
6e7d01
(2) # chmod u+s foo
6e7d01
(3) # setcap '' foo
6e7d01
6e7d01
Then in the guest let some process truncate that file after it has
6e7d01
dropped all of its capabilities (at least CAP_FSETID):
6e7d01
6e7d01
int main(int argc, char *argv[])
6e7d01
{
6e7d01
    capng_setpid(getpid());
6e7d01
    capng_clear(CAPNG_SELECT_BOTH);
6e7d01
    capng_updatev(CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, 0);
6e7d01
    capng_apply(CAPNG_SELECT_BOTH);
6e7d01
6e7d01
    ftruncate(open(argv[1], O_RDWR), 0);
6e7d01
}
6e7d01
6e7d01
This will cause the guest kernel to drop the sticky bit (i.e. perform a
6e7d01
mode change) as part of the truncate (where FATTR_FH is set), and that
6e7d01
will cause virtiofsd to invoke fchmod() instead of fchmodat().
6e7d01
6e7d01
(A similar configuration exists further below with futimens() vs.
6e7d01
utimensat(), but the former is not a syscall but just a wrapper for the
6e7d01
latter, so no further whitelisting is required.)
6e7d01
6e7d01
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1842667
6e7d01
Reported-by: Qian Cai <caiqian@redhat.com>
6e7d01
Cc: qemu-stable@nongnu.org
6e7d01
Signed-off-by: Max Reitz <mreitz@redhat.com>
6e7d01
Message-Id: <20200608093111.14942-1-mreitz@redhat.com>
6e7d01
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
6e7d01
Reviewed-by: Vivek Goyal <vgoyal@redhat.com>
6e7d01
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
6e7d01
(cherry picked from commit 63659fe74e76f5c5285466f0c5cfbdca65b3688e)
6e7d01
Signed-off-by: Max Reitz <mreitz@redhat.com>
6e7d01
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
6e7d01
---
6e7d01
 tools/virtiofsd/seccomp.c | 1 +
6e7d01
 1 file changed, 1 insertion(+)
6e7d01
6e7d01
diff --git a/tools/virtiofsd/seccomp.c b/tools/virtiofsd/seccomp.c
6e7d01
index bd9e7b083c..3b1522acdd 100644
6e7d01
--- a/tools/virtiofsd/seccomp.c
6e7d01
+++ b/tools/virtiofsd/seccomp.c
6e7d01
@@ -42,6 +42,7 @@ static const int syscall_whitelist[] = {
6e7d01
     SCMP_SYS(exit_group),
6e7d01
     SCMP_SYS(fallocate),
6e7d01
     SCMP_SYS(fchdir),
6e7d01
+    SCMP_SYS(fchmod),
6e7d01
     SCMP_SYS(fchmodat),
6e7d01
     SCMP_SYS(fchownat),
6e7d01
     SCMP_SYS(fcntl),
6e7d01
-- 
6e7d01
2.27.0
6e7d01