Add today's advisory and notices.
Approved by: so Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
5f4afae871
commit
94c673d390
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=51892
8 changed files with 804 additions and 0 deletions
144
share/security/advisories/FreeBSD-EN-18:07.pmap.asc
Normal file
144
share/security/advisories/FreeBSD-EN-18:07.pmap.asc
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
|
Hash: SHA512
|
||||||
|
|
||||||
|
=============================================================================
|
||||||
|
FreeBSD-EN-18:07.pmap Errata Notice
|
||||||
|
The FreeBSD Project
|
||||||
|
|
||||||
|
Topic: Incorrect TLB shootdown for Xen based guests
|
||||||
|
|
||||||
|
Category: core
|
||||||
|
Module: kernel
|
||||||
|
Announced: 2018-06-21
|
||||||
|
Credits: Colin Percival
|
||||||
|
Affects: FreeBSD 11.1
|
||||||
|
Corrected: 2018-05-22 14:36:46 UTC (stable/11, 11.2-BETA2)
|
||||||
|
2018-06-21 05:18:08 UTC (releng/11.1, 11.1-RELEASE-p11)
|
||||||
|
|
||||||
|
For general information regarding FreeBSD Errata Notices and Security
|
||||||
|
Advisories, including descriptions of the fields above, security
|
||||||
|
branches, and the following sections, please visit
|
||||||
|
<URL:https://security.FreeBSD.org/>.
|
||||||
|
|
||||||
|
I. Background
|
||||||
|
|
||||||
|
CPUs rely on a Translation Lookaside Buffer (TLB) to cache virtual memory
|
||||||
|
paging information. When a page is unmapped from the virtual address space
|
||||||
|
of a process on a multiprocessor system, an Inter-Processor Interrupt (IPI)
|
||||||
|
may be sent to instruct other CPUs to invalidate ("shoot down") their TLB
|
||||||
|
entries for the addresses in question.
|
||||||
|
|
||||||
|
For virtualization-related performance reasons, FreeBSD has IPI code for the
|
||||||
|
Xen platform which is separate from the generic x86 IPI code.
|
||||||
|
|
||||||
|
II. Problem Description
|
||||||
|
|
||||||
|
In the course of changes to the FreeBSD virtual memory system to address
|
||||||
|
FreeBSD-SA-18:03.speculative_execution, changes were made to the IPIs used
|
||||||
|
for shooting down TLB entries. Unfortunately, the IPI handlers for Xen were
|
||||||
|
left non-PTI, even when PTI was enabled, which result in TLB shootdowns for
|
||||||
|
the user mode portion of the address space not being consistently performed
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
III. Impact
|
||||||
|
|
||||||
|
Processes on Xen based guests may "see" pages of memory which were previously
|
||||||
|
mapped but have since been unmapped, resulted in data being corrupted and/or
|
||||||
|
processes crashing due to internal data structures becoming inconsistent.
|
||||||
|
|
||||||
|
IV. Workaround
|
||||||
|
|
||||||
|
Only Xen based guests are affected by this issue. All other platforms are
|
||||||
|
not susceptible.
|
||||||
|
|
||||||
|
For Xen based guests, disabling PTI will workaround the issue. Add the
|
||||||
|
following line to /boot/loader.conf:
|
||||||
|
vm.pmap.pti=0
|
||||||
|
|
||||||
|
Please be aware, by disabling PTI, the system will be vulnerable to
|
||||||
|
FreeBSD-SA-18:03.speculative_execution.
|
||||||
|
|
||||||
|
V. Solution
|
||||||
|
|
||||||
|
Perform one of the following:
|
||||||
|
|
||||||
|
1) Upgrade your system to a supported FreeBSD stable or release / security
|
||||||
|
branch (releng) dated after the correction date.
|
||||||
|
|
||||||
|
Afterward, reboot the system.
|
||||||
|
|
||||||
|
2) To update your system via a binary patch:
|
||||||
|
|
||||||
|
Systems running a RELEASE version of FreeBSD on the i386 or amd64
|
||||||
|
platforms can be updated via the freebsd-update(8) utility:
|
||||||
|
|
||||||
|
# freebsd-update fetch
|
||||||
|
# freebsd-update install
|
||||||
|
|
||||||
|
Afterward, reboot the system.
|
||||||
|
|
||||||
|
3) To update your system via a source code patch:
|
||||||
|
|
||||||
|
The following patches have been verified to apply to the applicable
|
||||||
|
FreeBSD release branches.
|
||||||
|
|
||||||
|
a) Download the relevant patch from the location below, and verify the
|
||||||
|
detached PGP signature using your PGP utility.
|
||||||
|
|
||||||
|
[FreeBSD 11.1]
|
||||||
|
# fetch https://security.FreeBSD.org/patches/EN-18:07/pmap.patch
|
||||||
|
# fetch https://security.FreeBSD.org/patches/EN-18:07/pmap.patch.asc
|
||||||
|
# gpg --verify pmap.patch.asc
|
||||||
|
|
||||||
|
b) Apply the patch. Execute the following commands as root:
|
||||||
|
|
||||||
|
# cd /usr/src
|
||||||
|
# patch < /path/to/patch
|
||||||
|
|
||||||
|
c) Recompile your kernel as described in
|
||||||
|
<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
|
||||||
|
system.
|
||||||
|
|
||||||
|
VI. Correction details
|
||||||
|
|
||||||
|
The following list contains the correction revision numbers for each
|
||||||
|
affected branch.
|
||||||
|
|
||||||
|
Branch/path Revision
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
stable/11/ r334047
|
||||||
|
releng/11.1/ r335466
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
To see which files were modified by a particular revision, run the
|
||||||
|
following command, replacing NNNNNN with the revision number, on a
|
||||||
|
machine with Subversion installed:
|
||||||
|
|
||||||
|
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
|
||||||
|
|
||||||
|
Or visit the following URL, replacing NNNNNN with the revision number:
|
||||||
|
|
||||||
|
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
|
||||||
|
|
||||||
|
VII. References
|
||||||
|
|
||||||
|
The latest revision of this notice is available at
|
||||||
|
<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-18:07.pmap.asc>
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN3hfFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
|
||||||
|
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
|
||||||
|
5cIOow/+P+zdQ8dmZcEIy7HjYdpTAbPIGNnSdvuXV5O5XGamOziTJOuEEDBxeNiE
|
||||||
|
QE9VM8a94Ybl0CJZhfBVPhqrDpYuXOqKvnfHlcXWjppDliUPWohF6kTj4ugqGKrl
|
||||||
|
T2VckEvjltgJQ1/XqnkE7n1LuezLcqF/RbW3xOeRkAhf3X+IXd/E3uCuw/n4yknl
|
||||||
|
O5EvLmjq3bGlN7OfHOM4E+PHvYOxxfbjYH5S+1Z9g0/apR6HOUi9WU0hV5YEB9Cz
|
||||||
|
hUCsnx15Nla97jD9P1xy0tr3FkPpvZRJGj2BelNaQoFNrZB7oWB9xwOmwSqxye/b
|
||||||
|
zvp+/WUuGlo1KWU8RldzVPP6A7piuL6oAvYqW8/wcpwd9HqNGXblWz1XodpE3x1F
|
||||||
|
TKHTGcP/e/wgU6810SolylwJKxhGVZaQK3UH1iVKPRRTw+HUR1OVDY+q7XAyFD7c
|
||||||
|
QbKRyWQIYr2X98LhiT8TMVssharFg7AcviRSDEdCYt+A6S9jiDWMe+C3hGndSSET
|
||||||
|
Cf/0q6PQ89GQKw3lQOgwvtWlMaKPwfg3W8lxkusK5o935aXWhbRee3Hzkld7eUl0
|
||||||
|
8/uGBCgDnSk7hPIHLDcddIKI+QT0IpHKCPlBRRoTJUhpXo/g5bVkbUnMKBZ7zf3O
|
||||||
|
mBvci+KPc2yqp///fw1eMhgRTOOOOnXAHUMsb/FH1b+yIcikudo=
|
||||||
|
=fw9I
|
||||||
|
-----END PGP SIGNATURE-----
|
147
share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc
Normal file
147
share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
|
Hash: SHA512
|
||||||
|
|
||||||
|
=============================================================================
|
||||||
|
FreeBSD-SA-18:07.lazyfpu Security Advisory
|
||||||
|
The FreeBSD Project
|
||||||
|
|
||||||
|
Topic: Lazy FPU State Restore Information Disclosure
|
||||||
|
|
||||||
|
Category: core
|
||||||
|
Module: kernel
|
||||||
|
Announced: 2018-06-21
|
||||||
|
Credits: Julian Stecklina from Amazon Germany
|
||||||
|
Thomas Prescher from Cyberus Technology GmbH
|
||||||
|
Zdenek Sojka from SYSGO AG
|
||||||
|
Colin Percival
|
||||||
|
Affects: All supported version of FreeBSD.
|
||||||
|
Corrected: 2018-06-14 18:50:49 UTC (stable/11, 11.2-PRERELEASE)
|
||||||
|
2018-06-15 13:21:37 UTC (releng/11.2, 11.2-RC3)
|
||||||
|
2018-06-21 05:17:13 UTC (releng/11.1, 11.1-RELEASE-p11)
|
||||||
|
CVE Name: CVE-2018-3665
|
||||||
|
|
||||||
|
Special Note: This advisory only addresses this issue for FreeBSD 11.x on
|
||||||
|
i386 and amd64. We expect to update this advisory to include
|
||||||
|
10.x in the near future.
|
||||||
|
|
||||||
|
For general information regarding FreeBSD Security Advisories,
|
||||||
|
including descriptions of the fields above, security branches, and the
|
||||||
|
following sections, please visit <URL:https://security.FreeBSD.org/>.
|
||||||
|
|
||||||
|
I. Background
|
||||||
|
|
||||||
|
Modern CPUs have a floating point unit (FPU) which needs to maintain state
|
||||||
|
per thread. One technique is to only save and to only restore the FPU state
|
||||||
|
for a thread when a thread attempts to utilize the FPU. This technique is
|
||||||
|
called Lazy FPU state restore.
|
||||||
|
|
||||||
|
II. Problem Description
|
||||||
|
|
||||||
|
A subset of Intel processors can allow a local thread to infer data from
|
||||||
|
another thread through a speculative execution side channel when Lazy FPU
|
||||||
|
state restore is used.
|
||||||
|
|
||||||
|
III. Impact
|
||||||
|
|
||||||
|
Any local thread can potentially read FPU state information from other
|
||||||
|
threads running on the host. This could include cryptographic keys when the
|
||||||
|
AES-NI CPU feature is present.
|
||||||
|
|
||||||
|
IV. Workaround
|
||||||
|
|
||||||
|
No workaround is available, but non-Intel branded CPUs are not believed
|
||||||
|
to be vulnerable.
|
||||||
|
|
||||||
|
V. Solution
|
||||||
|
|
||||||
|
The patch changes from Lazy FPU state restore to Eager FPU state restore.
|
||||||
|
This new technique is the recommended practice from Intel and in some cases
|
||||||
|
can actually increase performance, depending on workload.
|
||||||
|
|
||||||
|
Perform one of the following:
|
||||||
|
|
||||||
|
1) Upgrade your vulnerable system to a supported FreeBSD stable or
|
||||||
|
release / security branch (releng) dated after the correction date.
|
||||||
|
|
||||||
|
Afterward, reboot the system.
|
||||||
|
|
||||||
|
2) To update your vulnerable system via a binary patch:
|
||||||
|
|
||||||
|
Systems running a RELEASE version of FreeBSD on the i386 or amd64
|
||||||
|
platforms can be updated via the freebsd-update(8) utility:
|
||||||
|
|
||||||
|
# freebsd-update fetch
|
||||||
|
# freebsd-update install
|
||||||
|
|
||||||
|
Afterward, reboot the system.
|
||||||
|
|
||||||
|
3) To update your vulnerable system via a source code patch:
|
||||||
|
|
||||||
|
The following patches have been verified to apply to the applicable
|
||||||
|
FreeBSD release branches.
|
||||||
|
|
||||||
|
a) Download the relevant patch from the location below, and verify the
|
||||||
|
detached PGP signature using your PGP utility.
|
||||||
|
|
||||||
|
[FreeBSD 11.1]
|
||||||
|
# fetch https://security.FreeBSD.org/patches/SA-18:07/lazyfpu-11.patch
|
||||||
|
# fetch https://security.FreeBSD.org/patches/SA-18:07/lazyfpu-11.patch.asc
|
||||||
|
# gpg --verify lazyfpu-11.patch.asc
|
||||||
|
|
||||||
|
b) Apply the patch. Execute the following commands as root:
|
||||||
|
|
||||||
|
# cd /usr/src
|
||||||
|
# patch < /path/to/patch
|
||||||
|
|
||||||
|
c) Recompile your kernel as described in
|
||||||
|
<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
|
||||||
|
system.
|
||||||
|
|
||||||
|
VI. Correction details
|
||||||
|
|
||||||
|
The following list contains the correction revision numbers for each
|
||||||
|
affected branch.
|
||||||
|
|
||||||
|
Branch/path Revision
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
stable/11/ r335169
|
||||||
|
releng/11.2/ r335196
|
||||||
|
releng/11.1/ r335465
|
||||||
|
- -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
To see which files were modified by a particular revision, run the
|
||||||
|
following command, replacing NNNNNN with the revision number, on a
|
||||||
|
machine with Subversion installed:
|
||||||
|
|
||||||
|
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
|
||||||
|
|
||||||
|
Or visit the following URL, replacing NNNNNN with the revision number:
|
||||||
|
|
||||||
|
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
|
||||||
|
|
||||||
|
VII. References
|
||||||
|
|
||||||
|
<URL:https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00145.html>
|
||||||
|
|
||||||
|
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3665>
|
||||||
|
|
||||||
|
The latest revision of this advisory is available at
|
||||||
|
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-18:07.lazyfpu.asc>
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN1hfFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
|
||||||
|
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
|
||||||
|
5cJTLA/+Kt7QLkNCVudaiE+d+VMuC2f1aGhqoyd+36xL9rNsn2ShZhIo+gq1dhXn
|
||||||
|
2lJiOYCPN5cJkasj1YdP2bSIv25nTcFMp0rKOww0A1scOnzi66LAD+DXmGVUhmaA
|
||||||
|
MPyrnuL7rbuPq9ls9FGAO2XURwB9IrGYtqPuVWmNyn+HyKBYcGCkL5+UEnHeUCg8
|
||||||
|
oopJudZgrGBVMFCsqG6K/b+3uc397Hyq0PZzpyWFfkaxrbTwVMMwgWyTxIYaPVs7
|
||||||
|
2g7WK2JWjJNk0IWQGot9qpKYDRyxc9PPFX/0blwOLe1Wwrt5nEF+9av89HQJ6PXF
|
||||||
|
+Ws5w8Gnhi9wWuK19ew1j0nvP+f0zw09r4GuEzhZXADAz733HNK5dtsS/dMJi2wa
|
||||||
|
9fQ0s1joT3JFDvWZKUQS2mNuhpvBfYoI0d0OEJT2H2eycFYe4B+VNhB2V1e9wLn6
|
||||||
|
9X4+Vbc2LEOF09klQQFMYNMEyQzLtfq2gHIoD37sCw9mMrYKWjgy3NhY5AKrfGHG
|
||||||
|
OcBsvnaXCW/x9/kV9Pfoel/psrmjcQdp4QEKAZbRNwvJG5sGhtsQXTp0Nk+BCuVy
|
||||||
|
G0NNB9306dLfk0OTZ02SiOUjVagXObyo+LgWTBO6FryDlHVkopsYNkB5oRx9fLrm
|
||||||
|
68r7OXidl0ndGqnh87meMVH1/Fu/rr09Jd4osIzS+Gc0Dt7NOEQ=
|
||||||
|
=8fnI
|
||||||
|
-----END PGP SIGNATURE-----
|
78
share/security/patches/EN-18:07/pmap.patch
Normal file
78
share/security/patches/EN-18:07/pmap.patch
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
--- sys/x86/xen/xen_apic.c.orig
|
||||||
|
+++ sys/x86/xen/xen_apic.c
|
||||||
|
@@ -41,6 +41,7 @@
|
||||||
|
#include <machine/cpufunc.h>
|
||||||
|
#include <machine/cpu.h>
|
||||||
|
#include <machine/intr_machdep.h>
|
||||||
|
+#include <machine/md_var.h>
|
||||||
|
#include <machine/smp.h>
|
||||||
|
|
||||||
|
#include <x86/apicreg.h>
|
||||||
|
@@ -439,6 +440,46 @@
|
||||||
|
invltlb_pcid_handler();
|
||||||
|
return (FILTER_HANDLED);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xen_invltlb_invpcid_pti(void *arg)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ invltlb_invpcid_pti_handler();
|
||||||
|
+ return (FILTER_HANDLED);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xen_invlpg_invpcid_handler(void *arg)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ invlpg_invpcid_handler();
|
||||||
|
+ return (FILTER_HANDLED);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xen_invlpg_pcid_handler(void *arg)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ invlpg_pcid_handler();
|
||||||
|
+ return (FILTER_HANDLED);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xen_invlrng_invpcid_handler(void *arg)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ invlrng_invpcid_handler();
|
||||||
|
+ return (FILTER_HANDLED);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xen_invlrng_pcid_handler(void *arg)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ invlrng_pcid_handler();
|
||||||
|
+ return (FILTER_HANDLED);
|
||||||
|
+}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -529,8 +570,18 @@
|
||||||
|
|
||||||
|
#ifdef __amd64__
|
||||||
|
if (pmap_pcid_enabled) {
|
||||||
|
- xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = invpcid_works ?
|
||||||
|
- xen_invltlb_invpcid : xen_invltlb_pcid;
|
||||||
|
+ if (pti)
|
||||||
|
+ xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter =
|
||||||
|
+ invpcid_works ? xen_invltlb_invpcid_pti :
|
||||||
|
+ xen_invltlb_pcid;
|
||||||
|
+ else
|
||||||
|
+ xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter =
|
||||||
|
+ invpcid_works ? xen_invltlb_invpcid :
|
||||||
|
+ xen_invltlb_pcid;
|
||||||
|
+ xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = invpcid_works ?
|
||||||
|
+ xen_invlpg_invpcid_handler : xen_invlpg_pcid_handler;
|
||||||
|
+ xen_ipis[IPI_TO_IDX(IPI_INVLRNG)].filter = invpcid_works ?
|
||||||
|
+ xen_invlrng_invpcid_handler : xen_invlrng_pcid_handler;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CPU_FOREACH(i)
|
18
share/security/patches/EN-18:07/pmap.patch.asc
Normal file
18
share/security/patches/EN-18:07/pmap.patch.asc
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN4FfFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
|
||||||
|
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
|
||||||
|
5cI6+Q//dTnLur/Dtcz8y2b00OBdUvC1GL3kcFjFhk/fwcvceIdY1m6cC6u6ypxp
|
||||||
|
Mehewv2YENgLw0fkIu61OsqtyCDmQ+O1LKuFNZpkYqPuiVRvhwAlXTHEWjVHmP8f
|
||||||
|
52oSgspKxuZbpMKIDIZaQUiH3Ff7BcGIx8ru50wcsfe4dWXD0YJebqkK1etPuUYV
|
||||||
|
HuMNrqbq7cH8BgBBaRzlAABqz6qeXjLZryyE3bDT4QGEdQPvyrs0muj/TtKzqmZB
|
||||||
|
axX/V+aClQwnXARQ+EhGxCHDU+OoX4inH1N20+ZPwq7aGTjo0B19Yo/03cV1C7vs
|
||||||
|
3NDJWKk4oxM6QP1bUIYZ37qlX+WSXH25q8PGtWucd/YdVZR04iXOwC4G1ncmEUWi
|
||||||
|
1jEj9V7FOBzoLqCGdL2izibemVbKjza5FvODW2gq+Xzbe2F4eube0v12wOiLRED/
|
||||||
|
mTn71RWsImgzsRvywIsGMkaZCZm4j7gWi53dgBqNteitmw75esM000tcKhy5T5yl
|
||||||
|
VuxkhttAODFAujz7k4BRpUebzAf0autiRjec6QTHWek5jqD+bM3nGnlPVJMIzQrX
|
||||||
|
GVibFJga+zrqHhXVXAEKM6QEgcF4nPOlwWOIJ1mBGxomnCM5dKt+Fr1W9lFsurun
|
||||||
|
w83zqwX12Wz+gUENgBYeAawk9O86KoXC0gqf2pphjPnihN6x7Pc=
|
||||||
|
=6sV+
|
||||||
|
-----END PGP SIGNATURE-----
|
373
share/security/patches/SA-18:07/lazyfpu-11.patch
Normal file
373
share/security/patches/SA-18:07/lazyfpu-11.patch
Normal file
|
@ -0,0 +1,373 @@
|
||||||
|
--- sys/amd64/amd64/cpu_switch.S.orig
|
||||||
|
+++ sys/amd64/amd64/cpu_switch.S
|
||||||
|
@@ -105,10 +105,10 @@
|
||||||
|
|
||||||
|
/* have we used fp, and need a save? */
|
||||||
|
cmpq %rdi,PCPU(FPCURTHREAD)
|
||||||
|
- jne 3f
|
||||||
|
+ jne 2f
|
||||||
|
movq PCB_SAVEFPU(%r8),%r8
|
||||||
|
clts
|
||||||
|
- cmpl $0,use_xsave
|
||||||
|
+ cmpl $0,use_xsave(%rip)
|
||||||
|
jne 1f
|
||||||
|
fxsave (%r8)
|
||||||
|
jmp 2f
|
||||||
|
@@ -120,12 +120,7 @@
|
||||||
|
/* This is patched to xsaveopt if supported, see fpuinit_bsp1() */
|
||||||
|
xsave (%r8)
|
||||||
|
movq %rcx,%rdx
|
||||||
|
-2: smsw %ax
|
||||||
|
- orb $CR0_TS,%al
|
||||||
|
- lmsw %ax
|
||||||
|
- xorl %eax,%eax
|
||||||
|
- movq %rax,PCPU(FPCURTHREAD)
|
||||||
|
-3:
|
||||||
|
+2:
|
||||||
|
/* Save is done. Now fire up new thread. Leave old vmspace. */
|
||||||
|
movq %rsi,%r12
|
||||||
|
movq %rdi,%r13
|
||||||
|
@@ -212,6 +207,8 @@
|
||||||
|
movq PCB_RBX(%r8),%rbx
|
||||||
|
movq PCB_RIP(%r8),%rax
|
||||||
|
movq %rax,(%rsp)
|
||||||
|
+ movq PCPU(CURTHREAD),%rdi
|
||||||
|
+ call fpu_activate_sw
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
--- sys/amd64/amd64/fpu.c.orig
|
||||||
|
+++ sys/amd64/amd64/fpu.c
|
||||||
|
@@ -139,6 +139,11 @@
|
||||||
|
SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
|
||||||
|
SYSCTL_NULL_INT_PTR, 1, "Floating point instructions executed in hardware");
|
||||||
|
|
||||||
|
+int lazy_fpu_switch = 0;
|
||||||
|
+SYSCTL_INT(_hw, OID_AUTO, lazy_fpu_switch, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
|
||||||
|
+ &lazy_fpu_switch, 0,
|
||||||
|
+ "Lazily load FPU context after context switch");
|
||||||
|
+
|
||||||
|
int use_xsave; /* non-static for cpu_switch.S */
|
||||||
|
uint64_t xsave_mask; /* the same */
|
||||||
|
static uma_zone_t fpu_save_area_zone;
|
||||||
|
@@ -204,6 +209,7 @@
|
||||||
|
u_int cp[4];
|
||||||
|
uint64_t xsave_mask_user;
|
||||||
|
|
||||||
|
+ TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
|
||||||
|
if ((cpu_feature2 & CPUID2_XSAVE) != 0) {
|
||||||
|
use_xsave = 1;
|
||||||
|
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
|
||||||
|
@@ -611,6 +617,45 @@
|
||||||
|
return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+restore_fpu_curthread(struct thread *td)
|
||||||
|
+{
|
||||||
|
+ struct pcb *pcb;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Record new context early in case frstor causes a trap.
|
||||||
|
+ */
|
||||||
|
+ PCPU_SET(fpcurthread, td);
|
||||||
|
+
|
||||||
|
+ stop_emulating();
|
||||||
|
+ fpu_clean_state();
|
||||||
|
+ pcb = td->td_pcb;
|
||||||
|
+
|
||||||
|
+ if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
|
||||||
|
+ /*
|
||||||
|
+ * This is the first time this thread has used the FPU or
|
||||||
|
+ * the PCB doesn't contain a clean FPU state. Explicitly
|
||||||
|
+ * load an initial state.
|
||||||
|
+ *
|
||||||
|
+ * We prefer to restore the state from the actual save
|
||||||
|
+ * area in PCB instead of directly loading from
|
||||||
|
+ * fpu_initialstate, to ignite the XSAVEOPT
|
||||||
|
+ * tracking engine.
|
||||||
|
+ */
|
||||||
|
+ bcopy(fpu_initialstate, pcb->pcb_save,
|
||||||
|
+ cpu_max_ext_state_size);
|
||||||
|
+ fpurestore(pcb->pcb_save);
|
||||||
|
+ if (pcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
|
||||||
|
+ fldcw(pcb->pcb_initial_fpucw);
|
||||||
|
+ if (PCB_USER_FPU(pcb))
|
||||||
|
+ set_pcb_flags(pcb, PCB_FPUINITDONE |
|
||||||
|
+ PCB_USERFPUINITDONE);
|
||||||
|
+ else
|
||||||
|
+ set_pcb_flags(pcb, PCB_FPUINITDONE);
|
||||||
|
+ } else
|
||||||
|
+ fpurestore(pcb->pcb_save);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Device Not Available (DNA, #NM) exception handler.
|
||||||
|
*
|
||||||
|
@@ -621,7 +666,9 @@
|
||||||
|
void
|
||||||
|
fpudna(void)
|
||||||
|
{
|
||||||
|
+ struct thread *td;
|
||||||
|
|
||||||
|
+ td = curthread;
|
||||||
|
/*
|
||||||
|
* This handler is entered with interrupts enabled, so context
|
||||||
|
* switches may occur before critical_enter() is executed. If
|
||||||
|
@@ -635,49 +682,38 @@
|
||||||
|
|
||||||
|
KASSERT((curpcb->pcb_flags & PCB_FPUNOSAVE) == 0,
|
||||||
|
("fpudna while in fpu_kern_enter(FPU_KERN_NOCTX)"));
|
||||||
|
- if (PCPU_GET(fpcurthread) == curthread) {
|
||||||
|
- printf("fpudna: fpcurthread == curthread\n");
|
||||||
|
+ if (__predict_false(PCPU_GET(fpcurthread) == td)) {
|
||||||
|
+ /*
|
||||||
|
+ * Some virtual machines seems to set %cr0.TS at
|
||||||
|
+ * arbitrary moments. Silently clear the TS bit
|
||||||
|
+ * regardless of the eager/lazy FPU context switch
|
||||||
|
+ * mode.
|
||||||
|
+ */
|
||||||
|
stop_emulating();
|
||||||
|
- critical_exit();
|
||||||
|
- return;
|
||||||
|
+ } else {
|
||||||
|
+ if (__predict_false(PCPU_GET(fpcurthread) != NULL)) {
|
||||||
|
+ panic(
|
||||||
|
+ "fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
||||||
|
+ PCPU_GET(fpcurthread),
|
||||||
|
+ PCPU_GET(fpcurthread)->td_tid, td, td->td_tid);
|
||||||
|
+ }
|
||||||
|
+ restore_fpu_curthread(td);
|
||||||
|
}
|
||||||
|
- if (PCPU_GET(fpcurthread) != NULL) {
|
||||||
|
- panic("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
||||||
|
- PCPU_GET(fpcurthread), PCPU_GET(fpcurthread)->td_tid,
|
||||||
|
- curthread, curthread->td_tid);
|
||||||
|
- }
|
||||||
|
- stop_emulating();
|
||||||
|
- /*
|
||||||
|
- * Record new context early in case frstor causes a trap.
|
||||||
|
- */
|
||||||
|
- PCPU_SET(fpcurthread, curthread);
|
||||||
|
+ critical_exit();
|
||||||
|
+}
|
||||||
|
|
||||||
|
- fpu_clean_state();
|
||||||
|
+void fpu_activate_sw(struct thread *td); /* Called from the context switch */
|
||||||
|
+void
|
||||||
|
+fpu_activate_sw(struct thread *td)
|
||||||
|
+{
|
||||||
|
|
||||||
|
- if ((curpcb->pcb_flags & PCB_FPUINITDONE) == 0) {
|
||||||
|
- /*
|
||||||
|
- * This is the first time this thread has used the FPU or
|
||||||
|
- * the PCB doesn't contain a clean FPU state. Explicitly
|
||||||
|
- * load an initial state.
|
||||||
|
- *
|
||||||
|
- * We prefer to restore the state from the actual save
|
||||||
|
- * area in PCB instead of directly loading from
|
||||||
|
- * fpu_initialstate, to ignite the XSAVEOPT
|
||||||
|
- * tracking engine.
|
||||||
|
- */
|
||||||
|
- bcopy(fpu_initialstate, curpcb->pcb_save,
|
||||||
|
- cpu_max_ext_state_size);
|
||||||
|
- fpurestore(curpcb->pcb_save);
|
||||||
|
- if (curpcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
|
||||||
|
- fldcw(curpcb->pcb_initial_fpucw);
|
||||||
|
- if (PCB_USER_FPU(curpcb))
|
||||||
|
- set_pcb_flags(curpcb,
|
||||||
|
- PCB_FPUINITDONE | PCB_USERFPUINITDONE);
|
||||||
|
- else
|
||||||
|
- set_pcb_flags(curpcb, PCB_FPUINITDONE);
|
||||||
|
- } else
|
||||||
|
- fpurestore(curpcb->pcb_save);
|
||||||
|
- critical_exit();
|
||||||
|
+ if (lazy_fpu_switch || (td->td_pflags & TDP_KTHREAD) != 0 ||
|
||||||
|
+ !PCB_USER_FPU(td->td_pcb)) {
|
||||||
|
+ PCPU_SET(fpcurthread, NULL);
|
||||||
|
+ start_emulating();
|
||||||
|
+ } else if (PCPU_GET(fpcurthread) != td) {
|
||||||
|
+ restore_fpu_curthread(td);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
--- sys/i386/i386/swtch.s.orig
|
||||||
|
+++ sys/i386/i386/swtch.s
|
||||||
|
@@ -293,6 +293,12 @@
|
||||||
|
cpu_switch_load_gs:
|
||||||
|
mov PCB_GS(%edx),%gs
|
||||||
|
|
||||||
|
+ pushl %edx
|
||||||
|
+ pushl PCPU(CURTHREAD)
|
||||||
|
+ call npxswitch
|
||||||
|
+ popl %edx
|
||||||
|
+ popl %edx
|
||||||
|
+
|
||||||
|
/* Test if debug registers should be restored. */
|
||||||
|
testl $PCB_DBREGS,PCB_FLAGS(%edx)
|
||||||
|
jz 1f
|
||||||
|
--- sys/i386/isa/npx.c.orig
|
||||||
|
+++ sys/i386/isa/npx.c
|
||||||
|
@@ -191,6 +191,11 @@
|
||||||
|
SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
|
||||||
|
&hw_float, 0, "Floating point instructions executed in hardware");
|
||||||
|
|
||||||
|
+int lazy_fpu_switch = 0;
|
||||||
|
+SYSCTL_INT(_hw, OID_AUTO, lazy_fpu_switch, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
|
||||||
|
+ &lazy_fpu_switch, 0,
|
||||||
|
+ "Lazily load FPU context after context switch");
|
||||||
|
+
|
||||||
|
int use_xsave;
|
||||||
|
uint64_t xsave_mask;
|
||||||
|
static uma_zone_t fpu_save_area_zone;
|
||||||
|
@@ -327,6 +332,7 @@
|
||||||
|
u_int cp[4];
|
||||||
|
uint64_t xsave_mask_user;
|
||||||
|
|
||||||
|
+ TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
|
||||||
|
if (cpu_fxsr && (cpu_feature2 & CPUID2_XSAVE) != 0) {
|
||||||
|
use_xsave = 1;
|
||||||
|
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
|
||||||
|
@@ -785,47 +791,20 @@
|
||||||
|
return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Implement device not available (DNA) exception
|
||||||
|
- *
|
||||||
|
- * It would be better to switch FP context here (if curthread != fpcurthread)
|
||||||
|
- * and not necessarily for every context switch, but it is too hard to
|
||||||
|
- * access foreign pcb's.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-static int err_count = 0;
|
||||||
|
-
|
||||||
|
-int
|
||||||
|
-npxdna(void)
|
||||||
|
+static void
|
||||||
|
+restore_npx_curthread(struct thread *td, struct pcb *pcb)
|
||||||
|
{
|
||||||
|
|
||||||
|
- if (!hw_float)
|
||||||
|
- return (0);
|
||||||
|
- critical_enter();
|
||||||
|
- if (PCPU_GET(fpcurthread) == curthread) {
|
||||||
|
- printf("npxdna: fpcurthread == curthread %d times\n",
|
||||||
|
- ++err_count);
|
||||||
|
- stop_emulating();
|
||||||
|
- critical_exit();
|
||||||
|
- return (1);
|
||||||
|
- }
|
||||||
|
- if (PCPU_GET(fpcurthread) != NULL) {
|
||||||
|
- printf("npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
||||||
|
- PCPU_GET(fpcurthread),
|
||||||
|
- PCPU_GET(fpcurthread)->td_proc->p_pid,
|
||||||
|
- curthread, curthread->td_proc->p_pid);
|
||||||
|
- panic("npxdna");
|
||||||
|
- }
|
||||||
|
- stop_emulating();
|
||||||
|
/*
|
||||||
|
* Record new context early in case frstor causes a trap.
|
||||||
|
*/
|
||||||
|
- PCPU_SET(fpcurthread, curthread);
|
||||||
|
+ PCPU_SET(fpcurthread, td);
|
||||||
|
|
||||||
|
+ stop_emulating();
|
||||||
|
if (cpu_fxsr)
|
||||||
|
fpu_clean_state();
|
||||||
|
|
||||||
|
- if ((curpcb->pcb_flags & PCB_NPXINITDONE) == 0) {
|
||||||
|
+ if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
|
||||||
|
/*
|
||||||
|
* This is the first time this thread has used the FPU or
|
||||||
|
* the PCB doesn't contain a clean FPU state. Explicitly
|
||||||
|
@@ -836,18 +815,54 @@
|
||||||
|
* npx_initialstate, to ignite the XSAVEOPT
|
||||||
|
* tracking engine.
|
||||||
|
*/
|
||||||
|
- bcopy(npx_initialstate, curpcb->pcb_save, cpu_max_ext_state_size);
|
||||||
|
- fpurstor(curpcb->pcb_save);
|
||||||
|
- if (curpcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
|
||||||
|
- fldcw(curpcb->pcb_initial_npxcw);
|
||||||
|
- curpcb->pcb_flags |= PCB_NPXINITDONE;
|
||||||
|
- if (PCB_USER_FPU(curpcb))
|
||||||
|
- curpcb->pcb_flags |= PCB_NPXUSERINITDONE;
|
||||||
|
+ bcopy(npx_initialstate, pcb->pcb_save, cpu_max_ext_state_size);
|
||||||
|
+ fpurstor(pcb->pcb_save);
|
||||||
|
+ if (pcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
|
||||||
|
+ fldcw(pcb->pcb_initial_npxcw);
|
||||||
|
+ pcb->pcb_flags |= PCB_NPXINITDONE;
|
||||||
|
+ if (PCB_USER_FPU(pcb))
|
||||||
|
+ pcb->pcb_flags |= PCB_NPXUSERINITDONE;
|
||||||
|
} else {
|
||||||
|
- fpurstor(curpcb->pcb_save);
|
||||||
|
+ fpurstor(pcb->pcb_save);
|
||||||
|
}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Implement device not available (DNA) exception
|
||||||
|
+ *
|
||||||
|
+ * It would be better to switch FP context here (if curthread != fpcurthread)
|
||||||
|
+ * and not necessarily for every context switch, but it is too hard to
|
||||||
|
+ * access foreign pcb's.
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+npxdna(void)
|
||||||
|
+{
|
||||||
|
+ struct thread *td;
|
||||||
|
+
|
||||||
|
+ if (!hw_float)
|
||||||
|
+ return (0);
|
||||||
|
+ td = curthread;
|
||||||
|
+ critical_enter();
|
||||||
|
+ if (__predict_false(PCPU_GET(fpcurthread) == td)) {
|
||||||
|
+ /*
|
||||||
|
+ * Some virtual machines seems to set %cr0.TS at
|
||||||
|
+ * arbitrary moments. Silently clear the TS bit
|
||||||
|
+ * regardless of the eager/lazy FPU context switch
|
||||||
|
+ * mode.
|
||||||
|
+ */
|
||||||
|
+ stop_emulating();
|
||||||
|
+ } else {
|
||||||
|
+ if (__predict_false(PCPU_GET(fpcurthread) != NULL)) {
|
||||||
|
+ printf(
|
||||||
|
+ "npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
||||||
|
+ PCPU_GET(fpcurthread),
|
||||||
|
+ PCPU_GET(fpcurthread)->td_proc->p_pid,
|
||||||
|
+ td, td->td_proc->p_pid);
|
||||||
|
+ panic("npxdna");
|
||||||
|
+ }
|
||||||
|
+ restore_npx_curthread(td, td->td_pcb);
|
||||||
|
+ }
|
||||||
|
critical_exit();
|
||||||
|
-
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -869,10 +884,22 @@
|
||||||
|
xsaveopt((char *)addr, xsave_mask);
|
||||||
|
else
|
||||||
|
fpusave(addr);
|
||||||
|
- start_emulating();
|
||||||
|
- PCPU_SET(fpcurthread, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void npxswitch(struct thread *td, struct pcb *pcb);
|
||||||
|
+void
|
||||||
|
+npxswitch(struct thread *td, struct pcb *pcb)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ if (lazy_fpu_switch || (td->td_pflags & TDP_KTHREAD) != 0 ||
|
||||||
|
+ !PCB_USER_FPU(pcb)) {
|
||||||
|
+ start_emulating();
|
||||||
|
+ PCPU_SET(fpcurthread, NULL);
|
||||||
|
+ } else if (PCPU_GET(fpcurthread) != td) {
|
||||||
|
+ restore_npx_curthread(td, pcb);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Unconditionally save the current co-processor state across suspend and
|
||||||
|
* resume.
|
18
share/security/patches/SA-18:07/lazyfpu-11.patch.asc
Normal file
18
share/security/patches/SA-18:07/lazyfpu-11.patch.asc
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN2xfFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
|
||||||
|
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
|
||||||
|
5cJY2Q/+KyfnyHr1YphdZkXYLPTtIKCJasfR1jWSh+6Amr/QDCSvMSvvjvbg6PL0
|
||||||
|
snVq9108ycrKU7xOBebBQRYNYuS1KlRsjcw396dhpjoVwaoQ5mxuWqeiRbSudy/N
|
||||||
|
hFuX91E22832j1o4AsovV/vpqTREz0o4BnMrw9fUiZvuhEiPXs3VHoBcn3lCflXf
|
||||||
|
ubJVptVVCjIK7miVY/oGtvUnzNoSujjNQekpdhHmKyWxU+PrHHhh/kJg+CVEKNr9
|
||||||
|
IkeJV8w2NkpbXEkf59rMUxoMd4OkxlVlNuoPqWekXBwcLGwd5Uux7GAeI+X8crGA
|
||||||
|
cim6F8zniozsip7AptQU5e8yQL/mKYsoWpsghASEu1uanvwTjkmu82f3ER7/FX08
|
||||||
|
0MmhWcSkqGEvKlenQAajCLA7CTzXiMcB3QoCd3VYUmXZOJqcnDAijaDRZ/FMuVJV
|
||||||
|
wGDFus4cMiDhuC+WJTE699DGmveov3C3N6O65K7KNMdsECFwfP38xzzv+wvjzCbj
|
||||||
|
JzaYW14YYr5cgsBdL24z0Yl8Pz9vXexiFdPH+VxOaRIHZGMSQqRe0TXG85M8Pv9F
|
||||||
|
X0tje/gbMMnBpgHui3lUY3x45srRLSn8qt/v/j3W5zoxXINZTDTdqoZT7T9pKWpD
|
||||||
|
EmWdlLMRDDDvQceXdDebZytM/cMAUf2PS2RtWipSwC4Frqz9eYY=
|
||||||
|
=dd45
|
||||||
|
-----END PGP SIGNATURE-----
|
|
@ -7,6 +7,19 @@
|
||||||
<year>
|
<year>
|
||||||
<name>2018</name>
|
<name>2018</name>
|
||||||
|
|
||||||
|
<month>
|
||||||
|
<name>6</name>
|
||||||
|
|
||||||
|
<day>
|
||||||
|
<name>21</name>
|
||||||
|
|
||||||
|
<advisory>
|
||||||
|
<name>FreeBSD-SA-18:07.lazyfpu</name>
|
||||||
|
</advisory>
|
||||||
|
|
||||||
|
</day>
|
||||||
|
</month>
|
||||||
|
|
||||||
<month>
|
<month>
|
||||||
<name>5</name>
|
<name>5</name>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,19 @@
|
||||||
<year>
|
<year>
|
||||||
<name>2018</name>
|
<name>2018</name>
|
||||||
|
|
||||||
|
<month>
|
||||||
|
<name>6</name>
|
||||||
|
|
||||||
|
<day>
|
||||||
|
<name>21</name>
|
||||||
|
|
||||||
|
<notice>
|
||||||
|
<name>FreeBSD-EN-18:07.pmap</name>
|
||||||
|
</notice>
|
||||||
|
|
||||||
|
</day>
|
||||||
|
</month>
|
||||||
|
|
||||||
<month>
|
<month>
|
||||||
<name>5</name>
|
<name>5</name>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue