Blame SOURCES/kvm-virtiofsd-Drop-membership-of-all-supplementary-group.patch

60061b
From 2754dc2c7def01d7dd1bb39f3e86ef444652d397 Mon Sep 17 00:00:00 2001
4d2202
From: Vivek Goyal <vgoyal@redhat.com>
4d2202
Date: Tue, 25 Jan 2022 13:51:14 -0500
60061b
Subject: [PATCH 1/6] virtiofsd: Drop membership of all supplementary groups
4d2202
 (CVE-2022-0358)
4d2202
4d2202
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
60061b
RH-MergeRequest: 102: virtiofsd: Drop membership of all supplementary groups (CVE-2022-0358)
60061b
RH-Commit: [1/1] 93e56c88277fec8e42559a899d32b80fac4a923f
60061b
RH-Bugzilla: 2046198
60061b
RH-Acked-by: Greg Kurz <gkurz@redhat.com>
60061b
RH-Acked-by: Sergio Lopez <None>
4d2202
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
4d2202
4d2202
At the start, drop membership of all supplementary groups. This is
4d2202
not required.
4d2202
4d2202
If we have membership of "root" supplementary group and when we switch
4d2202
uid/gid using setresuid/setsgid, we still retain membership of existing
4d2202
supplemntary groups. And that can allow some operations which are not
4d2202
normally allowed.
4d2202
4d2202
For example, if root in guest creates a dir as follows.
4d2202
4d2202
$ mkdir -m 03777 test_dir
4d2202
4d2202
This sets SGID on dir as well as allows unprivileged users to write into
4d2202
this dir.
4d2202
4d2202
And now as unprivileged user open file as follows.
4d2202
4d2202
$ su test
4d2202
$ fd = open("test_dir/priviledge_id", O_RDWR|O_CREAT|O_EXCL, 02755);
4d2202
4d2202
This will create SGID set executable in test_dir/.
4d2202
4d2202
And that's a problem because now an unpriviliged user can execute it,
4d2202
get egid=0 and get access to resources owned by "root" group. This is
4d2202
privilege escalation.
4d2202
4d2202
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2044863
4d2202
Fixes: CVE-2022-0358
4d2202
Reported-by: JIETAO XIAO <shawtao1125@gmail.com>
4d2202
Suggested-by: Miklos Szeredi <mszeredi@redhat.com>
4d2202
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4d2202
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
4d2202
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
4d2202
Message-Id: <YfBGoriS38eBQrAb@redhat.com>
4d2202
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
4d2202
  dgilbert: Fixed missing {}'s style nit
4d2202
(cherry picked from commit 449e8171f96a6a944d1f3b7d3627ae059eae21ca)
4d2202
---
4d2202
 tools/virtiofsd/passthrough_ll.c | 27 +++++++++++++++++++++++++++
4d2202
 1 file changed, 27 insertions(+)
4d2202
4d2202
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
60061b
index 64b5b4fbb1..b3d0674f6d 100644
4d2202
--- a/tools/virtiofsd/passthrough_ll.c
4d2202
+++ b/tools/virtiofsd/passthrough_ll.c
60061b
@@ -54,6 +54,7 @@
60061b
 #include <sys/wait.h>
4d2202
 #include <sys/xattr.h>
4d2202
 #include <syslog.h>
4d2202
+#include <grp.h>
4d2202
 
60061b
 #include "qemu/cutils.h"
4d2202
 #include "passthrough_helpers.h"
60061b
@@ -1161,6 +1162,30 @@ static void lo_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
4d2202
 #define OURSYS_setresuid SYS_setresuid
4d2202
 #endif
4d2202
 
4d2202
+static void drop_supplementary_groups(void)
4d2202
+{
4d2202
+    int ret;
4d2202
+
4d2202
+    ret = getgroups(0, NULL);
4d2202
+    if (ret == -1) {
4d2202
+        fuse_log(FUSE_LOG_ERR, "getgroups() failed with error=%d:%s\n",
4d2202
+                 errno, strerror(errno));
4d2202
+        exit(1);
4d2202
+    }
4d2202
+
4d2202
+    if (!ret) {
4d2202
+        return;
4d2202
+    }
4d2202
+
4d2202
+    /* Drop all supplementary groups. We should not need it */
4d2202
+    ret = setgroups(0, NULL);
4d2202
+    if (ret == -1) {
4d2202
+        fuse_log(FUSE_LOG_ERR, "setgroups() failed with error=%d:%s\n",
4d2202
+                 errno, strerror(errno));
4d2202
+        exit(1);
4d2202
+    }
4d2202
+}
4d2202
+
4d2202
 /*
4d2202
  * Change to uid/gid of caller so that file is created with
4d2202
  * ownership of caller.
60061b
@@ -3926,6 +3951,8 @@ int main(int argc, char *argv[])
60061b
 
60061b
     qemu_init_exec_dir(argv[0]);
4d2202
 
4d2202
+    drop_supplementary_groups();
4d2202
+
4d2202
     pthread_mutex_init(&lo.mutex, NULL);
4d2202
     lo.inodes = g_hash_table_new(lo_key_hash, lo_key_equal);
4d2202
     lo.root.fd = -1;
4d2202
-- 
4d2202
2.27.0
4d2202