dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

Blame 0001-virtiofsd-Drop-membership-of-all-supplementary-groups.patch

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