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

4d2202
From 746e07f2d54908296dde64e97e12ea33a35063e0 Mon Sep 17 00:00:00 2001
4d2202
From: Vivek Goyal <vgoyal@redhat.com>
4d2202
Date: Tue, 25 Jan 2022 13:51:14 -0500
4d2202
Subject: [PATCH] virtiofsd: Drop membership of all supplementary groups
4d2202
 (CVE-2022-0358)
4d2202
4d2202
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
4d2202
RH-MergeRequest: 106: 8.5.0z non-av; virtiofsd security fix - drop secondary groups
4d2202
RH-Commit: [1/1] e39df0b31f3c236675262395b94d5c10e8e3073f
4d2202
RH-Bugzilla: 2048627
4d2202
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
4d2202
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
4d2202
RH-Acked-by: Vivek Goyal <None>
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
  dgilbert: Minor fixup around #includes on backport
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
4d2202
index b47029da89..578131179c 100644
4d2202
--- a/tools/virtiofsd/passthrough_ll.c
4d2202
+++ b/tools/virtiofsd/passthrough_ll.c
4d2202
@@ -63,6 +63,7 @@
4d2202
 #include <sys/xattr.h>
4d2202
 #include <syslog.h>
4d2202
 #include <unistd.h>
4d2202
+#include <grp.h>
4d2202
 
4d2202
 #include "passthrough_helpers.h"
4d2202
 #include "seccomp.h"
4d2202
@@ -1058,6 +1059,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.
4d2202
@@ -3010,6 +3035,8 @@ int main(int argc, char *argv[])
4d2202
     /* Don't mask creation mode, kernel already did that */
4d2202
     umask(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