File 50864dcd-CVE-2020-25637.patch of Package libvirt.16761

commit 50864dcda191eb35732dbd80fb6ca251a6bba923
Author: Ján Tomko <jtomko@redhat.com>
Date:   Fri Sep 18 16:09:25 2020 +0200

    rpc: add support for filtering @acls by uint params
    
    CVE-2020-25637
    
    Add a new field to @acl annotations for filtering by
    unsigned int parameters.
    
    Signed-off-by: Ján Tomko <jtomko@redhat.com>
    Reviewed-by: Jiri Denemark <jdenemar@redhat.com>

Index: libvirt-5.1.0/src/remote/remote_protocol.x
===================================================================
--- libvirt-5.1.0.orig/src/remote/remote_protocol.x
+++ libvirt-5.1.0/src/remote/remote_protocol.x
@@ -3599,6 +3599,7 @@ enum remote_procedure {
      *
      * - @acl: <object>:<permission>
      * - @acl: <object>:<permission>:<flagname>
+     * - @acl: <object>:<permission>::<param>:<value>
      *
      *   Declare the access control requirements for the API. May be repeated
      *   multiple times, if multiple rules are required.
@@ -3608,6 +3609,8 @@ enum remote_procedure {
      *     <permission> is one of the permissions in access/viraccessperm.h
      *     <flagname> indicates the rule only applies if the named flag
      *     is set in the API call
+     *     <param> and <value> can be used to check an unsigned int parameter
+     *     against value
      *
      * - @aclfilter: <object>:<permission>
      *
Index: libvirt-5.1.0/src/rpc/gendispatch.pl
===================================================================
--- libvirt-5.1.0.orig/src/rpc/gendispatch.pl
+++ libvirt-5.1.0/src/rpc/gendispatch.pl
@@ -2097,10 +2097,12 @@ elsif ($mode eq "client") {
             my @acl;
             foreach (@{$acl}) {
                 my @bits = split /:/;
-                push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2] }
+                push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2],
+                             param => $bits[3], value => $bits[4] }
             }
 
             my $checkflags = 0;
+            my $paramtocheck = undef;
             for (my $i = 1 ; $i <= $#acl ; $i++) {
                 if ($acl[$i]->{object} ne $acl[0]->{object}) {
                     die "acl for '$call->{ProcName}' cannot check different objects";
@@ -2108,6 +2110,9 @@ elsif ($mode eq "client") {
                 if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) {
                     $checkflags = 1;
                 }
+                if (defined $acl[$i]->{param}) {
+                    $paramtocheck = $acl[$i]->{param};
+                }
             }
 
             my $apiname = $prefix . $call->{ProcName};
@@ -2141,6 +2146,9 @@ elsif ($mode eq "client") {
             if ($checkflags) {
                 push @argdecls, "unsigned int flags";
             }
+            if (defined $paramtocheck) {
+                push @argdecls, "unsigned int " . $paramtocheck;
+            }
 
             my $ret;
             my $pass;
@@ -2199,6 +2207,17 @@ elsif ($mode eq "client") {
                         }
                         print "        ";
                     }
+                    if (defined $acl->{param}) {
+                        my $param = $acl->{param};
+                        my $value = $acl->{value};
+                        if ($value =~ /^\!/) {
+                            $value = substr $value, 1;
+                            print "($param != ($value)) &&\n";
+                        } else {
+                            print "($param == ($value)) &&\n";
+                        }
+                        print "        ";
+                    }
                     print "(rv = $method(" . join(", ", @argvars, $perm) . ")) <= 0) {\n";
                     print "        virObjectUnref(mgr);\n";
                     if ($action eq "Ensure") {
openSUSE Build Service is sponsored by