[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [web PATCH 2/4] Introduce content and tools for managing se
From: |
Daniel P . Berrangé |
Subject: |
[Qemu-devel] [web PATCH 2/4] Introduce content and tools for managing security notices |
Date: |
Thu, 18 Oct 2018 15:52:01 +0100 |
Signed-off-by: Daniel P. Berrangé <address@hidden>
---
_config.yml | 4 +
_includes/nav.html | 3 +-
_layouts/secnotice.html | 22 ++
assets/css/style.css | 47 +++
secnotice/Makefile | 40 +++
secnotice/README-template.md | 78 +++++
secnotice/README.md | 20 ++
secnotice/_scripts/index-html.xsl | 72 +++++
secnotice/_scripts/index-xml | 28 ++
secnotice/_scripts/notice-html.xsl | 286 +++++++++++++++++++
secnotice/_scripts/notice-txt.xsl | 277 ++++++++++++++++++
secnotice/_scripts/report-vulnerable-tags.pl | 135 +++++++++
secnotice/template.xml | 50 ++++
13 files changed, 1061 insertions(+), 1 deletion(-)
create mode 100644 _layouts/secnotice.html
create mode 100644 secnotice/Makefile
create mode 100644 secnotice/README-template.md
create mode 100644 secnotice/README.md
create mode 100644 secnotice/_scripts/index-html.xsl
create mode 100755 secnotice/_scripts/index-xml
create mode 100644 secnotice/_scripts/notice-html.xsl
create mode 100644 secnotice/_scripts/notice-txt.xsl
create mode 100644 secnotice/_scripts/report-vulnerable-tags.pl
create mode 100644 secnotice/template.xml
diff --git a/_config.yml b/_config.yml
index 0a0201c..6fddace 100644
--- a/_config.yml
+++ b/_config.yml
@@ -37,3 +37,7 @@ gems:
exclude:
- Gemfile
- Gemfile.lock
+ - Makefile
+ - secalert/README.md
+ - secalert/README-template.md
+ - secalert/template.xml
diff --git a/_includes/nav.html b/_includes/nav.html
index 241d83e..350de6d 100644
--- a/_includes/nav.html
+++ b/_includes/nav.html
@@ -6,7 +6,8 @@
</li><li {% if current[1] == 'download'
%}class='current'{% endif %}><a href="/download">Download</a>
</li><li {% if current[1] == 'contribute'
%}class='current'{% endif %}><a href="/contribute">Contribute</a>
</li><li {% if current[1] == 'documentation'
%}class='current'{% endif %}><a href="/documentation">Documentation</a>
- </li><li {% if current[1] == 'blog' %}class='current'{%
endif %}><a href="/blog">Blog</a></li>
+ </li><li {% if current[1] == 'blog' %}class='current'{%
endif %}><a href="/blog">Blog</a>
+ </li><li {% if current[1] == 'secnotice'
%}class='current'{% endif %}><a href="/secnotice">Security Notices</a></li>
</ul>
</nav>
diff --git a/_layouts/secnotice.html b/_layouts/secnotice.html
new file mode 100644
index 0000000..b30c036
--- /dev/null
+++ b/_layouts/secnotice.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<!--
+Linear by TEMPLATED
+templated.co @templatedco
+Released for free under the Creative Commons Attribution 3.0 license
(templated.co/license)
+-->
+<html>
+<head>
+ <title>{{ page.title }} - {{ site.title }}</title>
+ {% include assets.html %}
+</head>
+<body class="secnotice">
+
+ {% include nav.html %}
+
+ {{ content }}
+
+ {% include footer.html %}
+ {% include copyright.html %}
+
+</body>
+</html>
diff --git a/assets/css/style.css b/assets/css/style.css
index b828887..dccffb0 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -590,3 +590,50 @@
{
margin-top: 1.5em;
}
+
+/*********************************************************************************/
+/* Security notices
*/
+/*********************************************************************************/
+
+ body.secnotice #main
+ {
+ width: 50%;
+ }
+
+ body.secnotice #sidebar
+ {
+ margin-top: 10em;
+ width: 30%;
+ }
+
+ body.secnotice p.altformat
+ {
+ font-size: smaller;
+ color: inherit;
+ text-align: right;
+ }
+
+ body.secnotice table.repository {
+ border-spacing: 0px;
+ }
+
+ body.secnotice table.repository tbody th {
+ text-align: right;
+ }
+
+ body.secnotice table.repository tbody th,
+ body.secnotice table.repository tbody td {
+ padding: 2px;
+ }
+
+ body.secnotice table.repository tbody td.fixedtag,
+ body.secnotice table.repository tbody td.mergedcommit {
+ background: rgb(240,255,240);
+ }
+ body.secnotice table.repository tbody td.fixedcommit {
+ background: rgb(240,240,255);
+ }
+
+ body.secnotice table.repository thead {
+ background: rgb(240,240,240);
+ }
diff --git a/secnotice/Makefile b/secnotice/Makefile
new file mode 100644
index 0000000..fef2e8c
--- /dev/null
+++ b/secnotice/Makefile
@@ -0,0 +1,40 @@
+
+YEARS = $(wildcard 2???)
+
+INDEX_XML = index.xml $(YEARS:%=%/index.xml)
+INDEX_HTML = $(INDEX_XML:%.xml=%.html)
+
+NOTICE_XML = $(wildcard */???.xml)
+NOTICE_TXT = $(NOTICE_XML:%.xml=%.txt)
+NOTICE_HTML = $(NOTICE_XML:%.xml=%.html)
+
+all: $(INDEX_XML) $(INDEX_HTML) $(NOTICE_TXT) $(NOTICE_HTML)
+
+index.xml: $(NOTICE_XML) _scripts/index-xml Makefile
+ mkdir -p `dirname address@hidden
+ _scripts/index-xml $(sort $(NOTICE_XML)) > $@
+
+index.html: index.xml _scripts/index-html.xsl Makefile
+ xsltproc _scripts/index-html.xsl $< > $@
+
+%/index.xml: $(NOTICE_XML) _scripts/index-xml Makefile
+ mkdir -p `dirname address@hidden
+ DIR=`echo $@ | sed -e 's,/index.xml,,'`
+ rm -f $@
+ _scripts/index-xml $(sort $(wildcard $(@:%/index.xml=%/)???.xml)) > $@
+
+%/index.html: %/index.xml _scripts/index-html.xsl Makefile
+ xsltproc --stringparam permalink $(@:%/index.html=/secnotice/%/)
_scripts/index-html.xsl $< > $@
+
+%.txt: %.xml _scripts/notice-txt.xsl Makefile
+ mkdir -p `dirname address@hidden
+ xsltproc _scripts/notice-txt.xsl $< > $@
+
+%.html: %.xml _scripts/notice-html.xsl Makefile
+ mkdir -p `dirname address@hidden
+ xsltproc _scripts/notice-html.xsl $< > $@
+
+clean:
+ rm -rf index.{xml,html}
+ rm -rf */index.{xml,html}
+ rm -rf */*.{txt,html}
diff --git a/secnotice/README-template.md b/secnotice/README-template.md
new file mode 100644
index 0000000..2b80dca
--- /dev/null
+++ b/secnotice/README-template.md
@@ -0,0 +1,78 @@
+QEMU Security Notice Schema
+===========================
+
+The top level element of a QEMU security notice has a name of
+``security-notice`` and is in an XML namespace of
+``http://qemu.org/xmlns/security-notice/1.0``
+
+Basic metadata
+--------------
+
+The ``id`` element content is a pair of 4 digit numbers uniquely identifying
+the security issue. By convention the first 4 digit number is the year in which
+it was reported and the second number is an integer value that is unique within
+the year, monotonically incrementing from 1. eg the 137th issue reported in
+2013 would have an id of ``2013-0137``
+
+The ``summary`` element is a short, single line description of the flaw,
+ideally 80 characters or less to make it suitable for use in email subject
+lines or git commit messages.
+
+The ``credits`` element provides information on persons involved with the flaw.
+It permits the child elements ``reporter`` or ``patcher`` each of which can be
+repeated zero or more times. Both elements contain two further child elements
+``email`` and ``name`` with the former providing the email address and the
+latter providing the full name. At least one of ``email`` and ``name`` must
+be provided.
+
+The ``lifecycle`` element provides date on key milestones in handling of the
+issue. It contains between one and three child elements, ``reported``,
+``published`` and ``fixed``. The ``reported`` element says the date on which
+the QEMU security received notification of the issue. The ``published`` element
+says the date on which the issue was revealed to the public. The ``fixed``
+element says the date on which the issue was patched in the primary code branch
+(typically GIT master).
+
+The ``reference`` element provides details of related resources. It will have
+one or more child elements which can be either ``advisory`` or ``bug``. An
+``advisory`` element includes a ``type`` and ``id`` attribute where ``type`` is
+currently allowed to be ``CVE`` and ``id`` is the identifier of the report. A
+``bug`` element includes ``tracker`` and ``id`` attributes where ``tracker`` is
+allowed to be ``redhat``, ``debian`` or a short name for another vendors' bug
+tracker.
+
+Descriptive data
+----------------
+
+There are three free form text elements providing descriptive data about the
+issue. The data will usually be inside a CDATA block.
+
+The ``description`` element content is an expanded version of the ``summary``
+element content, describing what the flaw is.
+
+The ``impact`` element content describes the implications of the security
+issue. ie what can a malicious user do with the flaw.
+
+The ``workaround`` element content describes any steps that an administrator
+can take to eliminate or at least mitigate the impact of the flaw.
+
+
+Product data
+------------
+
+The ``product`` element provides information about the codebase of the affected
+products. The ``name`` attribute is the name of a QEMU product, typically based
+on the tar.gz archive name with the suffix stripped. This contains a child
+``repository`` element which is a URL to the master GIT repository. There is
+then one or more ``branch`` elements which details the state of affected
+branches.
+
+The first child of the ``branch`` element is a ``name`` giving the branch name,
+eg ``master``, ``v1.0.1-maint``, etc. There are then zero or more ``tag`` or
+``change`` child elements with a ``state`` attribute of ``vulnerable`` or
+``fixed``. The ``tag`` element content details the name of the GIT tag(s) on
+that branch are vulnerable and which tags are fixed. The ``change`` element
+content details the GIT hash of the change(s) which both introduce and fix the
+flaw. The same vulnerable change hash may appear under multiple ``branch``
+elements since branches will share large portions of their history. The fix
+hash will however usually be different.
diff --git a/secnotice/README.md b/secnotice/README.md
new file mode 100644
index 0000000..643076d
--- /dev/null
+++ b/secnotice/README.md
@@ -0,0 +1,20 @@
+QEMU Security Notices
+=====================
+
+This directory records all QEMU Security Notices that are issued.
+
+Notices must only added to this directory once any embargo is lifted, since the
+GIT repository is fully public.
+
+Notices are written in XML in a file ``$YEAR/$NUM.xml`` eg ``2014/0001.xml``.
+Assign numbers incrementally as new issues are reported. More details on the
+XML format can be found in `README-schema.rst``.
+
+When a new notice is published for the first time, send the text rendering of
+the notice to the address@hidden
+
+When backporting security fixes to ``stable-X.Y`` branches, update the notice
+with details of the backported changeset hash.
+
+When doing a formal stable release, update the notices included with the
release
+tag name.
diff --git a/secnotice/_scripts/index-html.xsl
b/secnotice/_scripts/index-html.xsl
new file mode 100644
index 0000000..71ae716
--- /dev/null
+++ b/secnotice/_scripts/index-html.xsl
@@ -0,0 +1,72 @@
+<!--
+ - This program is free software; you can redistribute it and/or modify
+ - it under the terms of the GNU General Public License as published by
+ - the Free Software Foundation; either version 2 of the License, or
+ - (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU General Public License for more details.
+ -
+ - You should have received a copy of the GNU General Public License
+ - along with this program. If not, see
+ - <http://www.gnu.org/licenses/>.
+ -->
+<xsl:stylesheet
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:qsn="http://qemu.org/xmlns/security-notice/1.0"
+ xmlns:qsnl="http://qemu.org/xmlns/security-notice-list/1.0"
+ exclude-result-prefixes="xsl qsn qsnl"
+ version="1.0">
+
+ <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
+
+ <xsl:param name="permalink" select="'/secnotice/'"/>
+
+ <xsl:template match="/qsnl:security-notice-list">---
+title: QEMU Security Notices
+permalink: <xsl:value-of select="$permalink"/>
+---
+
+ <p>
+ If you believe you have identified a new security issue in QEMU, please
+ follow the <a href="https://wiki.qemu.org/SecurityProcess">security
process</a>
+ to report it in a non-public way. Do <strong>NOT</strong> use the bug
tracker,
+ mailing lists, or IRC to report non-public security issues.
+ </p>
+
+ <ul>
+ <xsl:apply-templates select="qsnl:security-notice">
+ <xsl:sort select="@name" order="descending" />
+ </xsl:apply-templates>
+ </ul>
+
+ <p class="alt">
+ Alternative formats: <a href="index.xml">[xml]</a>
+ </p>
+ </xsl:template>
+
+ <xsl:template name="qsnhref">
+ <xsl:param name="id"/>
+
+ <xsl:variable name="dir" select="substring-before($id, '-')"/>
+ <xsl:variable name="file" select="substring-after($id, '-')"/>
+
+ <xsl:value-of select="concat($dir, '/', $file)"/>
+ </xsl:template>
+
+ <xsl:template match="qsnl:security-notice">
+ <xsl:variable name="notice" select="document(concat('../../', @name))"/>
+ <xsl:variable name="id" select="$notice/qsn:security-notice/qsn:id"/>
+ <xsl:variable name="summary"
select="$notice/qsn:security-notice/qsn:summary"/>
+ <xsl:variable name="href">
+ <xsl:call-template name="qsnhref">
+ <xsl:with-param name="id" select="$id"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <li><a href="{$href}">QSN-<xsl:value-of select="$id"/>: <xsl:value-of
select="$summary"/></a></li>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/secnotice/_scripts/index-xml b/secnotice/_scripts/index-xml
new file mode 100755
index 0000000..67de29f
--- /dev/null
+++ b/secnotice/_scripts/index-xml
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Copyright (C) 2013-2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+echo '<security-notice-list
xmlns="http://qemu.org/xmlns/security-notice-list/1.0">'
+for n in $@
+do
+ echo " <security-notice name='/secnotice/$n'/>"
+done
+echo '</security-notice-list>'
diff --git a/secnotice/_scripts/notice-html.xsl
b/secnotice/_scripts/notice-html.xsl
new file mode 100644
index 0000000..50ba802
--- /dev/null
+++ b/secnotice/_scripts/notice-html.xsl
@@ -0,0 +1,286 @@
+<!--
+ - This program is free software; you can redistribute it and/or modify
+ - it under the terms of the GNU General Public License as published by
+ - the Free Software Foundation; either version 2 of the License, or
+ - (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU General Public License for more details.
+ -
+ - You should have received a copy of the GNU General Public License
+ - along with this program. If not, see
+ - <http://www.gnu.org/licenses/>.
+ -->
+<xsl:stylesheet
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:qsn="http://qemu.org/xmlns/security-notice/1.0"
+ exclude-result-prefixes="xsl qsn"
+ version="1.0">
+
+ <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
+
+ <xsl:template name="selfhref">
+ <xsl:param name="id"/>
+ <xsl:param name="ext"/>
+
+ <xsl:variable name="dir" select="substring-before($id, '-')"/>
+ <xsl:variable name="file" select="substring-after($id, '-')"/>
+
+ <xsl:value-of select="concat('/secnotice/', $dir, '/', $file, $ext)"/>
+ </xsl:template>
+
+ <xsl:template match="/qsn:security-notice">---
+title: 'QSN-<xsl:value-of select="qsn:id"/>: <xsl:value-of
select="qsn:summary"/>'
+layout: secnotice
+permalink: <xsl:call-template name="selfhref">
+ <xsl:with-param name="id" select="qsn:id"/>
+</xsl:call-template>
+---
+
+ <div id="main">
+ <div class="container">
+
+ <h2>
+ <xsl:value-of select="qsn:summary"/>
+ </h2>
+
+ <xsl:apply-templates select="qsn:lifecycle"/>
+ <xsl:apply-templates select="qsn:credits"/>
+
+ <xsl:apply-templates select="qsn:reference"/>
+ <xsl:apply-templates select="qsn:description"/>
+ <xsl:apply-templates select="qsn:impact"/>
+ <xsl:apply-templates select="qsn:mitigation"/>
+
+ <xsl:call-template name="selflink"/>
+ </div>
+ </div>
+
+ <div id="sidebar">
+ <div class="container">
+ <section>
+ <header>
+ <h2>Related commits</h2>
+ </header>
+ <xsl:apply-templates select="qsn:repository"/>
+ </section>
+ </div>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="selflink">
+ <p class="altformat">
+ Alternative formats:
+ <a>
+ <xsl:attribute name="href">
+ <xsl:call-template name="selfhref">
+ <xsl:with-param name="id" select="qsn:id"/>
+ <xsl:with-param name="ext" select="'.xml'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:text>[xml]</xsl:text>
+ </a>
+ <xsl:text> </xsl:text>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:call-template name="selfhref">
+ <xsl:with-param name="id" select="qsn:id"/>
+ <xsl:with-param name="ext" select="'.txt'"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:text>[text]</xsl:text>
+ </a>
+ </p>
+ </xsl:template>
+
+ <xsl:template match="qsn:lifecycle">
+ <h3>Lifecycle</h3>
+ <table>
+ <tr>
+ <th>Reported on:</th>
+ <td><xsl:value-of select="qsn:reported"/></td>
+ </tr>
+ <tr>
+ <th>Published on:</th>
+ <td><xsl:value-of select="qsn:published"/></td>
+ </tr>
+ <tr>
+ <th>Fixed on:</th>
+ <td><xsl:value-of select="qsn:fixed"/></td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="qsn:credits">
+ <h3>Credits</h3>
+ <table>
+ <xsl:for-each select="qsn:reporter">
+ <tr>
+ <xsl:if test="position() = 1">
+ <th>Reported by:</th>
+ </xsl:if>
+ <xsl:if test="position() > 1">
+ <th></th>
+ </xsl:if>
+ <td>
+ <a href="mailto:{qsn:email}"><xsl:value-of select="qsn:name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:patcher">
+ <tr>
+ <xsl:if test="position() = 1">
+ <th>Patched by:</th>
+ </xsl:if>
+ <xsl:if test="position() > 1">
+ <th></th>
+ </xsl:if>
+ <td>
+ <a href="mailto:{qsn:email}"><xsl:value-of select="qsn:name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="qsn:advisory">
+ <xsl:choose>
+ <xsl:when test="@type='CVE'">
+ <a href="https://nvd.nist.gov/vuln/detail/address@hidden">
+ <xsl:text>CVE-</xsl:text>
+ <xsl:value-of select="@id"/>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@type"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="@id"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="qsn:bug">
+ <xsl:value-of select="@tracker"/>
+ <xsl:text> bug #</xsl:text>
+ <xsl:value-of select="@id"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:reference">
+ <h3>See also</h3>
+ <ul>
+ <xsl:for-each select="qsn:advisory|qsn:bug">
+ <li><xsl:apply-templates select="."/></li>
+ </xsl:for-each>
+ </ul>
+ </xsl:template>
+
+ <xsl:template match="qsn:description">
+ <h3>Description</h3>
+ <p>
+ <xsl:value-of select="."/>
+ </p>
+ </xsl:template>
+
+ <xsl:template match="qsn:impact">
+ <h3>Impact</h3>
+ <p>
+ <xsl:value-of select="."/>
+ </p>
+ </xsl:template>
+
+ <xsl:template match="qsn:mitigation">
+ <h3>Mitigation</h3>
+ <p>
+ <xsl:value-of select="."/>
+ </p>
+ </xsl:template>
+
+ <xsl:template name="gitbranch">
+ <xsl:param name="branch"/>
+
+ <a
href="http://git.qemu.org/?p=qemu.git;a=shortlog;h=refs/heads/{$branch}"><xsl:value-of
select="$branch"/></a>
+ </xsl:template>
+
+ <xsl:template name="gittag">
+ <xsl:param name="tag"/>
+
+ <a href="http://git.qemu.org/?p=qemu.git;a=tag;h={$tag}"><xsl:value-of
select="$tag"/></a>
+ </xsl:template>
+
+ <xsl:template name="gitchange">
+ <xsl:param name="change"/>
+
+ <a
href="http://git.qemu.org/?p=qemu.git;a=commit;h={$change}"><xsl:value-of
select="$change"/></a>
+ </xsl:template>
+
+ <xsl:template match="qsn:repository">
+ <xsl:for-each select="qsn:branch">
+ <table class="repository">
+ <thead>
+ <tr>
+ <th colspan="2">Branch:
+ <xsl:call-template name="gitbranch">
+ <xsl:with-param name="branch" select="qsn:name"/>
+ </xsl:call-template>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <xsl:for-each select="qsn:address@hidden'fixed']">
+ <tr>
+ <th>Fixed in:</th>
+ <td class="fixedtag">
+ <xsl:call-template name="gittag">
+ <xsl:with-param name="tag" select="."/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:address@hidden'fixed']">
+ <tr>
+ <th>Fixed by:</th>
+ <td class="fixedcommit">
+ <xsl:call-template name="gitchange">
+ <xsl:with-param name="change" select="."/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:address@hidden'merged']">
+ <tr>
+ <th>Merged by:</th>
+ <td class="mergedcommit">
+ <xsl:call-template name="gitchange">
+ <xsl:with-param name="change" select="."/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:address@hidden'vulnerable']">
+ <tr>
+ <th>Broken in:</th>
+ <td class="brokentag">
+ <xsl:call-template name="gittag">
+ <xsl:with-param name="tag" select="."/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:address@hidden'vulnerable']">
+ <tr>
+ <th>Broken by:</th>
+ <td class="brokencommit">
+ <xsl:call-template name="gitchange">
+ <xsl:with-param name="change" select="."/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </tbody>
+ </table>
+ </xsl:for-each>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/secnotice/_scripts/notice-txt.xsl
b/secnotice/_scripts/notice-txt.xsl
new file mode 100644
index 0000000..dc4c125
--- /dev/null
+++ b/secnotice/_scripts/notice-txt.xsl
@@ -0,0 +1,277 @@
+<!--
+ - This program is free software; you can redistribute it and/or modify
+ - it under the terms of the GNU General Public License as published by
+ - the Free Software Foundation; either version 2 of the License, or
+ - (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU General Public License for more details.
+ -
+ - You should have received a copy of the GNU General Public License
+ - along with this program. If not, see
+ - <http://www.gnu.org/licenses/>.
+ -->
+<xsl:stylesheet
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:qsn="http://qemu.org/xmlns/security-notice/1.0"
+ exclude-result-prefixes="xsl qsn"
+ version="1.0">
+
+ <xsl:output method="text"/>
+
+ <xsl:variable name="nl">
+ <xsl:text>
+</xsl:text>
+ </xsl:variable>
+
+ <!-- based on http://plasmasturm.org/log/xslwordwrap/ -->
+ <!-- Copyright 2010 Aristotle Pagaltzis; under the MIT licence -->
+ <!-- http://www.opensource.org/licenses/mit-license.php -->
+ <xsl:template name="wrap-string">
+ <xsl:param name="str" />
+ <xsl:param name="wrap-col" />
+ <xsl:param name="break-mark" />
+ <xsl:param name="pos" select="0" />
+ <xsl:choose>
+ <xsl:when test="contains( $str, ' ' )">
+ <xsl:variable name="first-word" select="substring-before( $str, ' ' )"
/>
+ <xsl:variable name="pos-now" select="$pos + 1 + string-length(
$first-word )" />
+ <xsl:choose>
+ <xsl:when test="$pos > 0 and $pos-now >= $wrap-col">
+ <xsl:copy-of select="$break-mark" />
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="$str" />
+ <xsl:with-param name="wrap-col" select="$wrap-col" />
+ <xsl:with-param name="break-mark" select="$break-mark" />
+ <xsl:with-param name="pos" select="0" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="$pos > 0">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:value-of select="$first-word" />
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="substring-after( $str, ' ' )"
/>
+ <xsl:with-param name="wrap-col" select="$wrap-col" />
+ <xsl:with-param name="break-mark" select="$break-mark" />
+ <xsl:with-param name="pos" select="$pos-now" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$pos + string-length( $str ) >= $wrap-col">
+ <xsl:copy-of select="$break-mark" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="$pos > 0">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="$str" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="/qsn:security-notice">
+ <xsl:text> QEMU Security Notice: QSN-</xsl:text>
+ <xsl:value-of select="qsn:id"/>
+ <xsl:value-of select="$nl"/>
+ <xsl:text> ==================================</xsl:text>
+ <xsl:value-of select="$nl"/>
+
+ <xsl:value-of select="$nl"/>
+
+
+ <xsl:apply-templates select="qsn:summary"/>
+ <xsl:apply-templates select="qsn:lifecycle"/>
+ <xsl:apply-templates select="qsn:credits"/>
+ <xsl:apply-templates select="qsn:reference"/>
+ <xsl:apply-templates select="qsn:description"/>
+ <xsl:apply-templates select="qsn:impact"/>
+ <xsl:apply-templates select="qsn:mitigation"/>
+ <xsl:apply-templates select="qsn:repository"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:summary">
+ <xsl:text> Summary: </xsl:text>
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="normalize-space(.)"/>
+ <xsl:with-param name="wrap-col" select="52"/>
+ <xsl:with-param name="break-mark" select="concat($nl, '
')"/>
+ </xsl:call-template>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:lifecycle">
+ <xsl:text> Reported on: </xsl:text>
+ <xsl:value-of select="qsn:reported"/>
+ <xsl:value-of select="$nl"/>
+
+ <xsl:text> Published on: </xsl:text>
+ <xsl:value-of select="qsn:published"/>
+ <xsl:value-of select="$nl"/>
+
+ <xsl:text> Fixed on: </xsl:text>
+ <xsl:value-of select="qsn:fixed"/>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:credits">
+ <xsl:text> Reported by: </xsl:text>
+ <xsl:for-each select="qsn:reporter">
+ <xsl:if test="position() > 1">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:value-of select="qsn:name"/>
+ <xsl:text> <</xsl:text>
+ <xsl:value-of select="qsn:email"/>
+ <xsl:text>></xsl:text>
+ <xsl:if test="position() != last()">
+ <xsl:value-of select="$nl"/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:value-of select="$nl"/>
+ <xsl:text> Patched by: </xsl:text>
+ <xsl:for-each select="qsn:patcher">
+ <xsl:if test="position() > 1">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ <xsl:value-of select="qsn:name"/>
+ <xsl:text> <</xsl:text>
+ <xsl:value-of select="qsn:email"/>
+ <xsl:text>></xsl:text>
+ <xsl:if test="position() != last()">
+ <xsl:value-of select="concat(',',$nl)"/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:advisory">
+ <xsl:value-of select="@type"/>
+ <xsl:text>-</xsl:text>
+ <xsl:value-of select="@id"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:bug">
+ <xsl:value-of select="@tracker"/>
+ <xsl:text> bug #</xsl:text>
+ <xsl:value-of select="@id"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:reference">
+ <xsl:text> See also: </xsl:text>
+ <xsl:variable name="refs">
+ <xsl:for-each select="qsn:advisory|qsn:bug">
+ <xsl:apply-templates select="."/>
+ <xsl:if test="position() != last()">
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="$refs"/>
+ <xsl:with-param name="wrap-col" select="52"/>
+ <xsl:with-param name="break-mark" select="concat($nl, '
')"/>
+ </xsl:call-template>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:description">
+ <xsl:text>Description</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:text>-----------</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="normalize-space(.)"/>
+ <xsl:with-param name="wrap-col" select="70"/>
+ <xsl:with-param name="break-mark" select="$nl"/>
+ </xsl:call-template>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:impact">
+ <xsl:text>Impact</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:text>------</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="normalize-space(.)"/>
+ <xsl:with-param name="wrap-col" select="70"/>
+ <xsl:with-param name="break-mark" select="$nl"/>
+ </xsl:call-template>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+ <xsl:template match="qsn:mitigation">
+ <xsl:text>Mitigation</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:text>----------</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ <xsl:call-template name="wrap-string">
+ <xsl:with-param name="str" select="normalize-space(.)"/>
+ <xsl:with-param name="wrap-col" select="70"/>
+ <xsl:with-param name="break-mark" select="$nl"/>
+ </xsl:call-template>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ </xsl:template>
+
+
+ <xsl:template match="qsn:repository">
+ <xsl:text>Related commits</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:text>----------------</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+ <xsl:text> git://git.qemu.org/qemu.git</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:text> https://git.qemu.org/?p=qemu.git</xsl:text>
+ <xsl:value-of select="$nl"/>
+ <xsl:value-of select="$nl"/>
+
+ <xsl:for-each select="qsn:branch">
+ <xsl:text> Branch: </xsl:text>
+ <xsl:value-of select="qsn:name"/>
+ <xsl:value-of select="$nl"/>
+ <xsl:if test="count(qsn:tag)">
+ <xsl:for-each select="qsn:address@hidden'vulnerable']">
+ <xsl:text> Broken in: </xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:value-of select="$nl"/>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:address@hidden'fixed']">
+ <xsl:text> Fixed in: </xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:value-of select="$nl"/>
+ </xsl:for-each>
+ </xsl:if>
+ <xsl:if test="count(qsn:change)">
+ <xsl:for-each select="qsn:address@hidden'vulnerable']">
+ <xsl:text> Broken by: </xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:value-of select="$nl"/>
+ </xsl:for-each>
+ <xsl:for-each select="qsn:address@hidden'fixed']">
+ <xsl:text> Fixed by: </xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:value-of select="$nl"/>
+ </xsl:for-each>
+ </xsl:if>
+ <xsl:value-of select="$nl"/>
+ </xsl:for-each>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/secnotice/_scripts/report-vulnerable-tags.pl
b/secnotice/_scripts/report-vulnerable-tags.pl
new file mode 100644
index 0000000..3b89efd
--- /dev/null
+++ b/secnotice/_scripts/report-vulnerable-tags.pl
@@ -0,0 +1,135 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Sort::Versions;
+
+if (int(@ARGV) != 1 && int (@ARGV) != 2) {
+ die "syntax: $0 BROKEN-COMMIT [MERGED-COMMIT]\n";
+}
+
+my $broken = shift @ARGV;
+my $merged = 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/(stable-.*)$,) {
+ push @branches, $1;
+ }
+ }
+
+ close GIT;
+
+ return @branches;
+}
+
+my @branches;
+my %tags;
+my %branches;
+
+my %merged;
+my $mergedtag;
+
+if (defined $merged) {
+ for my $tag (get_tags("--contains", $merged)) {
+ $merged{$tag} = 1;
+ $mergedtag = $tag unless defined $mergedtag;
+ }
+}
+
+$branches{"master"} = [];
+# Most tags live on master so lets get them first
+for my $tag (get_tags("--contains", $broken, "--merged", "master")) {
+ next if exists $merged{$tag};
+ 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", $broken)) {
+
+ next if exists $tags{$tag};
+ next if exists $merged{$tag};
+ next if $tag =~ /v\d+\.\d+\.9\d/;
+
+ my @tagbranches = get_branch($tag);
+ if (int(@tagbranches) == 0) {
+ if ($tag =~ "^v0.10") {
+ @tagbranches = ("stable-0.10")
+ } elsif ($tag =~ "^v0") {
+ @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";
+ if ($branch eq "master") {
+ print " <change state=\"fixed\"></change>\n";
+ if (defined $merged) {
+ print " <change state=\"merged\">$merged</change>\n";
+ } else {
+ print " <change state=\"merged\"></change>\n";
+ }
+ if (defined $mergedtag) {
+ print " <tag state=\"fixed\">$mergedtag</tag>\n";
+ } else {
+ print " <tag state=\"fixed\"></tag>\n";
+ }
+ }
+
+ foreach my $tag (sort versioncmp @{$branches{$branch}}) {
+ print " <tag state=\"vulnerable\">$tag</tag>\n";
+ }
+ print " <change state=\"vulnerable\">$broken</change>\n";
+
+ print " </branch>\n";
+}
diff --git a/secnotice/template.xml b/secnotice/template.xml
new file mode 100644
index 0000000..8f8a0d4
--- /dev/null
+++ b/secnotice/template.xml
@@ -0,0 +1,50 @@
+<security-notice xmlns="http://qemu.org/xmlns/security-notice/1.0">
+ <id>XXXX-XXX</id>
+
+ <summary></summary>
+
+ <description>
+<![CDATA[]]>
+ </description>
+
+ <impact>
+<![CDATA[]]>
+ </impact>
+
+ <workaround>
+<![CDATA[]]>
+ </workaround>
+
+ <credits>
+ <reporter>
+ <name></name>
+ <email></email>
+ </reporter>
+ <patcher>
+ <name></name>
+ <email></email>
+ </patcher>
+ </credits>
+
+ <lifecycle>
+ <reported></reported>
+ <published></published>
+ <fixed></fixed>
+ </lifecycle>
+
+ <reference>
+ <advisory type="CVE" id="XXXX-XXXX"/>
+ </reference>
+
+ <repository>
+ <branch>
+ <name>master</name>
+ <tag state="fixed"></tag>
+ <change state="fixed"></change>
+ <change state="merged"></change>
+ <change state="vulnerable"></change>
+ <tag state="vulnerable"></tag>
+ </branch>
+ </repository>
+
+</security-notice>
--
2.17.2