+ These abbreviations are:
+ AMT Amsterdam, Asunción, Athens;
+- BMT Baghdad, Bangkok, Batavia, Bern, Bogotá, Bridgetown, Brussels,
+- Bucharest;
++ BMT Baghdad, Bangkok, Batavia, Bermuda, Bern, Bogotá, Bridgetown,
++ Brussels, Bucharest;
+ CMT Calamarca, Caracas, Chisinau, Colón, Copenhagen, Córdoba;
+ DMT Dublin/Dunsink;
+ EMT Easter;
+@@ -506,6 +506,7 @@
+ A few abbreviations also follow the pattern that
+ GMT/BST established for time in the UK.
+ They are:
++ BMT/BST for Bermuda 1890–1930,
+ CMT/BST for Calamarca Mean Time and Bolivian Summer Time
+ 1890–1932,
+ DMT/IST for Dublin/Dunsink Mean Time and Irish Summer Time
+--- contrib/tzdata/version.orig
++++ contrib/tzdata/version
+@@ -1 +1 @@
+-2020d
++2021a
+--- contrib/tzdata/ziguard.awk.orig
++++ contrib/tzdata/ziguard.awk
+@@ -37,7 +37,7 @@
+
+ # If this line should differ due to Czechoslovakia using negative SAVE values,
+ # uncomment the desired version and comment out the undesired one.
+- if (zone == "Europe/Prague" && /1947 Feb 23/) {
++ if (zone == "Europe/Prague" && /^#?[\t ]+[01]:00[\t ]/ && /1947 Feb 23/) {
+ if (($(in_comment + 2) != "-") == vanguard) {
+ uncomment = in_comment
+ } else {
+@@ -65,10 +65,11 @@
+ # uncomment the desired version and comment out the undesired one.
+ Rule_Namibia = /^#?Rule[\t ]+Namibia[\t ]/
+ Zone_using_Namibia_rule \
+- = (zone == "Africa/Windhoek" \
++ = (zone == "Africa/Windhoek" && /^#?[\t ]+[12]:00[\t ]/ \
+ && ($(in_comment + 2) == "Namibia" \
+- || (1994 <= $(in_comment + 4) && $(in_comment + 4) <= 2017) \
+- || in_comment + 3 == NF))
++ || ($(in_comment + 2) == "-" && $(in_comment + 3) == "CAT" \
++ && ((1994 <= $(in_comment + 4) && $(in_comment + 4) <= 2017) \
++ || in_comment + 3 == NF))))
+ if (Rule_Namibia || Zone_using_Namibia_rule) {
+ if ((Rule_Namibia \
+ ? ($(in_comment + 9) ~ /^-/ \
+--- contrib/tzdata/zone.tab.orig
++++ contrib/tzdata/zone.tab
+@@ -56,8 +56,7 @@
+ AT +4813+01620 Europe/Vienna
+ AU -3133+15905 Australia/Lord_Howe Lord Howe Island
+ AU -5430+15857 Antarctica/Macquarie Macquarie Island
+-AU -4253+14719 Australia/Hobart Tasmania (most areas)
+-AU -3956+14352 Australia/Currie Tasmania (King Island)
++AU -4253+14719 Australia/Hobart Tasmania
+ AU -3749+14458 Australia/Melbourne Victoria
+ AU -3352+15113 Australia/Sydney New South Wales (most areas)
+ AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna)
+@@ -130,9 +129,9 @@
+ CA +4906-11631 America/Creston MST - BC (Creston)
+ CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
+ CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
++CA +6043-13503 America/Whitehorse MST - Yukon (east)
++CA +6404-13925 America/Dawson MST - Yukon (west)
+ CA +4916-12307 America/Vancouver Pacific - BC (most areas)
+-CA +6043-13503 America/Whitehorse Pacific - Yukon (east)
+-CA +6404-13925 America/Dawson Pacific - Yukon (west)
+ CC -1210+09655 Indian/Cocos
+ CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west)
+ CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east)
+@@ -337,8 +336,8 @@
+ # Programs should use zone1970.tab instead; see above.
+ UA +4457+03406 Europe/Simferopol Crimea
+ RU +5836+04939 Europe/Kirov MSK+00 - Kirov
++RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd
+ RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan
+-RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd
+ RU +5134+04602 Europe/Saratov MSK+01 - Saratov
+ RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk
+ RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia
+--- contrib/tzdata/zone1970.tab.orig
++++ contrib/tzdata/zone1970.tab
+@@ -64,8 +64,7 @@
+ AT +4813+01620 Europe/Vienna
+ AU -3133+15905 Australia/Lord_Howe Lord Howe Island
+ AU -5430+15857 Antarctica/Macquarie Macquarie Island
+-AU -4253+14719 Australia/Hobart Tasmania (most areas)
+-AU -3956+14352 Australia/Currie Tasmania (King Island)
++AU -4253+14719 Australia/Hobart Tasmania
+ AU -3749+14458 Australia/Melbourne Victoria
+ AU -3352+15113 Australia/Sydney New South Wales (most areas)
+ AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna)
+@@ -128,9 +127,9 @@
+ CA +4906-11631 America/Creston MST - BC (Creston)
+ CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
+ CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
++CA +6043-13503 America/Whitehorse MST - Yukon (east)
++CA +6404-13925 America/Dawson MST - Yukon (west)
+ CA +4916-12307 America/Vancouver Pacific - BC (most areas)
+-CA +6043-13503 America/Whitehorse Pacific - Yukon (east)
+-CA +6404-13925 America/Dawson Pacific - Yukon (west)
+ CC -1210+09655 Indian/Cocos
+ CH,DE,LI +4723+00832 Europe/Zurich Swiss time
+ CI,BF,GM,GN,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan
+@@ -293,8 +292,8 @@
+ # Mention RU and UA alphabetically. See "territorial claims" above.
+ RU,UA +4457+03406 Europe/Simferopol Crimea
+ RU +5836+04939 Europe/Kirov MSK+00 - Kirov
++RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd
+ RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan
+-RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd
+ RU +5134+04602 Europe/Saratov MSK+01 - Saratov
+ RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk
+ RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia
diff --git a/website/static/security/patches/EN-21:01/tzdata-2021a.patch.asc b/website/static/security/patches/EN-21:01/tzdata-2021a.patch.asc
new file mode 100644
index 0000000000..ae76c0013c
--- /dev/null
+++ b/website/static/security/patches/EN-21:01/tzdata-2021a.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbgVfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cL0kQ//RYNiBRCzjAawttj9Wz6ryKf1rTERp1FJ17NpLRzRHp/WnjTKZ4uyEqGn
+pb4VWPbhVjiiCCyA0zvwGAOF5Yviv1UR79i5U+G0ErxVPdQKapqoQ240CY09eObG
+rqKGLJIhdXIyEEPK9YrYYDUb0kAwOzpnvt3xgPH1sph0QT8fga0bffnr2sDthDu7
+b5NOKMA51JkB1G2tlevHGUXrTnh+gZntXApSYVZ8/c8jKqnzAdcm9Co80hb8oVuC
+yWwEM7s2v/HTF0NUPPIz3PfAETLWCzVHGb0ZjXdZO6rd1BV6Zm1TIZ4wRoNOzl5n
+4PQGmEQckxojDcDIUImF9EDS+8SxxnP3cDUyN3vIqmTKUkVjAIStqqq5AfFZBs0+
+CjvkX9v0LgaCNHfPPknUuldeORO4YLTc/6dj4Ern7gocHRE9/feBcHdV58XGQLB/
+jI92wckBD0G738TCKQg74rX21A3564h/cbThmsGUP05C2D1vW+jT+v9DJy15LpG6
+CIF9zU8IwLFKlzI28Oc8vLekgU/6E8z7V0+ObmpboRIVJTXetkRCN61SyIKSnJT+
+nZgIgvd22jTFXJh6j18SmQS6cN2kEq22AtYLimNKEgrsGcT7uMrWyTJQ6vJiooqc
+a5txbMB2R4uRNv810IpMl0li2J0kshNBsnmsv0UxNQcAVyORBm8=
+=ynES
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-21:02/extattr.patch b/website/static/security/patches/EN-21:02/extattr.patch
new file mode 100644
index 0000000000..ce1908786d
--- /dev/null
+++ b/website/static/security/patches/EN-21:02/extattr.patch
@@ -0,0 +1,11 @@
+--- sys/ufs/ffs/ffs_vnops.c.orig
++++ sys/ufs/ffs/ffs_vnops.c
+@@ -1663,7 +1663,7 @@
+ *p++ = ap->a_attrnamespace;
+ *p++ = eapad2;
+ *p++ = strlen(ap->a_name);
+- strcpy(p, ap->a_name);
++ memcpy(p, ap->a_name, strlen(ap->a_name));
+ p += strlen(ap->a_name);
+ bzero(p, eapad1);
+ p += eapad1;
diff --git a/website/static/security/patches/EN-21:02/extattr.patch.asc b/website/static/security/patches/EN-21:02/extattr.patch.asc
new file mode 100644
index 0000000000..a8d0eb4d21
--- /dev/null
+++ b/website/static/security/patches/EN-21:02/extattr.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbilfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLRwQ//cPFjEPuSDNSMa6NcQnDKo7pZ+0jYON5t8CSMj9CqxKs3V/wa6F9rB78l
+px6lkasBBFClmXH/lnVBrg8KTTD699Q8q7SHbydC7cG3XVB73QJnDjJrm6XgdcFt
+RKF546+h50JQBXqlW5JRpCCzqMzqzdqa5eFGjJfPI16TjbAuz8ywOez1PHTuTmuS
+lSJaT+UN78s5tD2D2WgQzzTG/o8umuJXisfCGFLsK7RI3p7c9N8QcrIGikrose9R
+yu/NFpfs/5iIE40VtTb6J/4PcOBlzfdjDv4EgAyRKzhTkFxPDgh3cgfh/gtJg9CV
+AZtf5K0qOufD79l1PA25znU3nf761VFQIyPv/sIT5nuhITm1WkPtV4mvHlN+bb9C
+tVF4HkLx6raghE5XnIAg0cFndVlS+zwAmzety/75W0h0AUqofrn4jbdcmeFGogG+
+BAtaPE39xWGJMT4R9zXMnF+mojX2GOqSKOyfshBrolsnkT9oEQQAVGb0N3ZxRT/2
+tmvV2Q01d5NORvtBlD0yvJ/qkihiF0UrfG+I9GJ2+gMjibpU/iZik8y0msboBYIB
+2zjf3DdNZY/n+hSN8cxN32maU0ZYl+he394rmMt0Lj1Ff7EuUz5RsKtzHoYPHoWm
+mTnXK/PUrJTEdvYxUzMbOsfM41Pqq476XYl/7B6bU4ZnSNlTxNM=
+=ntJx
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-21:03/vnet.patch b/website/static/security/patches/EN-21:03/vnet.patch
new file mode 100644
index 0000000000..0f875b029d
--- /dev/null
+++ b/website/static/security/patches/EN-21:03/vnet.patch
@@ -0,0 +1,291 @@
+--- sys/net/if.c.orig
++++ sys/net/if.c
+@@ -274,6 +274,8 @@
+ static void if_delgroups(struct ifnet *);
+ static void if_attach_internal(struct ifnet *, int, struct if_clone *);
+ static int if_detach_internal(struct ifnet *, int, struct if_clone **);
++static void if_link_ifnet(struct ifnet *);
++static bool if_unlink_ifnet(struct ifnet *, bool);
+ #ifdef VIMAGE
+ static void if_vmove(struct ifnet *, struct vnet *);
+ #endif
+@@ -305,12 +307,8 @@
+
+ /*
+ * The global network interface list (V_ifnet) and related state (such as
+- * if_index, if_indexlim, and ifindex_table) are protected by an sxlock and
+- * an rwlock. Either may be acquired shared to stablize the list, but both
+- * must be acquired writable to modify the list. This model allows us to
+- * both stablize the interface list during interrupt thread processing, but
+- * also to stablize it over long-running ioctls, without introducing priority
+- * inversions and deadlocks.
++ * if_index, if_indexlim, and ifindex_table) are protected by an sxlock.
++ * This may be acquired to stabilise the list, or we may rely on NET_EPOCH.
+ */
+ struct rwlock ifnet_rwlock;
+ RW_SYSINIT_FLAGS(ifnet_rw, &ifnet_rwlock, "ifnet_rw", RW_RECURSE);
+@@ -317,6 +315,9 @@
+ struct sx ifnet_sxlock;
+ SX_SYSINIT_FLAGS(ifnet_sx, &ifnet_sxlock, "ifnet_sx", SX_RECURSE);
+
++struct sx ifnet_detach_sxlock;
++SX_SYSINIT(ifnet_detach, &ifnet_detach_sxlock, "ifnet_detach_sx");
++
+ /*
+ * The allocation of network interfaces is a rather non-atomic affair; we
+ * need to select an index before we are ready to expose the interface for
+@@ -476,17 +477,87 @@
+ }
+ VNET_SYSUNINIT(vnet_if_uninit, SI_SUB_INIT_IF, SI_ORDER_FIRST,
+ vnet_if_uninit, NULL);
++#endif
+
+ static void
++if_link_ifnet(struct ifnet *ifp)
++{
++
++ IFNET_WLOCK();
++ CK_STAILQ_INSERT_TAIL(&V_ifnet, ifp, if_link);
++#ifdef VIMAGE
++ curvnet->vnet_ifcnt++;
++#endif
++ IFNET_WUNLOCK();
++}
++
++static bool
++if_unlink_ifnet(struct ifnet *ifp, bool vmove)
++{
++ struct ifnet *iter;
++ int found = 0;
++
++ IFNET_WLOCK();
++ CK_STAILQ_FOREACH(iter, &V_ifnet, if_link)
++ if (iter == ifp) {
++ CK_STAILQ_REMOVE(&V_ifnet, ifp, ifnet, if_link);
++ if (!vmove)
++ ifp->if_flags |= IFF_DYING;
++ found = 1;
++ break;
++ }
++#ifdef VIMAGE
++ curvnet->vnet_ifcnt--;
++#endif
++ IFNET_WUNLOCK();
++
++ return (found);
++}
++
++#ifdef VIMAGE
++static void
+ vnet_if_return(const void *unused __unused)
+ {
+ struct ifnet *ifp, *nifp;
++ struct ifnet **pending;
++ int found, i;
+
++ i = 0;
++
++ /*
++ * We need to protect our access to the V_ifnet tailq. Ordinarily we'd
++ * enter NET_EPOCH, but that's not possible, because if_vmove() calls
++ * if_detach_internal(), which waits for NET_EPOCH callbacks to
++ * complete. We can't do that from within NET_EPOCH.
++ *
++ * However, we can also use the IFNET_xLOCK, which is the V_ifnet
++ * read/write lock. We cannot hold the lock as we call if_vmove()
++ * though, as that presents LOR w.r.t ifnet_sx, in_multi_sx and iflib
++ * ctx lock.
++ */
++ IFNET_WLOCK();
++
++ pending = malloc(sizeof(struct ifnet *) * curvnet->vnet_ifcnt,
++ M_IFNET, M_WAITOK | M_ZERO);
++
+ /* Return all inherited interfaces to their parent vnets. */
+ CK_STAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) {
+- if (ifp->if_home_vnet != ifp->if_vnet)
+- if_vmove(ifp, ifp->if_home_vnet);
++ if (ifp->if_home_vnet != ifp->if_vnet) {
++ found = if_unlink_ifnet(ifp, true);
++ MPASS(found);
++
++ pending[i++] = ifp;
++ }
+ }
++ IFNET_WUNLOCK();
++
++ for (int j = 0; j < i; j++) {
++ sx_xlock(&ifnet_detach_sxlock);
++ if_vmove(pending[j], pending[j]->if_home_vnet);
++ sx_xunlock(&ifnet_detach_sxlock);
++ }
++
++ free(pending, M_IFNET);
+ }
+ VNET_SYSUNINIT(vnet_if_return, SI_SUB_VNET_DONE, SI_ORDER_ANY,
+ vnet_if_return, NULL);
+@@ -894,12 +965,7 @@
+ }
+ #endif
+
+- IFNET_WLOCK();
+- CK_STAILQ_INSERT_TAIL(&V_ifnet, ifp, if_link);
+-#ifdef VIMAGE
+- curvnet->vnet_ifcnt++;
+-#endif
+- IFNET_WUNLOCK();
++ if_link_ifnet(ifp);
+
+ if (domain_init_status >= 2)
+ if_attachdomain1(ifp);
+@@ -1037,9 +1103,15 @@
+ void
+ if_detach(struct ifnet *ifp)
+ {
++ bool found;
+
+ CURVNET_SET_QUIET(ifp->if_vnet);
+- if_detach_internal(ifp, 0, NULL);
++ found = if_unlink_ifnet(ifp, false);
++ if (found) {
++ sx_slock(&ifnet_detach_sxlock);
++ if_detach_internal(ifp, 0, NULL);
++ sx_sunlock(&ifnet_detach_sxlock);
++ }
+ CURVNET_RESTORE();
+ }
+
+@@ -1059,8 +1131,6 @@
+ struct ifaddr *ifa;
+ int i;
+ struct domain *dp;
+- struct ifnet *iter;
+- int found = 0;
+ #ifdef VIMAGE
+ int shutdown;
+
+@@ -1067,39 +1137,11 @@
+ shutdown = (ifp->if_vnet->vnet_state > SI_SUB_VNET &&
+ ifp->if_vnet->vnet_state < SI_SUB_VNET_DONE) ? 1 : 0;
+ #endif
+- IFNET_WLOCK();
+- CK_STAILQ_FOREACH(iter, &V_ifnet, if_link)
+- if (iter == ifp) {
+- CK_STAILQ_REMOVE(&V_ifnet, ifp, ifnet, if_link);
+- if (!vmove)
+- ifp->if_flags |= IFF_DYING;
+- found = 1;
+- break;
+- }
+- IFNET_WUNLOCK();
+- if (!found) {
+- /*
+- * While we would want to panic here, we cannot
+- * guarantee that the interface is indeed still on
+- * the list given we don't hold locks all the way.
+- */
+- return (ENOENT);
+-#if 0
+- if (vmove)
+- panic("%s: ifp=%p not on the ifnet tailq %p",
+- __func__, ifp, &V_ifnet);
+- else
+- return; /* XXX this should panic as well? */
+-#endif
+- }
+
+ /*
+ * At this point we know the interface still was on the ifnet list
+ * and we removed it so we are in a stable state.
+ */
+-#ifdef VIMAGE
+- curvnet->vnet_ifcnt--;
+-#endif
+ epoch_wait_preempt(net_epoch_preempt);
+
+ /*
+@@ -1326,6 +1368,7 @@
+ struct prison *pr;
+ struct ifnet *difp;
+ int shutdown;
++ bool found;
+
+ /* Try to find the prison within our visibility. */
+ sx_slock(&allprison_lock);
+@@ -1362,6 +1405,9 @@
+ }
+ CURVNET_RESTORE();
+
++ found = if_unlink_ifnet(ifp, true);
++ MPASS(found);
++
+ /* Move the interface into the child jail/vnet. */
+ if_vmove(ifp, pr->pr_vnet);
+
+@@ -1378,7 +1424,8 @@
+ struct prison *pr;
+ struct vnet *vnet_dst;
+ struct ifnet *ifp;
+- int shutdown;
++ int shutdown;
++ bool found;
+
+ /* Try to find the prison within our visibility. */
+ sx_slock(&allprison_lock);
+@@ -1416,6 +1463,8 @@
+ }
+
+ /* Get interface back from child jail/vnet. */
++ found = if_unlink_ifnet(ifp, true);
++ MPASS(found);
+ if_vmove(ifp, vnet_dst);
+ CURVNET_RESTORE();
+
+@@ -3100,8 +3149,12 @@
+ goto out_noref;
+ case SIOCIFDESTROY:
+ error = priv_check(td, PRIV_NET_IFDESTROY);
+- if (error == 0)
++
++ if (error == 0) {
++ sx_slock(&ifnet_detach_sxlock);
+ error = if_clone_destroy(ifr->ifr_name);
++ sx_sunlock(&ifnet_detach_sxlock);
++ }
+ goto out_noref;
+
+ case SIOCIFGCLONERS:
+--- sys/net/if_var.h.orig
++++ sys/net/if_var.h
+@@ -569,27 +569,11 @@
+ extern struct rwlock ifnet_rwlock;
+ extern struct sx ifnet_sxlock;
+
+-#define IFNET_WLOCK() do { \
+- sx_xlock(&ifnet_sxlock); \
+- rw_wlock(&ifnet_rwlock); \
+-} while (0)
+-
+-#define IFNET_WUNLOCK() do { \
+- rw_wunlock(&ifnet_rwlock); \
+- sx_xunlock(&ifnet_sxlock); \
+-} while (0)
+-
+-/*
+- * To assert the ifnet lock, you must know not only whether it's for read or
+- * write, but also whether it was acquired with sleep support or not.
+- */
+-#define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED)
++#define IFNET_WLOCK() sx_xlock(&ifnet_sxlock)
++#define IFNET_WUNLOCK() sx_xunlock(&ifnet_sxlock)
++#define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED)
+ #define IFNET_RLOCK_NOSLEEP_ASSERT() MPASS(in_epoch(net_epoch_preempt))
+-#define IFNET_WLOCK_ASSERT() do { \
+- sx_assert(&ifnet_sxlock, SA_XLOCKED); \
+- rw_assert(&ifnet_rwlock, RA_WLOCKED); \
+-} while (0)
+-
++#define IFNET_WLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_XLOCKED)
+ #define IFNET_RLOCK() sx_slock(&ifnet_sxlock)
+ #define IFNET_RLOCK_NOSLEEP() struct epoch_tracker ifnet_rlock_et; epoch_enter_preempt(net_epoch_preempt, &ifnet_rlock_et)
+ #define IFNET_RUNLOCK() sx_sunlock(&ifnet_sxlock)
diff --git a/website/static/security/patches/EN-21:03/vnet.patch.asc b/website/static/security/patches/EN-21:03/vnet.patch.asc
new file mode 100644
index 0000000000..bac6f744af
--- /dev/null
+++ b/website/static/security/patches/EN-21:03/vnet.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbipfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLRyQ//du+e1JRQvV+xth02xPmDbklqvfsH9ge20DeExN/grbrqv1nLkGBP0I1j
+CnxMMDPsm33fATsxa6HndAcQXDO4bRf0E7qjE+bgC1gJevCrCptXI7LaOgTWrlpP
+0iszfjqF0DIJhXL7MiFVDYkt5EBvPkvJMBo1q3A7HKG8YKzZHI6EUa6g+yspHip0
+p4TKVexl7L4ERb0h8hDUIycAPSmK4lNn9SOlErD9mTUUYRp/xvkVdAV53xnuo2aD
+zt/sqO7lPRP1oiOCp/8D2ZiMbtg6dzOKyw0xhfnsW8a/h0k7nthWKWL+KpyOQVpj
+QZ/lYnzzqxu93/2cZSuGFpIUw3WKl67IlYNW0qtGsvXeFjpx85AqFyYueg00Wvew
+jUQk0lONd6k2XkyMS/mYgYXOuadA5uzJwgffRuKNP7aVxXIXM+4PJFleJ86c0q2b
+qRLUWeWC4l+1oYY+0YHEAzv0VWc+VQilcERgUXezwF40vbUIvc+AhAzUDIO919Yg
+PBz8vAGiDPSfeveihTtuD9FTugw4oaM6mgxFBSnkrHK6EyNuwMk5kvHjx25rjuzX
+eqVEE1gUaigGzXoy1FsFpUeaAr4/vZcwwVu9sZ2Oysyknm7c6j6q/kR1JzH8Y8am
+H0NX4nlccagnfTy5aGPQWPrV8QHAmOYuzw6LltUZxcIMDdLSGH4=
+=edmV
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-21:04/zfs.patch b/website/static/security/patches/EN-21:04/zfs.patch
new file mode 100644
index 0000000000..f83ce9229d
--- /dev/null
+++ b/website/static/security/patches/EN-21:04/zfs.patch
@@ -0,0 +1,150 @@
+--- cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c.orig
++++ cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
+@@ -613,8 +613,8 @@
+ const char *fromsnap;
+ const char *tosnap;
+ boolean_t recursive;
+- boolean_t verbose;
+ boolean_t replicate;
++ boolean_t verbose;
+
+ /*
+ * The header nvlist is of the following format:
+@@ -848,36 +848,36 @@
+ rv = -1;
+ goto out;
+ }
+- VERIFY(0 == nvlist_add_uint64(nvfs, "origin",
+- origin->zfs_dmustats.dds_guid));
++ fnvlist_add_uint64(nvfs, "origin",
++ origin->zfs_dmustats.dds_guid);
+ }
+
+ /* iterate over props */
+- VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
++ nv = fnvlist_alloc();
+ send_iterate_prop(zhp, nv);
+- VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv));
+- nvlist_free(nv);
++ fnvlist_add_nvlist(nvfs, "props", nv);
++ fnvlist_free(nv);
+
+ /* iterate over snaps, and set sd->parent_fromsnap_guid */
++ sd->parent_fromsnap_guid = 0;
++ sd->parent_snaps = fnvlist_alloc();
++ sd->snapprops = fnvlist_alloc();
+ if (!sd->replicate && fromsnap_txg != 0)
+ min_txg = fromsnap_txg;
+ if (!sd->replicate && tosnap_txg != 0)
+ max_txg = tosnap_txg;
+- sd->parent_fromsnap_guid = 0;
+- VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
+- VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
+ (void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd,
+ min_txg, max_txg);
+- VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
+- VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
++ fnvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps);
++ fnvlist_add_nvlist(nvfs, "snapprops", sd->snapprops);
+ fnvlist_free(sd->parent_snaps);
+ fnvlist_free(sd->snapprops);
+
+ /* add this fs to nvlist */
+ (void) snprintf(guidstring, sizeof (guidstring),
+ "0x%llx", (longlong_t)guid);
+- VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs));
+- nvlist_free(nvfs);
++ fnvlist_add_nvlist(sd->fss, guidstring, nvfs);
++ fnvlist_free(nvfs);
+
+ /* iterate over children */
+ if (sd->recursive)
+@@ -894,13 +894,12 @@
+
+ static int
+ gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
+- const char *tosnap, boolean_t recursive, boolean_t verbose,
+- boolean_t replicate, nvlist_t **nvlp, avl_tree_t **avlp)
++ const char *tosnap, boolean_t recursive, boolean_t replicate,
++ boolean_t verbose, nvlist_t **nvlp, avl_tree_t **avlp)
+ {
+ zfs_handle_t *zhp;
+- int error;
+- uint64_t min_txg = 0, max_txg = 0;
+ send_data_t sd = { 0 };
++ int error;
+
+ zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+ if (zhp == NULL)
+@@ -911,8 +910,8 @@
+ sd.fromsnap = fromsnap;
+ sd.tosnap = tosnap;
+ sd.recursive = recursive;
+- sd.verbose = verbose;
+ sd.replicate = replicate;
++ sd.verbose = verbose;
+
+ if ((error = send_iterate_fs(zhp, &sd)) != 0) {
+ nvlist_free(sd.fss);
+@@ -1349,10 +1348,10 @@
+ dump_filesystem(zfs_handle_t *zhp, void *arg)
+ {
+ int rv = 0;
+- uint64_t min_txg = 0, max_txg = 0;
+ send_dump_data_t *sdd = arg;
+ boolean_t missingfrom = B_FALSE;
+ zfs_cmd_t zc = { 0 };
++ uint64_t min_txg = 0, max_txg = 0;
+
+ (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
+ zhp->zfs_name, sdd->tosnap);
+@@ -1853,8 +1852,8 @@
+ }
+
+ err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
+- fromsnap, tosnap, flags->replicate, flags->verbose,
+- flags->replicate, &fss, &fsavl);
++ fromsnap, tosnap, flags->replicate,
++ flags->replicate, flags->verbose, &fss, &fsavl);
+ if (err)
+ goto err_out;
+ VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
+@@ -2497,7 +2496,7 @@
+ VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));
+
+ if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
+- recursive, B_FALSE, B_FALSE, &local_nv, &local_avl)) != 0)
++ recursive, recursive, B_FALSE, &local_nv, &local_avl)) != 0)
+ return (error);
+
+ /*
+--- sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h.orig
++++ sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+@@ -881,6 +881,13 @@
+ VDEV_INITIALIZE_COMPLETE
+ } vdev_initializing_state_t;
+
++/*
++ * nvlist name constants. Facilitate restricting snapshot iteration range for
++ * the "list next snapshot" ioctl
++ */
++#define SNAP_ITER_MIN_TXG "snap_iter_min_txg"
++#define SNAP_ITER_MAX_TXG "snap_iter_max_txg"
++
+ /*
+ * Vdev statistics. Note: all fields should be 64-bit because this
+ * is passed between kernel and userland as an nvlist uint64 array.
+@@ -1157,13 +1164,6 @@
+ #define ZCP_DEFAULT_MEMLIMIT (10 * 1024 * 1024)
+ #define ZCP_MAX_MEMLIMIT (10 * ZCP_DEFAULT_MEMLIMIT)
+
+-/*
+- * nvlist name constants. Facilitate restricting snapshot iteration range for
+- * the "list next snapshot" ioctl
+- */
+-#define SNAP_ITER_MIN_TXG "snap_iter_min_txg"
+-#define SNAP_ITER_MAX_TXG "snap_iter_max_txg"
+-
+ /*
+ * Sysevent payload members. ZFS will generate the following sysevents with the
+ * given payloads:
diff --git a/website/static/security/patches/EN-21:04/zfs.patch.asc b/website/static/security/patches/EN-21:04/zfs.patch.asc
new file mode 100644
index 0000000000..f386991ee1
--- /dev/null
+++ b/website/static/security/patches/EN-21:04/zfs.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbipfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJ9ow/9Hpft2BnP9cFpvRtXtc6J6Pw3s7iS36PHXJXiRTbif72pzUU0dhnGxXT1
+AA8YX8BvyoHOFxUDqTRFcG+/B6HOpjGEq9aqNiBsGxmA8OXPdtjg1nhR23QH+NNt
+tJ5YTVztO2tq/VHri41Ez0ttMMYDIpdPAGJIsnJwzFGMgsXKFcNGhG1IXhSzpJOo
+ZE3R0117MWETR07LJjK7aY5sAvCPA0rtWqosh8DtGa1Qz8k3nNVq91qikAdG2/Ea
+ymICIz/x1vp9J6SUlMt/2Y3t9V3pCyrL2VwyKbBzKZ+PrJUxM9HgA1w5sMn3ANe0
+sT+Ijk3TbAkSkV01PgQsYIwX2mHAH38MKO5foq3oU3bLWCGkxu0jDlSvEgLCE5U+
+4jcJpbH1k1uLOKaLXH3FcK3X0ahIWwOr7ckvcKmsem4f18VLcfQuZ7qHQq3oQT/B
+ooIvF4Xvv/3kfMK2mdMGza6x5AhkJHp4+cDJhw7CVvTWuo+jb+dQYSlrOVOaaaSl
+OQDEqSaja+xGh02asMrtdrCm5+DoMfQ+28jMkb2QyA6IHhUkEa8xa/JBka9o71rZ
+45KIlM7aFxiCACi4LScUNGh94qPnNkG9Mgez1O91nhiFMVCaUSdEDNkz4HMRseli
+hPD2/3rUJ9pRRFcXMbZHrtXK7gwJ+A8Fd++MgYvedwbjke+efe4=
+=mdRJ
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/EN-21:05/libatomic.patch b/website/static/security/patches/EN-21:05/libatomic.patch
new file mode 100644
index 0000000000..959e24bd51
--- /dev/null
+++ b/website/static/security/patches/EN-21:05/libatomic.patch
@@ -0,0 +1,71 @@
+--- contrib/llvm-project/compiler-rt/lib/builtins/atomic.c.orig
++++ contrib/llvm-project/compiler-rt/lib/builtins/atomic.c
+@@ -124,8 +124,8 @@
+ #define IS_LOCK_FREE_2 __c11_atomic_is_lock_free(2)
+ #define IS_LOCK_FREE_4 __c11_atomic_is_lock_free(4)
+
+-/// 32 bit PowerPC doesn't support 8-byte lock_free atomics
+-#if !defined(__powerpc64__) && defined(__powerpc__)
++/// 32 bit MIPS and PowerPC don't support 8-byte lock_free atomics
++#if defined(__mips__) || (!defined(__powerpc64__) && defined(__powerpc__))
+ #define IS_LOCK_FREE_8 0
+ #else
+ #define IS_LOCK_FREE_8 __c11_atomic_is_lock_free(8)
+--- lib/libcompiler_rt/Makefile.inc.orig
++++ lib/libcompiler_rt/Makefile.inc
+@@ -18,6 +18,8 @@
+ SRCF+= ashlti3
+ SRCF+= ashrdi3
+ SRCF+= ashrti3
++SRCF+= bswapdi2
++SRCF+= bswapsi2
+ SRCF+= clear_cache
+ SRCF+= clzdi2
+ SRCF+= clzsi2
+@@ -117,6 +119,14 @@
+ SRCF+= umoddi3
+ SRCF+= umodti3
+
++# Enable compiler-rt's atomic implementation only for clang, as it uses clang
++# specific builtins, and gcc packages usually come with their own libatomic.
++# Exclude arm which has its own implementations of atomic functions, below.
++.if "${COMPILER_TYPE}" == "clang" && \
++ !(${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "armv6")
++SRCF+= atomic
++.endif
++
+ # Avoid using SSE2 instructions on i386, if unsupported.
+ .if ${MACHINE_CPUARCH} == "i386" && empty(MACHINE_CPU:Msse2)
+ SRCS+= floatdidf.c
+@@ -215,12 +225,6 @@
+ SRCF+= stdatomic
+ .endif
+
+-.if "${COMPILER_TYPE}" == "clang" && \
+- (${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpcspe")
+-SRCS+= atomic.c
+-CFLAGS.atomic.c+= -Wno-atomic-alignment
+-.endif
+-
+ .for file in ${SRCF}
+ .if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") \
+ && exists(${CRTSRC}/${CRTARCH}/${file}vfp.S)
+@@ -242,18 +246,9 @@
+ SRCS+= aeabi_memset.S
+ SRCS+= aeabi_uidivmod.S
+ SRCS+= aeabi_uldivmod.S
+-SRCS+= bswapdi2.S
+-SRCS+= bswapsi2.S
+ SRCS+= switch16.S
+ SRCS+= switch32.S
+ SRCS+= switch8.S
+ SRCS+= switchu8.S
+ SRCS+= sync_synchronize.S
+ .endif
+-
+-# GCC-6.3 on mips32 requires bswap32 built-in.
+-.if ${MACHINE_CPUARCH} == "mips"
+-SRCS+= bswapdi2.c
+-SRCS+= bswapsi2.c
+-.endif
+-
diff --git a/website/static/security/patches/EN-21:05/libatomic.patch.asc b/website/static/security/patches/EN-21:05/libatomic.patch.asc
new file mode 100644
index 0000000000..8b650be0d2
--- /dev/null
+++ b/website/static/security/patches/EN-21:05/libatomic.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbipfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cITKxAAipVfcvry45Ih14/dOrobd6s4NtFpck4x+CT9p/SMS5LLLFAJYpjazGtf
+1WytYOv305wZo0toQQDZwTOwGdjPCdZyXzJFXfQGX2KpVA/pqEqY+SBxBEDbzU0X
+4LKiijtGNDqikrb7Rs4m5DiOgcY0UFHvwisGvX4/1yHEx33cSPR6P90uLSwiIUlu
+qxTa400oN79ICecRibtr1rjTRZbSoP/9p3Si2UFVLZPD/mXaYU626T70yIARaach
+8oO8afQHVrvMfdDJrKIuas4DrbhORtZsst4mtmWRDuQlDAIcZuI43uLCjTjMVVjk
+VsQlS/YprSGkzVyBz/hyKqPa8eYkmpmWekSW8mvyNudfjqCfHh6qFAZD9yqqufRr
+am3nWKLqjIclLeF7/nBoyC9Vvhb+okCS3slkejm/4WDpgUoJWyd262Hj4jsviQ3f
+8/MkhkAahSJJTXf9CVDM5iz4DpobCMc27mX/uctfeQrMzw6JMZ3IcSZ/k9mPqlR/
+znhW4gSc1bCrN2t/UCaBeGvnL8eGa5ohhLIHGm3vekMvlpFmj3kPidmgjts1RoHA
+gW0MWfYod54/WceTGC/RVwUQyQjjj4qlLrWZCmU2SAK5Atw54w+l/skj9HZlGJC3
+0OBeQvqSOUszbn8H48+1l039t90rdCbYW5/suZfhoK6OeudbMmY=
+=DgCX
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/SA-21:01/fsdisclosure.11.patch b/website/static/security/patches/SA-21:01/fsdisclosure.11.patch
new file mode 100644
index 0000000000..fea427e96e
--- /dev/null
+++ b/website/static/security/patches/SA-21:01/fsdisclosure.11.patch
@@ -0,0 +1,10 @@
+--- sys/fs/msdosfs/msdosfs_vnops.c.orig
++++ sys/fs/msdosfs/msdosfs_vnops.c
+@@ -1701,6 +1701,7 @@
+ mbnambuf_flush(&nb, &dirbuf);
+ chksum = -1;
+ dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf);
++ dirent_terminate(&dirbuf);
+ if (uio->uio_resid < dirbuf.d_reclen) {
+ brelse(bp);
+ goto out;
diff --git a/website/static/security/patches/SA-21:01/fsdisclosure.11.patch.asc b/website/static/security/patches/SA-21:01/fsdisclosure.11.patch.asc
new file mode 100644
index 0000000000..1bf6b21c8a
--- /dev/null
+++ b/website/static/security/patches/SA-21:01/fsdisclosure.11.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbjNfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJ8HA/+PgmcD+mXjlONm6S2iODbNlot81XtSJFZBVvGsuez3YnDt4NV4TVivf+A
+SFs/3olGaMxtAT/ME8dVrgAF8+cHcjBMj5Vd+SYEgYAS3gQsOm4jfzWTh+z0Wwm7
+SGDgW3h9wMb7WKevudvZ9kI5xV5uOD3IeCs8zag5eNoOp+BvgPbOgP9GdqgP1WmT
+vEFtk8g1PAXoOkDm89rdYf05oUHyC6FvVF1vxCTEypmHt97meIkOn71f+CBMBLTS
+qyFf/DHeXjuWg6XNZckbShRXgJufv8cf2GkK/dX37VzX5qXk4HKsOckQTwxXLjtc
+xQGXyhw2lCWlkJUS6yzeeH4elzl3Z+EPE9t1zrEq5fmwGCV2cGuDQbdgWTfr4LnZ
+5uTFJ6RtAT66hnbTu0LWhsBh7JWTYih6Vhq/RDS/HaIt0tgf20xaiVEwbtshAfsR
+djHU2KgFCua+Y0NHKsFlgE7wM1i7lcPC4oJQxVvgtK1Zac49VVgMn1M9V9K4iFrq
+D2j9mcW4Bi8bWPH2c3MdqSZZo5s1VfWWPH5CEDGyYRWC9TR8MLbeu5svnQrPgTcm
+CoQysqeP9/50LADgSwIgnEdyJizydAhecck5t6BbkimanUAfGKw4lH3d9xWP24y/
+F3MmYHkrAw88np2rlmaVFnydu4I1stzUiE5Nyrp00ATybc2vny0=
+=tSMc
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/SA-21:01/fsdisclosure.12.patch b/website/static/security/patches/SA-21:01/fsdisclosure.12.patch
new file mode 100644
index 0000000000..cee40d343f
--- /dev/null
+++ b/website/static/security/patches/SA-21:01/fsdisclosure.12.patch
@@ -0,0 +1,166 @@
+--- sys/fs/autofs/autofs_vnops.c.orig
++++ sys/fs/autofs/autofs_vnops.c
+@@ -369,6 +369,7 @@
+ return (EINVAL);
+
+ dirent.d_fileno = fileno;
++ dirent.d_off = uio->uio_offset + reclen;
+ dirent.d_reclen = reclen;
+ dirent.d_type = DT_DIR;
+ dirent.d_namlen = namlen;
+--- sys/fs/msdosfs/msdosfs_vnops.c.orig
++++ sys/fs/msdosfs/msdosfs_vnops.c
+@@ -1687,6 +1687,7 @@
+ dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf);
+ /* NOTE: d_off is the offset of the *next* entry. */
+ dirbuf.d_off = offset + sizeof(struct direntry);
++ dirent_terminate(&dirbuf);
+ if (uio->uio_resid < dirbuf.d_reclen) {
+ brelse(bp);
+ goto out;
+--- sys/fs/smbfs/smbfs_io.c.orig
++++ sys/fs/smbfs/smbfs_io.c
+@@ -103,6 +103,7 @@
+ (np->n_parent ? np->n_parentino : 2);
+ if (de.d_fileno == 0)
+ de.d_fileno = 0x7ffffffd + offset;
++ de.d_off = offset + 1;
+ de.d_namlen = offset + 1;
+ de.d_name[0] = '.';
+ de.d_name[1] = '.';
+@@ -153,6 +154,7 @@
+ bzero((caddr_t)&de, DE_SIZE);
+ de.d_reclen = DE_SIZE;
+ de.d_fileno = ctx->f_attr.fa_ino;
++ de.d_off = offset + 1;
+ de.d_type = (ctx->f_attr.fa_attr & SMB_FA_DIR) ? DT_DIR : DT_REG;
+ de.d_namlen = ctx->f_nmlen;
+ bcopy(ctx->f_name, de.d_name, de.d_namlen);
+--- sys/fs/tmpfs/tmpfs_subr.c.orig
++++ sys/fs/tmpfs/tmpfs_subr.c
+@@ -1188,6 +1188,7 @@
+ MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOT);
+
+ dent.d_fileno = node->tn_id;
++ dent.d_off = TMPFS_DIRCOOKIE_DOTDOT;
+ dent.d_type = DT_DIR;
+ dent.d_namlen = 1;
+ dent.d_name[0] = '.';
+@@ -1213,7 +1214,7 @@
+ */
+ static int
+ tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
+- struct uio *uio)
++ struct uio *uio, off_t next)
+ {
+ struct tmpfs_node *parent;
+ struct dirent dent;
+@@ -1234,6 +1235,7 @@
+ dent.d_fileno = parent->tn_id;
+ TMPFS_NODE_UNLOCK(parent);
+
++ dent.d_off = next;
+ dent.d_type = DT_DIR;
+ dent.d_namlen = 2;
+ dent.d_name[0] = '.';
+@@ -1263,7 +1265,7 @@
+ struct uio *uio, int maxcookies, u_long *cookies, int *ncookies)
+ {
+ struct tmpfs_dir_cursor dc;
+- struct tmpfs_dirent *de;
++ struct tmpfs_dirent *de, *nde;
+ off_t off;
+ int error;
+
+@@ -1284,18 +1286,19 @@
+ error = tmpfs_dir_getdotdent(tm, node, uio);
+ if (error != 0)
+ return (error);
+- uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
++ uio->uio_offset = off = TMPFS_DIRCOOKIE_DOTDOT;
+ if (cookies != NULL)
+- cookies[(*ncookies)++] = off = uio->uio_offset;
++ cookies[(*ncookies)++] = off;
+ /* FALLTHROUGH */
+ case TMPFS_DIRCOOKIE_DOTDOT:
+- error = tmpfs_dir_getdotdotdent(tm, node, uio);
++ de = tmpfs_dir_first(node, &dc);
++ off = tmpfs_dirent_cookie(de);
++ error = tmpfs_dir_getdotdotdent(tm, node, uio, off);
+ if (error != 0)
+ return (error);
+- de = tmpfs_dir_first(node, &dc);
+- uio->uio_offset = tmpfs_dirent_cookie(de);
++ uio->uio_offset = off;
+ if (cookies != NULL)
+- cookies[(*ncookies)++] = off = uio->uio_offset;
++ cookies[(*ncookies)++] = off;
+ /* EOF. */
+ if (de == NULL)
+ return (0);
+@@ -1310,13 +1313,17 @@
+ off = tmpfs_dirent_cookie(de);
+ }
+
+- /* Read as much entries as possible; i.e., until we reach the end of
+- * the directory or we exhaust uio space. */
++ /*
++ * Read as much entries as possible; i.e., until we reach the end of the
++ * directory or we exhaust uio space.
++ */
+ do {
+ struct dirent d;
+
+- /* Create a dirent structure representing the current
+- * tmpfs_node and fill it. */
++ /*
++ * Create a dirent structure representing the current tmpfs_node
++ * and fill it.
++ */
+ if (de->td_node == NULL) {
+ d.d_fileno = 1;
+ d.d_type = DT_WHT;
+@@ -1360,20 +1367,27 @@
+ MPASS(de->td_namelen < sizeof(d.d_name));
+ (void)memcpy(d.d_name, de->ud.td_name, de->td_namelen);
+ d.d_reclen = GENERIC_DIRSIZ(&d);
+- dirent_terminate(&d);
+
+- /* Stop reading if the directory entry we are treating is
+- * bigger than the amount of data that can be returned. */
++ /*
++ * Stop reading if the directory entry we are treating is bigger
++ * than the amount of data that can be returned.
++ */
+ if (d.d_reclen > uio->uio_resid) {
+ error = EJUSTRETURN;
+ break;
+ }
+
+- /* Copy the new dirent structure into the output buffer and
+- * advance pointers. */
++ nde = tmpfs_dir_next(node, &dc);
++ d.d_off = tmpfs_dirent_cookie(nde);
++ dirent_terminate(&d);
++
++ /*
++ * Copy the new dirent structure into the output buffer and
++ * advance pointers.
++ */
+ error = uiomove(&d, d.d_reclen, uio);
+ if (error == 0) {
+- de = tmpfs_dir_next(node, &dc);
++ de = nde;
+ if (cookies != NULL) {
+ off = tmpfs_dirent_cookie(de);
+ MPASS(*ncookies < maxcookies);
+--- sys/kern/uipc_mqueue.c.orig
++++ sys/kern/uipc_mqueue.c
+@@ -1426,6 +1426,7 @@
+ if (!pn->mn_fileno)
+ mqfs_fileno_alloc(mi, pn);
+ entry.d_fileno = pn->mn_fileno;
++ entry.d_off = offset + entry.d_reclen;
+ for (i = 0; i < MQFS_NAMELEN - 1 && pn->mn_name[i] != '\0'; ++i)
+ entry.d_name[i] = pn->mn_name[i];
+ entry.d_namlen = i;
diff --git a/website/static/security/patches/SA-21:01/fsdisclosure.12.patch.asc b/website/static/security/patches/SA-21:01/fsdisclosure.12.patch.asc
new file mode 100644
index 0000000000..fe012400fa
--- /dev/null
+++ b/website/static/security/patches/SA-21:01/fsdisclosure.12.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbjNfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJY7A//cxfRPjkTLhctIEVx1PCFqEQ02Fj8rarjyKu8fWPrjB7zB9DuJPIMDfzs
+VEupOfXlw0R71n+6UV3EuplbHF7jodX5g79FG0AqjrhzKmGVmN3azx/erbAQj46Q
+ccRyGNltZLtji3iD9eespNNbuXkE0HB4hgR8uwbzTtEI12l9FybrRfR/Lo0EpakX
+avnwAMSmbUp8IHvXJmiae6jNqW5qbXH0j0wUaQGIhF/ZgJtvZhRN2xbXWb7A0Uqm
+DkUSatoFnTZ3YXKh1dY7wr9qUQujoO7tqvM1RMsgX+GGQNIwIzWsWJo6bcMNKmN+
+bjVRQgLp8o2okApFKbEX535tzudGwet9xJGCrz8znUhgN0riUVsPy8/AbVFiLoWi
+Rp8YlBTuuIQEG1naOlkdwbyoNXnIKajuA3s+BawdcpQEoB8o9OSd1jdQcdafZE6d
+E9Oo/yIetviAmcu4Xt/KYXT2NbLIezDO26EYLsLver1qF9QE2A8syy3qld/mz4+n
+Q90L/Qs4iN7nDzB0WenreA7YlG0rXjG5WyXxfxIpefdaSWvd51LUU56tGJEkGzAt
+VT1kOyNKKI5zfV6K+pN3+0G7MPmfMN7au7UoAnC3C2QnbvvZZ4kxd/8+FerWyHrT
+2CQAxwErn2hDLXJn9SDU8uQnXY3cJ3efO6lx9jwGQtCpJPzKd/A=
+=DVI2
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/SA-21:02/xenoom.11.patch b/website/static/security/patches/SA-21:02/xenoom.11.patch
new file mode 100644
index 0000000000..057a656114
--- /dev/null
+++ b/website/static/security/patches/SA-21:02/xenoom.11.patch
@@ -0,0 +1,255 @@
+--- sys/dev/xen/balloon/balloon.c.orig
++++ sys/dev/xen/balloon/balloon.c
+@@ -310,7 +310,8 @@
+
+ static struct xs_watch target_watch =
+ {
+- .node = "memory/target"
++ .node = "memory/target",
++ .max_pending = 1,
+ };
+
+ /* React to a change in the target key */
+--- sys/dev/xen/blkback/blkback.c.orig
++++ sys/dev/xen/blkback/blkback.c
+@@ -3767,6 +3767,12 @@
+ xbb->hotplug_watch.callback = xbb_attach_disk;
+ KASSERT(xbb->hotplug_watch.node == NULL, ("watch node already setup"));
+ xbb->hotplug_watch.node = strdup(sbuf_data(watch_path), M_XENBLOCKBACK);
++ /*
++ * We don't care about the path updated, just about the value changes
++ * on that single node, hence there's no need to queue more that one
++ * event.
++ */
++ xbb->hotplug_watch.max_pending = 1;
+ sbuf_delete(watch_path);
+ error = xs_register_watch(&xbb->hotplug_watch);
+ if (error != 0) {
+--- sys/dev/xen/control/control.c.orig
++++ sys/dev/xen/control/control.c
+@@ -432,6 +432,12 @@
+ xctrl->xctrl_watch.node = "control/shutdown";
+ xctrl->xctrl_watch.callback = xctrl_on_watch_event;
+ xctrl->xctrl_watch.callback_data = (uintptr_t)xctrl;
++ /*
++ * We don't care about the path updated, just about the value changes
++ * on that single node, hence there's no need to queue more that one
++ * event.
++ */
++ xctrl->xctrl_watch.max_pending = 1;
+ xs_register_watch(&xctrl->xctrl_watch);
+
+ if (xen_pv_domain())
+--- sys/dev/xen/xenstore/xenstore.c.orig
++++ sys/dev/xen/xenstore/xenstore.c
+@@ -668,12 +668,17 @@
+ mtx_lock(&xs.registered_watches_lock);
+ msg->u.watch.handle = find_watch(
+ msg->u.watch.vec[XS_WATCH_TOKEN]);
+- if (msg->u.watch.handle != NULL) {
+- mtx_lock(&xs.watch_events_lock);
++ mtx_lock(&xs.watch_events_lock);
++ if (msg->u.watch.handle != NULL &&
++ (!msg->u.watch.handle->max_pending ||
++ msg->u.watch.handle->pending <
++ msg->u.watch.handle->max_pending)) {
++ msg->u.watch.handle->pending++;
+ TAILQ_INSERT_TAIL(&xs.watch_events, msg, list);
+ wakeup(&xs.watch_events);
+ mtx_unlock(&xs.watch_events_lock);
+ } else {
++ mtx_unlock(&xs.watch_events_lock);
+ free(msg->u.watch.vec, M_XENSTORE);
+ free(msg, M_XENSTORE);
+ }
+@@ -1045,8 +1050,10 @@
+
+ mtx_lock(&xs.watch_events_lock);
+ msg = TAILQ_FIRST(&xs.watch_events);
+- if (msg)
++ if (msg) {
+ TAILQ_REMOVE(&xs.watch_events, msg, list);
++ msg->u.watch.handle->pending--;
++ }
+ mtx_unlock(&xs.watch_events_lock);
+
+ if (msg != NULL) {
+@@ -1629,6 +1636,7 @@
+ char token[sizeof(watch) * 2 + 1];
+ int error;
+
++ watch->pending = 0;
+ sprintf(token, "%lX", (long)watch);
+
+ sx_slock(&xs.suspend_mutex);
+--- sys/xen/xenbus/xenbus.c.orig
++++ sys/xen/xenbus/xenbus.c
+@@ -102,48 +102,6 @@
+ return ((state < (XenbusStateClosed + 1)) ? name[state] : "INVALID");
+ }
+
+-int
+-xenbus_watch_path(device_t dev, char *path, struct xs_watch *watch,
+- xs_watch_cb_t *callback, uintptr_t callback_data)
+-{
+- int error;
+-
+- watch->node = path;
+- watch->callback = callback;
+- watch->callback_data = callback_data;
+-
+- error = xs_register_watch(watch);
+-
+- if (error) {
+- watch->node = NULL;
+- watch->callback = NULL;
+- xenbus_dev_fatal(dev, error, "adding watch on %s", path);
+- }
+-
+- return (error);
+-}
+-
+-int
+-xenbus_watch_path2(device_t dev, const char *path,
+- const char *path2, struct xs_watch *watch,
+- xs_watch_cb_t *callback, uintptr_t callback_data)
+-{
+- int error;
+- char *state = malloc(strlen(path) + 1 + strlen(path2) + 1,
+- M_XENBUS, M_WAITOK);
+-
+- strcpy(state, path);
+- strcat(state, "/");
+- strcat(state, path2);
+-
+- error = xenbus_watch_path(dev, state, watch, callback, callback_data);
+- if (error) {
+- free(state,M_XENBUS);
+- }
+-
+- return (error);
+-}
+-
+ void
+ xenbus_dev_verror(device_t dev, int err, const char *fmt, va_list ap)
+ {
+--- sys/xen/xenbus/xenbusb.c.orig
++++ sys/xen/xenbus/xenbusb.c
+@@ -702,10 +702,21 @@
+ ivars->xd_otherend_watch.node = statepath;
+ ivars->xd_otherend_watch.callback = xenbusb_otherend_watch_cb;
+ ivars->xd_otherend_watch.callback_data = (uintptr_t)ivars;
++ /*
++ * Other end state node watch, limit to one pending event
++ * to prevent frontends from queuing too many events that
++ * could cause resource starvation.
++ */
++ ivars->xd_otherend_watch.max_pending = 1;
+
+ ivars->xd_local_watch.node = ivars->xd_node;
+ ivars->xd_local_watch.callback = xenbusb_local_watch_cb;
+ ivars->xd_local_watch.callback_data = (uintptr_t)ivars;
++ /*
++ * Watch our local path, only writable by us or a privileged
++ * domain, no need to limit.
++ */
++ ivars->xd_local_watch.max_pending = 0;
+
+ mtx_lock(&xbs->xbs_lock);
+ xbs->xbs_connecting_children++;
+@@ -764,6 +775,12 @@
+ xbs->xbs_device_watch.node = bus_node;
+ xbs->xbs_device_watch.callback = xenbusb_devices_changed;
+ xbs->xbs_device_watch.callback_data = (uintptr_t)xbs;
++ /*
++ * Allow for unlimited pending watches, as those are local paths
++ * either controlled by the guest or only writable by privileged
++ * domains.
++ */
++ xbs->xbs_device_watch.max_pending = 0;
+
+ TASK_INIT(&xbs->xbs_probe_children, 0, xenbusb_probe_children_cb, dev);
+
+--- sys/xen/xenbus/xenbusvar.h.orig
++++ sys/xen/xenbus/xenbusvar.h
+@@ -123,62 +123,6 @@
+ return (xenbus_read_driver_state(xenbus_get_otherend_path(dev)));
+ }
+
+-/**
+- * Initialize and register a watch on the given path (client suplied storage).
+- *
+- * \param dev The XenBus device requesting the watch service.
+- * \param path The XenStore path of the object to be watched. The
+- * storage for this string must be stable for the lifetime
+- * of the watch.
+- * \param watch The watch object to use for this request. This object
+- * must be stable for the lifetime of the watch.
+- * \param callback The function to call when XenStore objects at or below
+- * path are modified.
+- * \param cb_data Client data that can be retrieved from the watch object
+- * during the callback.
+- *
+- * \return On success, 0. Otherwise an errno value indicating the
+- * type of failure.
+- *
+- * \note On error, the device 'dev' will be switched to the XenbusStateClosing
+- * state and the returned error is saved in the per-device error node
+- * for dev in the XenStore.
+- */
+-int xenbus_watch_path(device_t dev, char *path,
+- struct xs_watch *watch,
+- xs_watch_cb_t *callback,
+- uintptr_t cb_data);
+-
+-/**
+- * Initialize and register a watch at path/path2 in the XenStore.
+- *
+- * \param dev The XenBus device requesting the watch service.
+- * \param path The base XenStore path of the object to be watched.
+- * \param path2 The tail XenStore path of the object to be watched.
+- * \param watch The watch object to use for this request. This object
+- * must be stable for the lifetime of the watch.
+- * \param callback The function to call when XenStore objects at or below
+- * path are modified.
+- * \param cb_data Client data that can be retrieved from the watch object
+- * during the callback.
+- *
+- * \return On success, 0. Otherwise an errno value indicating the
+- * type of failure.
+- *
+- * \note On error, \a dev will be switched to the XenbusStateClosing
+- * state and the returned error is saved in the per-device error node
+- * for \a dev in the XenStore.
+- *
+- * Similar to xenbus_watch_path, however the storage for the path to the
+- * watched object is allocated from the heap and filled with "path '/' path2".
+- * Should a call to this function succeed, it is the callers responsibility
+- * to free watch->node using the M_XENBUS malloc type.
+- */
+-int xenbus_watch_path2(device_t dev, const char *path,
+- const char *path2, struct xs_watch *watch,
+- xs_watch_cb_t *callback,
+- uintptr_t cb_data);
+-
+ /**
+ * Grant access to the given ring_mfn to the peer of the given device.
+ *
+--- sys/xen/xenstore/xenstorevar.h.orig
++++ sys/xen/xenstore/xenstorevar.h
+@@ -72,6 +72,15 @@
+
+ /* Callback client data untouched by the XenStore watch mechanism. */
+ uintptr_t callback_data;
++
++ /* Maximum number of pending watch events to be delivered. */
++ unsigned int max_pending;
++
++ /*
++ * Private counter used by xenstore to keep track of the pending
++ * watches. Protected by xs.watch_events_lock.
++ */
++ unsigned int pending;
+ };
+ LIST_HEAD(xs_watch_list, xs_watch);
+
diff --git a/website/static/security/patches/SA-21:02/xenoom.11.patch.asc b/website/static/security/patches/SA-21:02/xenoom.11.patch.asc
new file mode 100644
index 0000000000..3b7f0b10ef
--- /dev/null
+++ b/website/static/security/patches/SA-21:02/xenoom.11.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAmATbjRfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cKfghAAkrse02lN4PZizc0OEsABoBTpTLLNFTTQ+3alY9MeYmLzgoP6crG6nETa
+VwRh44ztjXeMB0/HUKu4rCcSbasYPLYAGZ+z8WCGmgVs30og7m6fC1eLb3zvlHxq
+O4J9E3JhvQIPbhFpZMDMyjj+aS4SncgB7Hswcr3FGuUQkl9ySm7frV6umDHkwaiN
+0wNEQVHQIQSVxawSG2+hMwVCDH/rxm2gLPpoTlQ4rwD3dsr6Ul8hCqPTTUV7vpRE
+88AAv+xPgglWjNFo2LAYvtXjTiO3/v+TfiNnf47uwbMpmEaUKRDDirMqrAd8k6x4
+UgbYC+Dils9Fbo+hc2P8kxwaDDb3xPk6RwPErCbQfyoF2w09YQeaIB5na9aRV43u
+qCOj/3OFcuZxEqY1pWLWutD6HM2qi72Btm2U4dp/zFa6V7x4hRKrxmimM07uJGRy
+/Pk3mBpLQLm0wbjSTR+8+RFM4fYRUQbJYZFINn99WDsL4zqD/KzL/ZW5e2pFjRcC
+n2DuuMULHQ1ivBZmdMBOIvx5JUllHn5vazDVErIdILJhAb4ypFpuyFdkBUNO72Hn
+dfrNrwABGi57nqxdAP8nIYTEUyUxm6q3vC4VXsoarYZvGECmWLrNWSADR7YtsMSi
+7C9lanrEy3CH4eFwXkPTYAvmLgubQTm5pMxCZfM/qHSkUhVocBQ=
+=6nop
+-----END PGP SIGNATURE-----
diff --git a/website/static/security/patches/SA-21:02/xenoom.12.patch b/website/static/security/patches/SA-21:02/xenoom.12.patch
new file mode 100644
index 0000000000..f8797b1123
--- /dev/null
+++ b/website/static/security/patches/SA-21:02/xenoom.12.patch
@@ -0,0 +1,300 @@
+--- sys/dev/xen/balloon/balloon.c.orig
++++ sys/dev/xen/balloon/balloon.c
+@@ -310,7 +310,8 @@
+
+ static struct xs_watch target_watch =
+ {
+- .node = "memory/target"
++ .node = "memory/target",
++ .max_pending = 1,
+ };
+
+ /* React to a change in the target key */
+--- sys/dev/xen/blkback/blkback.c.orig
++++ sys/dev/xen/blkback/blkback.c
+@@ -3768,6 +3768,12 @@
+ xbb->hotplug_watch.callback = xbb_attach_disk;
+ KASSERT(xbb->hotplug_watch.node == NULL, ("watch node already setup"));
+ xbb->hotplug_watch.node = strdup(sbuf_data(watch_path), M_XENBLOCKBACK);
++ /*
++ * We don't care about the path updated, just about the value changes
++ * on that single node, hence there's no need to queue more that one
++ * event.
++ */
++ xbb->hotplug_watch.max_pending = 1;
+ sbuf_delete(watch_path);
+ error = xs_register_watch(&xbb->hotplug_watch);
+ if (error != 0) {
+--- sys/dev/xen/control/control.c.orig
++++ sys/dev/xen/control/control.c
+@@ -432,6 +432,12 @@
+ xctrl->xctrl_watch.node = "control/shutdown";
+ xctrl->xctrl_watch.callback = xctrl_on_watch_event;
+ xctrl->xctrl_watch.callback_data = (uintptr_t)xctrl;
++ /*
++ * We don't care about the path updated, just about the value changes
++ * on that single node, hence there's no need to queue more that one
++ * event.
++ */
++ xctrl->xctrl_watch.max_pending = 1;
+ xs_register_watch(&xctrl->xctrl_watch);
+
+ if (xen_pv_domain())
+--- sys/dev/xen/xenstore/xenstore.c.orig
++++ sys/dev/xen/xenstore/xenstore.c
+@@ -656,12 +656,17 @@
+ mtx_lock(&xs.registered_watches_lock);
+ msg->u.watch.handle = find_watch(
+ msg->u.watch.vec[XS_WATCH_TOKEN]);
+- if (msg->u.watch.handle != NULL) {
+- mtx_lock(&xs.watch_events_lock);
++ mtx_lock(&xs.watch_events_lock);
++ if (msg->u.watch.handle != NULL &&
++ (!msg->u.watch.handle->max_pending ||
++ msg->u.watch.handle->pending <
++ msg->u.watch.handle->max_pending)) {
++ msg->u.watch.handle->pending++;
+ TAILQ_INSERT_TAIL(&xs.watch_events, msg, list);
+ wakeup(&xs.watch_events);
+ mtx_unlock(&xs.watch_events_lock);
+ } else {
++ mtx_unlock(&xs.watch_events_lock);
+ free(msg->u.watch.vec, M_XENSTORE);
+ free(msg, M_XENSTORE);
+ }
+@@ -983,8 +988,10 @@
+
+ mtx_lock(&xs.watch_events_lock);
+ msg = TAILQ_FIRST(&xs.watch_events);
+- if (msg)
++ if (msg) {
+ TAILQ_REMOVE(&xs.watch_events, msg, list);
++ msg->u.watch.handle->pending--;
++ }
+ mtx_unlock(&xs.watch_events_lock);
+
+ if (msg != NULL) {
+@@ -1578,6 +1585,7 @@
+ char token[sizeof(watch) * 2 + 1];
+ int error;
+
++ watch->pending = 0;
+ sprintf(token, "%lX", (long)watch);
+
+ mtx_lock(&xs.registered_watches_lock);
+--- sys/dev/xen/xenstore/xenstore_dev.c.orig
++++ sys/dev/xen/xenstore/xenstore_dev.c
+@@ -45,6 +45,7 @@
+ #include