File 0016-qemu-bridge-helper-reduce-security-.patch of Package qemu-testsuite.15021

From: Bruce Rogers <brogers@suse.com>
Date: Tue, 2 Aug 2016 11:36:02 -0600
Subject: qemu-bridge-helper: reduce security profile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change from using glib alloc and free routines to those
from libc. Also perform safety measure of dropping privs
to user if configured no-caps.

[BR: BOO#988279]
[BR: for 3.1.1 stable, use strcmp here instead of g_str_equal]
Signed-off-by: Bruce Rogers <brogers@suse.com>
[AF: Rebased for v2.7.0-rc2]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 qemu-bridge-helper.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
index 2c9614e28e..da688d78d5 100644
--- a/qemu-bridge-helper.c
+++ b/qemu-bridge-helper.c
@@ -109,7 +109,7 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
         }
         *argend = 0;
 
-        if (!g_str_equal(cmd, "include") && strlen(arg) >= IFNAMSIZ) {
+        if (!strcmp(cmd, "include") && strlen(arg) >= IFNAMSIZ) {
             fprintf(stderr, "name `%s' too long: %zu\n", arg, strlen(arg));
             fclose(f);
             errno = EINVAL;
@@ -117,7 +117,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
         }
 
         if (strcmp(cmd, "deny") == 0) {
-            acl_rule = g_malloc(sizeof(*acl_rule));
+            acl_rule = calloc(1, sizeof(*acl_rule));
+            if (!acl_rule) {
+                fclose(f);
+                errno = ENOMEM;
+                return -1;
+            }
             if (strcmp(arg, "all") == 0) {
                 acl_rule->type = ACL_DENY_ALL;
             } else {
@@ -126,7 +131,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
             }
             QSIMPLEQ_INSERT_TAIL(acl_list, acl_rule, entry);
         } else if (strcmp(cmd, "allow") == 0) {
-            acl_rule = g_malloc(sizeof(*acl_rule));
+            acl_rule = calloc(1, sizeof(*acl_rule));
+            if (!acl_rule) {
+                fclose(f);
+                errno = ENOMEM;
+                return -1;
+            }
             if (strcmp(arg, "all") == 0) {
                 acl_rule->type = ACL_ALLOW_ALL;
             } else {
@@ -424,6 +434,17 @@ int main(int argc, char **argv)
         goto cleanup;
     }
 
+#ifndef CONFIG_LIBCAP
+    /* avoid sending the fd as root user if running suid to not fool
+     * peer credentials to daemons that dont expect that
+     */
+    if (setuid(getuid()) < 0) {
+        fprintf(stderr, "Failed to drop privileges.\n");
+        ret = EXIT_FAILURE;
+        goto cleanup;
+    }
+#endif
+
     /* write fd to the domain socket */
     if (send_fd(unixfd, fd) == -1) {
         fprintf(stderr, "failed to write fd to unix socket: %s\n",
@@ -445,7 +466,7 @@ cleanup:
     }
     while ((acl_rule = QSIMPLEQ_FIRST(&acl_list)) != NULL) {
         QSIMPLEQ_REMOVE_HEAD(&acl_list, entry);
-        g_free(acl_rule);
+        free(acl_rule);
     }
 
     return ret;
openSUSE Build Service is sponsored by