]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Extend the ACL test case to validate filter rule checks
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 27 Jun 2013 16:12:20 +0000 (17:12 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 3 Jul 2013 14:54:54 +0000 (15:54 +0100)
The 'check-aclrules' test case validates that there are ACL
checks in each method. This extends it so that it can also
validate that methods which return info about lists of objects,
will filter their returned info throw an ACL check.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/Makefile.am
src/check-aclrules.pl

index 15a28404768dfa2973c07afa36af703fa688562a..d9e703fea0e98f97127127a6725bc5a353e946ba 100644 (file)
@@ -500,6 +500,7 @@ check-driverimpls:
 
 check-aclrules:
        $(AM_V_GEN)$(PERL) $(srcdir)/check-aclrules.pl \
+               $(addprefix $(srcdir)/,$(filter-out /%,$(REMOTE_PROTOCOL))) \
                $(addprefix $(srcdir)/,$(filter-out /%,$(STATEFUL_DRIVER_SOURCE_FILES)))
 
 EXTRA_DIST += check-driverimpls.pl check-aclrules.pl
index 336b2feaa3a01a0e3e32d099264783e2769c8df2..057517e521f0186d6b6505b396e9149b91ee045e 100644 (file)
@@ -42,6 +42,7 @@ my $intable = 0;
 my $table;
 
 my %acls;
+my %aclfilters;
 
 my %whitelist = (
     "connectClose" => 1,
@@ -73,9 +74,80 @@ my %implwhitelist = (
     "xenUnifiedDomainIsUpdated" => 1,
     "xenUnifiedDomainOpenConsole" => 1,
     );
+my %filterimplwhitelist = (
+    "xenUnifiedConnectListDomains" => 1,
+    "xenUnifiedConnectNumOfDomains" => 1,
+    "xenUnifiedConnectListDefinedDomains" => 1,
+    "xenUnifiedConnectNumOfDefinedDomains" => 1,
+    );
 
 my $lastfile;
 
+sub fixup_name {
+    my $name = shift;
+
+    $name =~ s/Nwfilter/NWFilter/;
+    $name =~ s/Xml$/XML/;
+    $name =~ s/Uri$/URI/;
+    $name =~ s/Uuid$/UUID/;
+    $name =~ s/Id$/ID/;
+    $name =~ s/Mac$/MAC/;
+    $name =~ s/Cpu$/CPU/;
+    $name =~ s/Os$/OS/;
+    $name =~ s/Nmi$/NMI/;
+    $name =~ s/Pm/PM/;
+    $name =~ s/Fstrim$/FSTrim/;
+    $name =~ s/Scsi/SCSI/;
+    $name =~ s/Wwn$/WWN/;
+
+    return $name;
+}
+
+sub name_to_ProcName {
+    my $name = shift;
+
+    my @elems;
+    if ($name =~ /_/ || (lc $name) eq "open" || (lc $name) eq "close") {
+        @elems = split /_/, $name;
+        @elems = map lc, @elems;
+        @elems = map ucfirst, @elems;
+    } else {
+        @elems = $name;
+    }
+    @elems = map { fixup_name($_) } @elems;
+    my $procname = join "", @elems;
+
+    $procname =~ s/^([A-Z])/lc $1/e;
+
+    return $procname;
+}
+
+
+my $proto = shift @ARGV;
+
+open PROTO, "<$proto" or die "cannot read $proto";
+
+my %filtered;
+my $incomment = 0;
+my $filtered = 0;
+while (<PROTO>) {
+    if (m,/\*\*,) {
+        $incomment = 1;
+        $filtered = 0;
+    } elsif ($incomment) {
+        if (m,\*\s\@aclfilter,) {
+            $filtered = 1;
+        } elsif ($filtered &&
+                 m,REMOTE_PROC_(.*)\s+=\s*\d+,) {
+            my $api = name_to_ProcName($1);
+            $filtered{$api} = 1;
+            $incomment = 0;
+        }
+    }
+}
+
+close PROTO;
+
 while (<>) {
     if (!defined $lastfile ||
         $lastfile ne $ARGV) {
@@ -107,6 +179,21 @@ while (<>) {
                 }
             }
             $acls{$maybefunc} = 1;
+        } elsif (m,(\w+)CheckACL,) {
+            # Record the fact that maybefunc contains an
+            # ACL filter call, and make sure it is the right call!
+            my $func = $1;
+            $func =~ s/^vir//;
+            if (!defined $maybefunc) {
+                print "$ARGV:$. Unexpected check '$func' outside function\n";
+                $status = 1;
+            } else {
+                unless ($maybefunc =~ /$func$/i) {
+                    print "$ARGV:$. Mismatch check 'vir${func}CheckACL' for function '$maybefunc'\n";
+                    $status = 1;
+                }
+            }
+            $aclfilters{$maybefunc} = 1;
         } elsif (m,\b(\w+)\(,) {
             # Handles case where we replaced an API with a new
             # one which  adds new parameters, and we're left with
@@ -115,6 +202,9 @@ while (<>) {
             if (exists $acls{$callfunc}) {
                 $acls{$maybefunc} = 1;
             }
+            if (exists $aclfilters{$callfunc}) {
+                $aclfilters{$maybefunc} = 1;
+            }
         }
     }
 
@@ -138,6 +228,13 @@ while (<>) {
                 print "$ARGV:$. Missing ACL check in function '$impl' for '$api'\n";
                 $status = 1;
             }
+
+            if (exists $filtered{$api} &&
+                !exists $aclfilters{$impl} &&
+                !exists $filterimplwhitelist{$impl}) {
+                print "$ARGV:$. Missing ACL filter in function '$impl' for '$api'\n";
+                $status = 1;
+            }
         }
     } elsif (/^(?:static\s+)?(vir(?:\w+)?Driver)\s+/) {
         if ($1 ne "virNWFilterCallbackDriver" &&