[libvirt] [PATCH security-notice 4/4] Add a script for generating a list of vulnerable tags & branches

Daniel P. Berrangé berrange at redhat.com
Tue Mar 13 17:27:37 UTC 2018


It is rather tedious making the list of vulnerable tags and branches
for the security notice reports. This script takes the changeset of
the commit that first introduced the flaw and then outputs an XML
snippet listing every tag and branch which contains that vulnerable
changeset. This can be copied straight into the security notice,
meaning we just have to then fill out details of which changeset
and tag fixed the flaw.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 scripts/report-vulnerable-tags.pl | 108 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)
 create mode 100644 scripts/report-vulnerable-tags.pl

diff --git a/scripts/report-vulnerable-tags.pl b/scripts/report-vulnerable-tags.pl
new file mode 100644
index 0000000..0b6ea6f
--- /dev/null
+++ b/scripts/report-vulnerable-tags.pl
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Sort::Versions;
+
+if (int(@ARGV) != 1) {
+    die "syntax: $0 CHANGESET\n";
+}
+
+my $changeset = shift @ARGV;
+
+sub get_tags {
+    my @args = @_;
+
+    my @tags;
+    open GIT, "-|", "git", "tag", @args or
+    die "cannot query 'git tags @args': $!\n";
+
+    while (<GIT>) {
+        chomp;
+
+        # Drop anything except  vN.N.N style tags
+        # where 'N' is only digits.
+        if (/^v(\d+)(\.\d+)+$/) {
+            push @tags, $_;
+        }
+    }
+
+    close GIT;
+
+    return @tags;
+}
+
+sub get_branch {
+    my $tag = shift;
+
+    my @branches;
+    open GIT, "-|", "git", "branch", "--all", "--contains", $tag or
+    die "cannot query 'git branch --all --contains $tag': $!\n";
+
+    while (<GIT>) {
+        chomp;
+
+        if (m,^\s*remotes/origin/(v.*-maint)$,) {
+            push @branches, $1;
+        }
+    }
+
+    close GIT;
+
+    return @branches;
+}
+
+my @branches;
+my %tags;
+my %branches;
+
+$branches{"master"} = [];
+# Most tags live on master so lets get them first
+for my $tag (get_tags("--contains", $changeset, "--merged", "master")) {
+    push @{$branches{"master"}}, $tag;
+    $tags{$tag} = 1;
+}
+push @branches, "master";
+
+# Now we need slower work to find branches for
+# few remaining tags
+for my $tag (get_tags("--contains", $changeset)) {
+
+    next if exists $tags{$tag};
+
+    my @tagbranches = get_branch($tag);
+    if (int(@tagbranches) == 0) {
+	if ($tag eq "v2.1.0") {
+	    @tagbranches = ("master")
+	} else {
+	    print "Tag $tag doesn't appear in any branch\n";
+	    next;
+	}
+    }
+
+    if (int(@tagbranches) > 1) {
+        print "Tag $tag appears in multiple branches\n";
+    }
+
+    unless (exists($branches{$tagbranches[0]})) {
+        $branches{$tagbranches[0]} = [];
+        push @branches, $tagbranches[0];
+    }
+    push @{$branches{$tagbranches[0]}}, $tag;
+}
+
+
+foreach my $branch (sort versioncmp @branches) {
+    print "    <branch>\n";
+    print "      <name>$branch</name>\n";
+    foreach my $tag (sort versioncmp @{$branches{$branch}}) {
+        print "      <tag state=\"vulnerable\">$tag</tag>\n";
+    }
+    print "      <change state=\"vulnerable\">$changeset</change>\n";
+
+    if ($branch eq "master") {
+	print "      <change state=\"fixed\"></change>\n";
+    }
+    print "    </branch>\n";
+}
-- 
2.14.3




More information about the libvir-list mailing list