cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

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

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