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