aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-filesystems/recipes-filesystems/ntfs-3g-ntfsprogs/ntfs-3g-ntfsprogs_2022.10.3.bb (renamed from meta-filesystems/recipes-filesystems/ntfs-3g-ntfsprogs/ntfs-3g-ntfsprogs_2022.5.17.bb)2
-rw-r--r--meta-networking/recipes-connectivity/networkmanager/networkmanager_1.22.16.bb (renamed from meta-networking/recipes-connectivity/networkmanager/networkmanager_1.22.10.bb)3
-rw-r--r--meta-networking/recipes-kernel/wireguard/files/0001-compat-SYM_FUNC_-START-END-were-backported-to-5.4.patch29
-rw-r--r--meta-networking/recipes-kernel/wireguard/files/0001-compat-icmp_ndo_send-functions-were-backported-exten.patch32
-rw-r--r--meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20200401.bb30
-rw-r--r--meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20220627.bb23
-rw-r--r--meta-networking/recipes-kernel/wireguard/wireguard-tools_1.0.20210914.bb (renamed from meta-networking/recipes-kernel/wireguard/wireguard-tools_1.0.20200319.bb)4
-rw-r--r--meta-networking/recipes-support/dnsmasq/dnsmasq/CVE-2022-0934.patch188
-rw-r--r--meta-networking/recipes-support/dnsmasq/dnsmasq_2.81.bb1
-rw-r--r--meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch210
-rw-r--r--meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb1
-rw-r--r--meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch904
-rw-r--r--meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb1
-rw-r--r--meta-oe/recipes-devtools/flatbuffers/flatbuffers_1.12.0.bb7
-rw-r--r--meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch319
-rw-r--r--meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb4
16 files changed, 1661 insertions, 97 deletions
diff --git a/meta-filesystems/recipes-filesystems/ntfs-3g-ntfsprogs/ntfs-3g-ntfsprogs_2022.5.17.bb b/meta-filesystems/recipes-filesystems/ntfs-3g-ntfsprogs/ntfs-3g-ntfsprogs_2022.10.3.bb
index cb52c55676..efb331d7b2 100644
--- a/meta-filesystems/recipes-filesystems/ntfs-3g-ntfsprogs/ntfs-3g-ntfsprogs_2022.5.17.bb
+++ b/meta-filesystems/recipes-filesystems/ntfs-3g-ntfsprogs/ntfs-3g-ntfsprogs_2022.10.3.bb
@@ -10,7 +10,7 @@ SRC_URI = "http://tuxera.com/opensource/ntfs-3g_ntfsprogs-${PV}.tgz \
file://0001-libntfs-3g-Makefile.am-fix-install-failed-while-host.patch \
"
S = "${WORKDIR}/ntfs-3g_ntfsprogs-${PV}"
-SRC_URI[sha256sum] = "0489fbb6972581e1b417ab578d543f6ae522e7fa648c3c9b49c789510fd5eb93"
+SRC_URI[sha256sum] = "f20e36ee68074b845e3629e6bced4706ad053804cbaf062fbae60738f854170c"
UPSTREAM_CHECK_URI = "https://www.tuxera.com/community/open-source-ntfs-3g/"
UPSTREAM_CHECK_REGEX = "ntfs-3g_ntfsprogs-(?P<pver>\d+(\.\d+)+)\.tgz"
diff --git a/meta-networking/recipes-connectivity/networkmanager/networkmanager_1.22.10.bb b/meta-networking/recipes-connectivity/networkmanager/networkmanager_1.22.16.bb
index 33a2b7c0ce..a28372dd1f 100644
--- a/meta-networking/recipes-connectivity/networkmanager/networkmanager_1.22.10.bb
+++ b/meta-networking/recipes-connectivity/networkmanager/networkmanager_1.22.16.bb
@@ -33,11 +33,12 @@ SRC_URI_append_libc-musl = " \
file://musl/0003-Fix-build-with-musl-for-n-dhcp4.patch \
file://musl/0004-Fix-build-with-musl-systemd-specific.patch \
"
-SRC_URI[sha256sum] = "2b29ccc1531ba7ebba95a97f40c22b963838e8b6833745efe8e6fb71fd8fca77"
+SRC_URI[sha256sum] = "377aa053752eaa304b72c9906f9efcd9fbd5f7f6cb4cd4ad72425a68982cffc6"
S = "${WORKDIR}/NetworkManager-${PV}"
EXTRA_OECONF = " \
+ --disable-firewalld-zone \
--disable-ifcfg-rh \
--disable-more-warnings \
--with-iptables=${sbindir}/iptables \
diff --git a/meta-networking/recipes-kernel/wireguard/files/0001-compat-SYM_FUNC_-START-END-were-backported-to-5.4.patch b/meta-networking/recipes-kernel/wireguard/files/0001-compat-SYM_FUNC_-START-END-were-backported-to-5.4.patch
deleted file mode 100644
index a9dc9dc2b7..0000000000
--- a/meta-networking/recipes-kernel/wireguard/files/0001-compat-SYM_FUNC_-START-END-were-backported-to-5.4.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From ce8faa3ee266ea69431805e6ed4bd7102d982508 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Thu, 12 Nov 2020 09:43:38 +0100
-Subject: [PATCH] compat: SYM_FUNC_{START,END} were backported to 5.4
-
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-
-Upstream-Status: Backport
-Fixes build failure in Dunfell.
-
-Signed-off-by: Armin Kuster <akuster808@gmail.com>
-
----
- compat/compat-asm.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: src/compat/compat-asm.h
-===================================================================
---- src.orig/compat/compat-asm.h
-+++ src/compat/compat-asm.h
-@@ -40,7 +40,7 @@
- #undef pull
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 76)
- #define SYM_FUNC_START ENTRY
- #define SYM_FUNC_END ENDPROC
- #endif
diff --git a/meta-networking/recipes-kernel/wireguard/files/0001-compat-icmp_ndo_send-functions-were-backported-exten.patch b/meta-networking/recipes-kernel/wireguard/files/0001-compat-icmp_ndo_send-functions-were-backported-exten.patch
deleted file mode 100644
index f01cfe4e1c..0000000000
--- a/meta-networking/recipes-kernel/wireguard/files/0001-compat-icmp_ndo_send-functions-were-backported-exten.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 122f06bfd8fc7b06a0899fa9adc4ce8e06900d98 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Sun, 7 Mar 2021 08:14:33 -0700
-Subject: [PATCH] compat: icmp_ndo_send functions were backported extensively
-
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-
-Upstream-Status: Backport
-
-Fixes build with 5.4.103 update.
-/include/linux/icmpv6.h:56:6: note: previous declaration of 'icmpv6_ndo_send' was here
-| 56 | void icmpv6_ndo_send(struct sk_buff *skb_in, u8 type, u8 code, __u32 info);
-
-Signed-of-by: Armin Kuster <akuster808@gmail.com>
-
----
- src/compat/compat.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: src/compat/compat.h
-===================================================================
---- src.orig/compat/compat.h
-+++ src/compat/compat.h
-@@ -946,7 +946,7 @@ static inline int skb_ensure_writable(st
- }
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) || (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 102) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 178) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 223) && LINUX_VERSION_CODE > KERNEL_VERSION(4, 10, 0)) || LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 259) || defined(ISRHEL8) || defined(ISUBUNTU1804)
- #if IS_ENABLED(CONFIG_NF_NAT)
- #include <linux/ip.h>
- #include <linux/icmpv6.h>
diff --git a/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20200401.bb b/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20200401.bb
deleted file mode 100644
index 9215f4a6d8..0000000000
--- a/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20200401.bb
+++ /dev/null
@@ -1,30 +0,0 @@
-require wireguard.inc
-
-SRCREV = "43f57dac7b8305024f83addc533c9eede6509129"
-
-SRC_URI = "git://git.zx2c4.com/wireguard-linux-compat;branch=master \
- file://0001-compat-SYM_FUNC_-START-END-were-backported-to-5.4.patch \
- file://0001-compat-icmp_ndo_send-functions-were-backported-exten.patch "
-
-inherit module kernel-module-split
-
-DEPENDS = "virtual/kernel libmnl"
-
-# This module requires Linux 3.10 higher and several networking related
-# configuration options. For exact kernel requirements visit:
-# https://www.wireguard.io/install/#kernel-requirements
-
-EXTRA_OEMAKE_append = " \
- KERNELDIR=${STAGING_KERNEL_DIR} \
- "
-
-MAKE_TARGETS = "module"
-
-RRECOMMENDS_${PN} = "kernel-module-xt-hashlimit"
-MODULE_NAME = "wireguard"
-
-module_do_install() {
- install -d ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/${MODULE_NAME}
- install -m 0644 ${MODULE_NAME}.ko \
- ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/${MODULE_NAME}/${MODULE_NAME}.ko
-}
diff --git a/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20220627.bb b/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20220627.bb
new file mode 100644
index 0000000000..df2db15349
--- /dev/null
+++ b/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20220627.bb
@@ -0,0 +1,23 @@
+require wireguard.inc
+
+SRCREV = "18fbcd68a35a892527345dc5679d0b2d860ee004"
+
+SRC_URI = "git://git.zx2c4.com/wireguard-linux-compat;protocol=https;branch=master"
+
+inherit module kernel-module-split
+
+DEPENDS = "virtual/kernel libmnl"
+
+# This module requires Linux 3.10 higher and several networking related
+# configuration options. For exact kernel requirements visit:
+# https://www.wireguard.io/install/#kernel-requirements
+
+EXTRA_OEMAKE_append = " \
+ KERNELDIR=${STAGING_KERNEL_DIR} \
+ "
+
+MAKE_TARGETS = "module"
+MODULES_INSTALL_TARGET = "module-install"
+
+RRECOMMENDS_${PN} = "kernel-module-xt-hashlimit"
+MODULE_NAME = "wireguard"
diff --git a/meta-networking/recipes-kernel/wireguard/wireguard-tools_1.0.20200319.bb b/meta-networking/recipes-kernel/wireguard/wireguard-tools_1.0.20210914.bb
index 9e486ecc34..b63ef88182 100644
--- a/meta-networking/recipes-kernel/wireguard/wireguard-tools_1.0.20200319.bb
+++ b/meta-networking/recipes-kernel/wireguard/wireguard-tools_1.0.20210914.bb
@@ -1,6 +1,6 @@
require wireguard.inc
-SRCREV = "a8063adc8ae9b4fc9848500e93f94bee8ad2e585"
+SRCREV = "3ba6527130c502144e7388b900138bca6260f4e8"
SRC_URI = "git://git.zx2c4.com/wireguard-tools;branch=master"
inherit bash-completion systemd pkgconfig
@@ -9,7 +9,7 @@ DEPENDS += "wireguard-module libmnl"
do_install () {
oe_runmake DESTDIR="${D}" PREFIX="${prefix}" SYSCONFDIR="${sysconfdir}" \
- SYSTEMDUNITDIR="${systemd_unitdir}" \
+ SYSTEMDUNITDIR="${systemd_system_unitdir}" \
WITH_SYSTEMDUNITS=${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'yes', '', d)} \
WITH_BASHCOMPLETION=yes \
WITH_WGQUICK=yes \
diff --git a/meta-networking/recipes-support/dnsmasq/dnsmasq/CVE-2022-0934.patch b/meta-networking/recipes-support/dnsmasq/dnsmasq/CVE-2022-0934.patch
new file mode 100644
index 0000000000..b2ef22c06f
--- /dev/null
+++ b/meta-networking/recipes-support/dnsmasq/dnsmasq/CVE-2022-0934.patch
@@ -0,0 +1,188 @@
+From 70df9f9104c8f0661966298b58caf794b99e26e1 Mon Sep 17 00:00:00 2001
+From: Hitendra Prajapati <hprajapati@mvista.com>
+Date: Thu, 22 Sep 2022 17:39:21 +0530
+Subject: [PATCH] CVE-2022-0934
+
+Upstream-Status: Backport [https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=03345ecefeb0d82e3c3a4c28f27c3554f0611b39]
+CVE: CVE-2022-0934
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ CHANGELOG | 2 ++
+ src/rfc3315.c | 48 +++++++++++++++++++++++++++---------------------
+ 2 files changed, 29 insertions(+), 21 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 60b08d0..d1d7e41 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -88,6 +88,8 @@ version 2.81
+
+ Add --script-on-renewal option.
+
++ Fix write-after-free error in DHCPv6 server code.
++ CVE-2022-0934 refers.
+
+ version 2.80
+ Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
+diff --git a/src/rfc3315.c b/src/rfc3315.c
+index b3f0a0a..eef1360 100644
+--- a/src/rfc3315.c
++++ b/src/rfc3315.c
+@@ -33,9 +33,9 @@ struct state {
+ unsigned int mac_len, mac_type;
+ };
+
+-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
++static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
+ struct in6_addr *client_addr, int is_unicast, time_t now);
+-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now);
++static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
+ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
+ static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
+ static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
+@@ -104,12 +104,12 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
+ }
+
+ /* This cost me blood to write, it will probably cost you blood to understand - srk. */
+-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
++static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
+ struct in6_addr *client_addr, int is_unicast, time_t now)
+ {
+ void *end = inbuff + sz;
+ void *opts = inbuff + 34;
+- int msg_type = *((unsigned char *)inbuff);
++ int msg_type = *inbuff;
+ unsigned char *outmsgtypep;
+ void *opt;
+ struct dhcp_vendor *vendor;
+@@ -259,15 +259,15 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
+ return 1;
+ }
+
+-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
++static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
+ {
+ void *opt;
+- int i, o, o1, start_opts;
++ int i, o, o1, start_opts, start_msg;
+ struct dhcp_opt *opt_cfg;
+ struct dhcp_netid *tagif;
+ struct dhcp_config *config = NULL;
+ struct dhcp_netid known_id, iface_id, v6_id;
+- unsigned char *outmsgtypep;
++ unsigned char outmsgtype;
+ struct dhcp_vendor *vendor;
+ struct dhcp_context *context_tmp;
+ struct dhcp_mac *mac_opt;
+@@ -296,12 +296,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ v6_id.next = state->tags;
+ state->tags = &v6_id;
+
+- /* copy over transaction-id, and save pointer to message type */
+- if (!(outmsgtypep = put_opt6(inbuff, 4)))
++ start_msg = save_counter(-1);
++ /* copy over transaction-id */
++ if (!put_opt6(inbuff, 4))
+ return 0;
+ start_opts = save_counter(-1);
+- state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
+-
++ state->xid = inbuff[3] | inbuff[2] << 8 | inbuff[1] << 16;
++
+ /* We're going to be linking tags from all context we use.
+ mark them as unused so we don't link one twice and break the list */
+ for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
+@@ -347,7 +348,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
+
+ {
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ o1 = new_opt6(OPTION6_STATUS_CODE);
+ put_opt6_short(DHCP6USEMULTI);
+ put_opt6_string("Use multicast");
+@@ -619,11 +620,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ struct dhcp_netid *solicit_tags;
+ struct dhcp_context *c;
+
+- *outmsgtypep = DHCP6ADVERTISE;
++ outmsgtype = DHCP6ADVERTISE;
+
+ if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
+ {
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ state->lease_allocate = 1;
+ o = new_opt6(OPTION6_RAPID_COMMIT);
+ end_opt6(o);
+@@ -809,7 +810,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ int start = save_counter(-1);
+
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ state->lease_allocate = 1;
+
+ log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
+@@ -921,7 +922,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ case DHCP6RENEW:
+ {
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPRENEW", NULL, NULL);
+
+@@ -1033,7 +1034,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ int good_addr = 0;
+
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
+
+@@ -1097,7 +1098,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
+ if (ignore)
+ return 0;
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+ tagif = add_options(state, 1);
+ break;
+ }
+@@ -1106,7 +1107,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ case DHCP6RELEASE:
+ {
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPRELEASE", NULL, NULL);
+
+@@ -1171,7 +1172,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ case DHCP6DECLINE:
+ {
+ /* set reply message type */
+- *outmsgtypep = DHCP6REPLY;
++ outmsgtype = DHCP6REPLY;
+
+ log6_quiet(state, "DHCPDECLINE", NULL, NULL);
+
+@@ -1251,7 +1252,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ }
+
+ }
+-
++
++ /* Fill in the message type. Note that we store the offset,
++ not a direct pointer, since the packet memory may have been
++ reallocated. */
++ ((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
++
+ log_tags(tagif, state->xid);
+ log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
+
+--
+2.25.1
+
diff --git a/meta-networking/recipes-support/dnsmasq/dnsmasq_2.81.bb b/meta-networking/recipes-support/dnsmasq/dnsmasq_2.81.bb
index 2fb389915b..8db57edb79 100644
--- a/meta-networking/recipes-support/dnsmasq/dnsmasq_2.81.bb
+++ b/meta-networking/recipes-support/dnsmasq/dnsmasq_2.81.bb
@@ -11,4 +11,5 @@ SRC_URI += "\
file://CVE-2020-25686-1.patch \
file://CVE-2020-25686-2.patch \
file://CVE-2021-3448.patch \
+ file://CVE-2022-0934.patch \
"
diff --git a/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch b/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch
new file mode 100644
index 0000000000..66e5047125
--- /dev/null
+++ b/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch
@@ -0,0 +1,210 @@
+From 66d3b2e0e596a6eac1ebcd15c83a8d9368fe7b34 Mon Sep 17 00:00:00 2001
+From: Tobias Brunner <tobias@strongswan.org>
+Date: Fri, 22 Jul 2022 15:37:43 +0200
+Subject: [PATCH] credential-manager: Do online revocation checks only after
+ basic trust chain validation
+
+This avoids querying URLs of potentially untrusted certificates, e.g. if
+an attacker sends a specially crafted end-entity and intermediate CA
+certificate with a CDP that points to a server that completes the
+TCP handshake but then does not send any further data, which will block
+the fetcher thread (depending on the plugin) for as long as the default
+timeout for TCP. Doing that multiple times will block all worker threads,
+leading to a DoS attack.
+
+The logging during the certificate verification obviously changes. The
+following example shows the output of `pki --verify` for the current
+strongswan.org certificate:
+
+new:
+
+ using certificate "CN=www.strongswan.org"
+ using trusted intermediate ca certificate "C=US, O=Let's Encrypt, CN=R3"
+ using trusted ca certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
+ reached self-signed root ca with a path length of 1
+checking certificate status of "CN=www.strongswan.org"
+ requesting ocsp status from 'http://r3.o.lencr.org' ...
+ ocsp response correctly signed by "C=US, O=Let's Encrypt, CN=R3"
+ ocsp response is valid: until Jul 27 12:59:58 2022
+certificate status is good
+checking certificate status of "C=US, O=Let's Encrypt, CN=R3"
+ocsp response verification failed, no signer certificate 'C=US, O=Let's Encrypt, CN=R3' found
+ fetching crl from 'http://x1.c.lencr.org/' ...
+ using trusted certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
+ crl correctly signed by "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
+ crl is valid: until Apr 18 01:59:59 2023
+certificate status is good
+certificate trusted, lifetimes valid, certificate not revoked
+
+old:
+
+ using certificate "CN=www.strongswan.org"
+ using trusted intermediate ca certificate "C=US, O=Let's Encrypt, CN=R3"
+checking certificate status of "CN=www.strongswan.org"
+ requesting ocsp status from 'http://r3.o.lencr.org' ...
+ ocsp response correctly signed by "C=US, O=Let's Encrypt, CN=R3"
+ ocsp response is valid: until Jul 27 12:59:58 2022
+certificate status is good
+ using trusted ca certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
+checking certificate status of "C=US, O=Let's Encrypt, CN=R3"
+ocsp response verification failed, no signer certificate 'C=US, O=Let's Encrypt, CN=R3' found
+ fetching crl from 'http://x1.c.lencr.org/' ...
+ using trusted certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
+ crl correctly signed by "C=US, O=Internet Security Research Group, CN=ISRG Root X1"
+ crl is valid: until Apr 18 01:59:59 2023
+certificate status is good
+ reached self-signed root ca with a path length of 1
+certificate trusted, lifetimes valid, certificate not revoked
+
+Note that this also fixes an issue with the previous dual-use of the
+`trusted` flag. It not only indicated whether the chain is trusted but
+also whether the current issuer is the root anchor (the corresponding
+flag in the `cert_validator_t` interface is called `anchor`). This was
+a problem when building multi-level trust chains for pre-trusted
+end-entity certificates (i.e. where `trusted` is TRUE from the start).
+This caused the main loop to get aborted after the first intermediate CA
+certificate and the mentioned `anchor` flag wasn't correct in any calls
+to `cert_validator_t` implementations.
+
+Fixes: CVE-2022-40617
+
+CVE: CVE-2022-40617
+Upstream-Status: Backport [https://download.strongswan.org/security/CVE-2022-40617/strongswan-5.1.0-5.9.7_cert_online_validate.patch]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ .../credentials/credential_manager.c | 54 +++++++++++++++----
+ 1 file changed, 45 insertions(+), 9 deletions(-)
+
+diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
+index e93b5943a3a7..798785544e41 100644
+--- a/src/libstrongswan/credentials/credential_manager.c
++++ b/src/libstrongswan/credentials/credential_manager.c
+@@ -556,7 +556,7 @@ static void cache_queue(private_credential_manager_t *this)
+ */
+ static bool check_lifetime(private_credential_manager_t *this,
+ certificate_t *cert, char *label,
+- int pathlen, bool trusted, auth_cfg_t *auth)
++ int pathlen, bool anchor, auth_cfg_t *auth)
+ {
+ time_t not_before, not_after;
+ cert_validator_t *validator;
+@@ -571,7 +571,7 @@ static bool check_lifetime(private_credential_manager_t *this,
+ continue;
+ }
+ status = validator->check_lifetime(validator, cert,
+- pathlen, trusted, auth);
++ pathlen, anchor, auth);
+ if (status != NEED_MORE)
+ {
+ break;
+@@ -604,13 +604,13 @@ static bool check_lifetime(private_credential_manager_t *this,
+ */
+ static bool check_certificate(private_credential_manager_t *this,
+ certificate_t *subject, certificate_t *issuer, bool online,
+- int pathlen, bool trusted, auth_cfg_t *auth)
++ int pathlen, bool anchor, auth_cfg_t *auth)
+ {
+ cert_validator_t *validator;
+ enumerator_t *enumerator;
+
+ if (!check_lifetime(this, subject, "subject", pathlen, FALSE, auth) ||
+- !check_lifetime(this, issuer, "issuer", pathlen + 1, trusted, auth))
++ !check_lifetime(this, issuer, "issuer", pathlen + 1, anchor, auth))
+ {
+ return FALSE;
+ }
+@@ -623,7 +623,7 @@ static bool check_certificate(private_credential_manager_t *this,
+ continue;
+ }
+ if (!validator->validate(validator, subject, issuer,
+- online, pathlen, trusted, auth))
++ online, pathlen, anchor, auth))
+ {
+ enumerator->destroy(enumerator);
+ return FALSE;
+@@ -726,6 +726,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
+ auth_cfg_t *auth;
+ signature_params_t *scheme;
+ int pathlen;
++ bool is_anchor = FALSE;
+
+ auth = auth_cfg_create();
+ get_key_strength(subject, auth);
+@@ -743,7 +744,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
+ auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
+ DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"",
+ issuer->get_subject(issuer));
+- trusted = TRUE;
++ trusted = is_anchor = TRUE;
+ }
+ else
+ {
+@@ -778,11 +779,18 @@ static bool verify_trust_chain(private_credential_manager_t *this,
+ DBG1(DBG_CFG, " issuer is \"%Y\"",
+ current->get_issuer(current));
+ call_hook(this, CRED_HOOK_NO_ISSUER, current);
++ if (trusted)
++ {
++ DBG1(DBG_CFG, " reached end of incomplete trust chain for "
++ "trusted certificate \"%Y\"",
++ subject->get_subject(subject));
++ }
+ break;
+ }
+ }
+- if (!check_certificate(this, current, issuer, online,
+- pathlen, trusted, auth))
++ /* don't do online verification here */
++ if (!check_certificate(this, current, issuer, FALSE,
++ pathlen, is_anchor, auth))
+ {
+ trusted = FALSE;
+ issuer->destroy(issuer);
+@@ -794,7 +802,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
+ }
+ current->destroy(current);
+ current = issuer;
+- if (trusted)
++ if (is_anchor)
+ {
+ DBG1(DBG_CFG, " reached self-signed root ca with a "
+ "path length of %d", pathlen);
+@@ -807,6 +815,34 @@ static bool verify_trust_chain(private_credential_manager_t *this,
+ DBG1(DBG_CFG, "maximum path length of %d exceeded", MAX_TRUST_PATH_LEN);
+ call_hook(this, CRED_HOOK_EXCEEDED_PATH_LEN, subject);
+ }
++ else if (trusted && online)
++ {
++ enumerator_t *enumerator;
++ auth_rule_t rule;
++
++ /* do online revocation checks after basic validation of the chain */
++ pathlen = 0;
++ current = subject;
++ enumerator = auth->create_enumerator(auth);
++ while (enumerator->enumerate(enumerator, &rule, &issuer))
++ {
++ if (rule == AUTH_RULE_CA_CERT || rule == AUTH_RULE_IM_CERT)
++ {
++ if (!check_certificate(this, current, issuer, TRUE, pathlen++,
++ rule == AUTH_RULE_CA_CERT, auth))
++ {
++ trusted = FALSE;
++ break;
++ }
++ else if (rule == AUTH_RULE_CA_CERT)
++ {
++ break;
++ }
++ current = issuer;
++ }
++ }
++ enumerator->destroy(enumerator);
++ }
+ if (trusted)
+ {
+ result->merge(result, auth, FALSE);
+--
+2.25.1
+
diff --git a/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb b/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb
index 8a5855fb87..c11748645c 100644
--- a/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb
+++ b/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb
@@ -14,6 +14,7 @@ SRC_URI = "http://download.strongswan.org/strongswan-${PV}.tar.bz2 \
file://CVE-2021-41990.patch \
file://CVE-2021-41991.patch \
file://CVE-2021-45079.patch \
+ file://CVE-2022-40617.patch \
"
SRC_URI[md5sum] = "0634e7f40591bd3f6770e583c3f27d29"
diff --git a/meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch b/meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch
new file mode 100644
index 0000000000..6417d8a2b7
--- /dev/null
+++ b/meta-oe/recipes-dbs/postgresql/files/CVE-2022-2625.patch
@@ -0,0 +1,904 @@
+From 84375c1db25ef650902cf80712495fc514b0ff63 Mon Sep 17 00:00:00 2001
+From: Hitendra Prajapati <hprajapati@mvista.com>
+Date: Thu, 13 Oct 2022 10:35:32 +0530
+Subject: [PATCH] CVE-2022-2625
+
+Upstream-Status: Backport [https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5579726bd60a6e7afb04a3548bced348cd5ffd89]
+CVE: CVE-2022-2625
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ doc/src/sgml/extend.sgml | 11 --
+ src/backend/catalog/pg_collation.c | 49 ++++--
+ src/backend/catalog/pg_depend.c | 74 ++++++++-
+ src/backend/catalog/pg_operator.c | 2 +-
+ src/backend/catalog/pg_type.c | 7 +-
+ src/backend/commands/createas.c | 18 ++-
+ src/backend/commands/foreigncmds.c | 19 ++-
+ src/backend/commands/schemacmds.c | 25 ++-
+ src/backend/commands/sequence.c | 8 +
+ src/backend/commands/statscmds.c | 4 +
+ src/backend/commands/view.c | 16 +-
+ src/backend/parser/parse_utilcmd.c | 10 ++
+ src/include/catalog/dependency.h | 2 +
+ src/test/modules/test_extensions/Makefile | 5 +-
+ .../expected/test_extensions.out | 153 ++++++++++++++++++
+ .../test_extensions/sql/test_extensions.sql | 110 +++++++++++++
+ .../test_ext_cine--1.0--1.1.sql | 26 +++
+ .../test_extensions/test_ext_cine--1.0.sql | 25 +++
+ .../test_extensions/test_ext_cine.control | 3 +
+ .../test_extensions/test_ext_cor--1.0.sql | 20 +++
+ .../test_extensions/test_ext_cor.control | 3 +
+ 21 files changed, 540 insertions(+), 50 deletions(-)
+ create mode 100644 src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql
+ create mode 100644 src/test/modules/test_extensions/test_ext_cine--1.0.sql
+ create mode 100644 src/test/modules/test_extensions/test_ext_cine.control
+ create mode 100644 src/test/modules/test_extensions/test_ext_cor--1.0.sql
+ create mode 100644 src/test/modules/test_extensions/test_ext_cor.control
+
+diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
+index 53f2638..bcc7a80 100644
+--- a/doc/src/sgml/extend.sgml
++++ b/doc/src/sgml/extend.sgml
+@@ -1109,17 +1109,6 @@ SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</replaceabl
+ <varname>search_path</varname>. However, no mechanism currently exists
+ to require that.
+ </para>
+-
+- <para>
+- Do <emphasis>not</emphasis> use <command>CREATE OR REPLACE
+- FUNCTION</command>, except in an update script that must change the
+- definition of a function that is known to be an extension member
+- already. (Likewise for other <literal>OR REPLACE</literal> options.)
+- Using <literal>OR REPLACE</literal> unnecessarily not only has a risk
+- of accidentally overwriting someone else's function, but it creates a
+- security hazard since the overwritten function would still be owned by
+- its original owner, who could modify it.
+- </para>
+ </sect3>
+ </sect2>
+
+diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
+index dd99d53..ba4c3ef 100644
+--- a/src/backend/catalog/pg_collation.c
++++ b/src/backend/catalog/pg_collation.c
+@@ -78,15 +78,25 @@ CollationCreate(const char *collname, Oid collnamespace,
+ * friendlier error message. The unique index provides a backstop against
+ * race conditions.
+ */
+- if (SearchSysCacheExists3(COLLNAMEENCNSP,
+- PointerGetDatum(collname),
+- Int32GetDatum(collencoding),
+- ObjectIdGetDatum(collnamespace)))
++ oid = GetSysCacheOid3(COLLNAMEENCNSP,
++ Anum_pg_collation_oid,
++ PointerGetDatum(collname),
++ Int32GetDatum(collencoding),
++ ObjectIdGetDatum(collnamespace));
++ if (OidIsValid(oid))
+ {
+ if (quiet)
+ return InvalidOid;
+ else if (if_not_exists)
+ {
++ /*
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddressSet(myself, CollationRelationId, oid);
++ checkMembershipInCurrentExtension(&myself);
++
++ /* OK to skip */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ collencoding == -1
+@@ -116,16 +126,19 @@ CollationCreate(const char *collname, Oid collnamespace,
+ * so we take a ShareRowExclusiveLock earlier, to protect against
+ * concurrent changes fooling this check.
+ */
+- if ((collencoding == -1 &&
+- SearchSysCacheExists3(COLLNAMEENCNSP,
+- PointerGetDatum(collname),
+- Int32GetDatum(GetDatabaseEncoding()),
+- ObjectIdGetDatum(collnamespace))) ||
+- (collencoding != -1 &&
+- SearchSysCacheExists3(COLLNAMEENCNSP,
+- PointerGetDatum(collname),
+- Int32GetDatum(-1),
+- ObjectIdGetDatum(collnamespace))))
++ if (collencoding == -1)
++ oid = GetSysCacheOid3(COLLNAMEENCNSP,
++ Anum_pg_collation_oid,
++ PointerGetDatum(collname),
++ Int32GetDatum(GetDatabaseEncoding()),
++ ObjectIdGetDatum(collnamespace));
++ else
++ oid = GetSysCacheOid3(COLLNAMEENCNSP,
++ Anum_pg_collation_oid,
++ PointerGetDatum(collname),
++ Int32GetDatum(-1),
++ ObjectIdGetDatum(collnamespace));
++ if (OidIsValid(oid))
+ {
+ if (quiet)
+ {
+@@ -134,6 +147,14 @@ CollationCreate(const char *collname, Oid collnamespace,
+ }
+ else if (if_not_exists)
+ {
++ /*
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddressSet(myself, CollationRelationId, oid);
++ checkMembershipInCurrentExtension(&myself);
++
++ /* OK to skip */
+ table_close(rel, NoLock);
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
+index 9ffadbb..71c7cef 100644
+--- a/src/backend/catalog/pg_depend.c
++++ b/src/backend/catalog/pg_depend.c
+@@ -124,15 +124,23 @@ recordMultipleDependencies(const ObjectAddress *depender,
+
+ /*
+ * If we are executing a CREATE EXTENSION operation, mark the given object
+- * as being a member of the extension. Otherwise, do nothing.
++ * as being a member of the extension, or check that it already is one.
++ * Otherwise, do nothing.
+ *
+ * This must be called during creation of any user-definable object type
+ * that could be a member of an extension.
+ *
+- * If isReplace is true, the object already existed (or might have already
+- * existed), so we must check for a pre-existing extension membership entry.
+- * Passing false is a guarantee that the object is newly created, and so
+- * could not already be a member of any extension.
++ * isReplace must be true if the object already existed, and false if it is
++ * newly created. In the former case we insist that it already be a member
++ * of the current extension. In the latter case we can skip checking whether
++ * it is already a member of any extension.
++ *
++ * Note: isReplace = true is typically used when updating a object in
++ * CREATE OR REPLACE and similar commands. We used to allow the target
++ * object to not already be an extension member, instead silently absorbing
++ * it into the current extension. However, this was both error-prone
++ * (extensions might accidentally overwrite free-standing objects) and
++ * a security hazard (since the object would retain its previous ownership).
+ */
+ void
+ recordDependencyOnCurrentExtension(const ObjectAddress *object,
+@@ -150,6 +158,12 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object,
+ {
+ Oid oldext;
+
++ /*
++ * Side note: these catalog lookups are safe only because the
++ * object is a pre-existing one. In the not-isReplace case, the
++ * caller has most likely not yet done a CommandCounterIncrement
++ * that would make the new object visible.
++ */
+ oldext = getExtensionOfObject(object->classId, object->objectId);
+ if (OidIsValid(oldext))
+ {
+@@ -163,6 +177,13 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object,
+ getObjectDescription(object),
+ get_extension_name(oldext))));
+ }
++ /* It's a free-standing object, so reject */
++ ereport(ERROR,
++ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
++ errmsg("%s is not a member of extension \"%s\"",
++ getObjectDescription(object),
++ get_extension_name(CurrentExtensionObject)),
++ errdetail("An extension is not allowed to replace an object that it does not own.")));
+ }
+
+ /* OK, record it as a member of CurrentExtensionObject */
+@@ -174,6 +195,49 @@ recordDependencyOnCurrentExtension(const ObjectAddress *object,
+ }
+ }
+
++/*
++ * If we are executing a CREATE EXTENSION operation, check that the given
++ * object is a member of the extension, and throw an error if it isn't.
++ * Otherwise, do nothing.
++ *
++ * This must be called whenever a CREATE IF NOT EXISTS operation (for an
++ * object type that can be an extension member) has found that an object of
++ * the desired name already exists. It is insecure for an extension to use
++ * IF NOT EXISTS except when the conflicting object is already an extension
++ * member; otherwise a hostile user could substitute an object with arbitrary
++ * properties.
++ */
++void
++checkMembershipInCurrentExtension(const ObjectAddress *object)
++{
++ /*
++ * This is actually the same condition tested in
++ * recordDependencyOnCurrentExtension; but we want to issue a
++ * differently-worded error, and anyway it would be pretty confusing to
++ * call recordDependencyOnCurrentExtension in these circumstances.
++ */
++
++ /* Only whole objects can be extension members */
++ Assert(object->objectSubId == 0);
++
++ if (creating_extension)
++ {
++ Oid oldext;
++
++ oldext = getExtensionOfObject(object->classId, object->objectId);
++ /* If already a member of this extension, OK */
++ if (oldext == CurrentExtensionObject)
++ return;
++ /* Else complain */
++ ereport(ERROR,
++ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
++ errmsg("%s is not a member of extension \"%s\"",
++ getObjectDescription(object),
++ get_extension_name(CurrentExtensionObject)),
++ errdetail("An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.")));
++ }
++}
++
+ /*
+ * deleteDependencyRecordsFor -- delete all records with given depender
+ * classId/objectId. Returns the number of records deleted.
+diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
+index bcaa26c..84784e6 100644
+--- a/src/backend/catalog/pg_operator.c
++++ b/src/backend/catalog/pg_operator.c
+@@ -867,7 +867,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate)
+ oper->oprowner);
+
+ /* Dependency on extension */
+- recordDependencyOnCurrentExtension(&myself, true);
++ recordDependencyOnCurrentExtension(&myself, isUpdate);
+
+ return myself;
+ }
+diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
+index 2a51501..3ff017f 100644
+--- a/src/backend/catalog/pg_type.c
++++ b/src/backend/catalog/pg_type.c
+@@ -528,10 +528,9 @@ TypeCreate(Oid newTypeOid,
+ * If rebuild is true, we remove existing dependencies and rebuild them
+ * from scratch. This is needed for ALTER TYPE, and also when replacing
+ * a shell type. We don't remove an existing extension dependency, though.
+- * (That means an extension can't absorb a shell type created in another
+- * extension, nor ALTER a type created by another extension. Also, if it
+- * replaces a free-standing shell type or ALTERs a free-standing type,
+- * that type will become a member of the extension.)
++ * That means an extension can't absorb a shell type that is free-standing
++ * or belongs to another extension, nor ALTER a type that is free-standing or
++ * belongs to another extension.
+ */
+ void
+ GenerateTypeDependencies(Oid typeObjectId,
+diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
+index 4c1d909..a68d945 100644
+--- a/src/backend/commands/createas.c
++++ b/src/backend/commands/createas.c
+@@ -243,15 +243,27 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
+ if (stmt->if_not_exists)
+ {
+ Oid nspid;
++ Oid oldrelid;
+
+- nspid = RangeVarGetCreationNamespace(stmt->into->rel);
++ nspid = RangeVarGetCreationNamespace(into->rel);
+
+- if (get_relname_relid(stmt->into->rel->relname, nspid))
++ oldrelid = get_relname_relid(into->rel->relname, nspid);
++ if (OidIsValid(oldrelid))
+ {
++ /*
++ * The relation exists and IF NOT EXISTS has been specified.
++ *
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddressSet(address, RelationRelationId, oldrelid);
++ checkMembershipInCurrentExtension(&address);
++
++ /* OK to skip */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_TABLE),
+ errmsg("relation \"%s\" already exists, skipping",
+- stmt->into->rel->relname)));
++ into->rel->relname)));
+ return InvalidObjectAddress;
+ }
+ }
+diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
+index d7bc6e3..bc583c6 100644
+--- a/src/backend/commands/foreigncmds.c
++++ b/src/backend/commands/foreigncmds.c
+@@ -887,13 +887,22 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
+ ownerId = GetUserId();
+
+ /*
+- * Check that there is no other foreign server by this name. Do nothing if
+- * IF NOT EXISTS was enforced.
++ * Check that there is no other foreign server by this name. If there is
++ * one, do nothing if IF NOT EXISTS was specified.
+ */
+- if (GetForeignServerByName(stmt->servername, true) != NULL)
++ srvId = get_foreign_server_oid(stmt->servername, true);
++ if (OidIsValid(srvId))
+ {
+ if (stmt->if_not_exists)
+ {
++ /*
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddressSet(myself, ForeignServerRelationId, srvId);
++ checkMembershipInCurrentExtension(&myself);
++
++ /* OK to skip */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("server \"%s\" already exists, skipping",
+@@ -1182,6 +1191,10 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
+ {
+ if (stmt->if_not_exists)
+ {
++ /*
++ * Since user mappings aren't members of extensions (see comments
++ * below), no need for checkMembershipInCurrentExtension here.
++ */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("user mapping for \"%s\" already exists for server \"%s\", skipping",
+diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
+index 6cf94a3..6bc4edc 100644
+--- a/src/backend/commands/schemacmds.c
++++ b/src/backend/commands/schemacmds.c
+@@ -113,14 +113,25 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString,
+ * the permissions checks, but since CREATE TABLE IF NOT EXISTS makes its
+ * creation-permission check first, we do likewise.
+ */
+- if (stmt->if_not_exists &&
+- SearchSysCacheExists1(NAMESPACENAME, PointerGetDatum(schemaName)))
++ if (stmt->if_not_exists)
+ {
+- ereport(NOTICE,
+- (errcode(ERRCODE_DUPLICATE_SCHEMA),
+- errmsg("schema \"%s\" already exists, skipping",
+- schemaName)));
+- return InvalidOid;
++ namespaceId = get_namespace_oid(schemaName, true);
++ if (OidIsValid(namespaceId))
++ {
++ /*
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddressSet(address, NamespaceRelationId, namespaceId);
++ checkMembershipInCurrentExtension(&address);
++
++ /* OK to skip */
++ ereport(NOTICE,
++ (errcode(ERRCODE_DUPLICATE_SCHEMA),
++ errmsg("schema \"%s\" already exists, skipping",
++ schemaName)));
++ return InvalidOid;
++ }
+ }
+
+ /*
+diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
+index 0960b33..0577184 100644
+--- a/src/backend/commands/sequence.c
++++ b/src/backend/commands/sequence.c
+@@ -149,6 +149,14 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
+ RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &seqoid);
+ if (OidIsValid(seqoid))
+ {
++ /*
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddressSet(address, RelationRelationId, seqoid);
++ checkMembershipInCurrentExtension(&address);
++
++ /* OK to skip */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_TABLE),
+ errmsg("relation \"%s\" already exists, skipping",
+diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
+index 5678d31..409cf28 100644
+--- a/src/backend/commands/statscmds.c
++++ b/src/backend/commands/statscmds.c
+@@ -173,6 +173,10 @@ CreateStatistics(CreateStatsStmt *stmt)
+ {
+ if (stmt->if_not_exists)
+ {
++ /*
++ * Since stats objects aren't members of extensions (see comments
++ * below), no need for checkMembershipInCurrentExtension here.
++ */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("statistics object \"%s\" already exists, skipping",
+diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
+index 87ed453..dd7cc97 100644
+--- a/src/backend/commands/view.c
++++ b/src/backend/commands/view.c
+@@ -205,7 +205,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
+ CommandCounterIncrement();
+
+ /*
+- * Finally update the view options.
++ * Update the view's options.
+ *
+ * The new options list replaces the existing options list, even if
+ * it's empty.
+@@ -218,8 +218,22 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
+ /* EventTriggerAlterTableStart called by ProcessUtilitySlow */
+ AlterTableInternal(viewOid, atcmds, true);
+
++ /*
++ * There is very little to do here to update the view's dependencies.
++ * Most view-level dependency relationships, such as those on the
++ * owner, schema, and associated composite type, aren't changing.
++ * Because we don't allow changing type or collation of an existing
++ * view column, those dependencies of the existing columns don't
++ * change either, while the AT_AddColumnToView machinery took care of
++ * adding such dependencies for new view columns. The dependencies of
++ * the view's query could have changed arbitrarily, but that was dealt
++ * with inside StoreViewQuery. What remains is only to check that
++ * view replacement is allowed when we're creating an extension.
++ */
+ ObjectAddressSet(address, RelationRelationId, viewOid);
+
++ recordDependencyOnCurrentExtension(&address, true);
++
+ /*
+ * Seems okay, so return the OID of the pre-existing view.
+ */
+diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
+index 44aa38a..8f4d940 100644
+--- a/src/backend/parser/parse_utilcmd.c
++++ b/src/backend/parser/parse_utilcmd.c
+@@ -206,6 +206,16 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
+ */
+ if (stmt->if_not_exists && OidIsValid(existing_relid))
+ {
++ /*
++ * If we are in an extension script, insist that the pre-existing
++ * object be a member of the extension, to avoid security risks.
++ */
++ ObjectAddress address;
++
++ ObjectAddressSet(address, RelationRelationId, existing_relid);
++ checkMembershipInCurrentExtension(&address);
++
++ /* OK to skip */
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_TABLE),
+ errmsg("relation \"%s\" already exists, skipping",
+diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
+index 8b1e3aa..27c7509 100644
+--- a/src/include/catalog/dependency.h
++++ b/src/include/catalog/dependency.h
+@@ -201,6 +201,8 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
+ extern void recordDependencyOnCurrentExtension(const ObjectAddress *object,
+ bool isReplace);
+
++extern void checkMembershipInCurrentExtension(const ObjectAddress *object);
++
+ extern long deleteDependencyRecordsFor(Oid classId, Oid objectId,
+ bool skipExtensionDeps);
+
+diff --git a/src/test/modules/test_extensions/Makefile b/src/test/modules/test_extensions/Makefile
+index d18108e..7428f15 100644
+--- a/src/test/modules/test_extensions/Makefile
++++ b/src/test/modules/test_extensions/Makefile
+@@ -4,10 +4,13 @@ MODULE = test_extensions
+ PGFILEDESC = "test_extensions - regression testing for EXTENSION support"
+
+ EXTENSION = test_ext1 test_ext2 test_ext3 test_ext4 test_ext5 test_ext6 \
+- test_ext7 test_ext8 test_ext_cyclic1 test_ext_cyclic2
++ test_ext7 test_ext8 test_ext_cine test_ext_cor \
++ test_ext_cyclic1 test_ext_cyclic2
+ DATA = test_ext1--1.0.sql test_ext2--1.0.sql test_ext3--1.0.sql \
+ test_ext4--1.0.sql test_ext5--1.0.sql test_ext6--1.0.sql \
+ test_ext7--1.0.sql test_ext7--1.0--2.0.sql test_ext8--1.0.sql \
++ test_ext_cine--1.0.sql test_ext_cine--1.0--1.1.sql \
++ test_ext_cor--1.0.sql \
+ test_ext_cyclic1--1.0.sql test_ext_cyclic2--1.0.sql
+
+ REGRESS = test_extensions test_extdepend
+diff --git a/src/test/modules/test_extensions/expected/test_extensions.out b/src/test/modules/test_extensions/expected/test_extensions.out
+index b5cbdfc..1e91640 100644
+--- a/src/test/modules/test_extensions/expected/test_extensions.out
++++ b/src/test/modules/test_extensions/expected/test_extensions.out
+@@ -154,3 +154,156 @@ DROP TABLE test_ext4_tab;
+ DROP FUNCTION create_extension_with_temp_schema();
+ RESET client_min_messages;
+ \unset SHOW_CONTEXT
++-- It's generally bad style to use CREATE OR REPLACE unnecessarily.
++-- Test what happens if an extension does it anyway.
++-- Replacing a shell type or operator is sort of like CREATE OR REPLACE;
++-- check that too.
++CREATE FUNCTION ext_cor_func() RETURNS text
++ AS $$ SELECT 'ext_cor_func: original'::text $$ LANGUAGE sql;
++CREATE EXTENSION test_ext_cor; -- fail
++ERROR: function ext_cor_func() is not a member of extension "test_ext_cor"
++DETAIL: An extension is not allowed to replace an object that it does not own.
++SELECT ext_cor_func();
++ ext_cor_func
++------------------------
++ ext_cor_func: original
++(1 row)
++
++DROP FUNCTION ext_cor_func();
++CREATE VIEW ext_cor_view AS
++ SELECT 'ext_cor_view: original'::text AS col;
++CREATE EXTENSION test_ext_cor; -- fail
++ERROR: view ext_cor_view is not a member of extension "test_ext_cor"
++DETAIL: An extension is not allowed to replace an object that it does not own.
++SELECT ext_cor_func();
++ERROR: function ext_cor_func() does not exist
++LINE 1: SELECT ext_cor_func();
++ ^
++HINT: No function matches the given name and argument types. You might need to add explicit type casts.
++SELECT * FROM ext_cor_view;
++ col
++------------------------
++ ext_cor_view: original
++(1 row)
++
++DROP VIEW ext_cor_view;
++CREATE TYPE test_ext_type;
++CREATE EXTENSION test_ext_cor; -- fail
++ERROR: type test_ext_type is not a member of extension "test_ext_cor"
++DETAIL: An extension is not allowed to replace an object that it does not own.
++DROP TYPE test_ext_type;
++-- this makes a shell "point <<@@ polygon" operator too
++CREATE OPERATOR @@>> ( PROCEDURE = poly_contain_pt,
++ LEFTARG = polygon, RIGHTARG = point,
++ COMMUTATOR = <<@@ );
++CREATE EXTENSION test_ext_cor; -- fail
++ERROR: operator <<@@(point,polygon) is not a member of extension "test_ext_cor"
++DETAIL: An extension is not allowed to replace an object that it does not own.
++DROP OPERATOR <<@@ (point, polygon);
++CREATE EXTENSION test_ext_cor; -- now it should work
++SELECT ext_cor_func();
++ ext_cor_func
++------------------------------
++ ext_cor_func: from extension
++(1 row)
++
++SELECT * FROM ext_cor_view;
++ col
++------------------------------
++ ext_cor_view: from extension
++(1 row)
++
++SELECT 'x'::test_ext_type;
++ test_ext_type
++---------------
++ x
++(1 row)
++
++SELECT point(0,0) <<@@ polygon(circle(point(0,0),1));
++ ?column?
++----------
++ t
++(1 row)
++
++\dx+ test_ext_cor
++Objects in extension "test_ext_cor"
++ Object description
++------------------------------
++ function ext_cor_func()
++ operator <<@@(point,polygon)
++ type test_ext_type
++ view ext_cor_view
++(4 rows)
++
++--
++-- CREATE IF NOT EXISTS is an entirely unsound thing for an extension
++-- to be doing, but let's at least plug the major security hole in it.
++--
++CREATE COLLATION ext_cine_coll
++ ( LC_COLLATE = "C", LC_CTYPE = "C" );
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: collation ext_cine_coll is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP COLLATION ext_cine_coll;
++CREATE MATERIALIZED VIEW ext_cine_mv AS SELECT 11 AS f1;
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: materialized view ext_cine_mv is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP MATERIALIZED VIEW ext_cine_mv;
++CREATE FOREIGN DATA WRAPPER dummy;
++CREATE SERVER ext_cine_srv FOREIGN DATA WRAPPER dummy;
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: server ext_cine_srv is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP SERVER ext_cine_srv;
++CREATE SCHEMA ext_cine_schema;
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: schema ext_cine_schema is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP SCHEMA ext_cine_schema;
++CREATE SEQUENCE ext_cine_seq;
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: sequence ext_cine_seq is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP SEQUENCE ext_cine_seq;
++CREATE TABLE ext_cine_tab1 (x int);
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: table ext_cine_tab1 is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP TABLE ext_cine_tab1;
++CREATE TABLE ext_cine_tab2 AS SELECT 42 AS y;
++CREATE EXTENSION test_ext_cine; -- fail
++ERROR: table ext_cine_tab2 is not a member of extension "test_ext_cine"
++DETAIL: An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.
++DROP TABLE ext_cine_tab2;
++CREATE EXTENSION test_ext_cine;
++\dx+ test_ext_cine
++Objects in extension "test_ext_cine"
++ Object description
++-----------------------------------
++ collation ext_cine_coll
++ foreign-data wrapper ext_cine_fdw
++ materialized view ext_cine_mv
++ schema ext_cine_schema
++ sequence ext_cine_seq
++ server ext_cine_srv
++ table ext_cine_tab1
++ table ext_cine_tab2
++(8 rows)
++
++ALTER EXTENSION test_ext_cine UPDATE TO '1.1';
++\dx+ test_ext_cine
++Objects in extension "test_ext_cine"
++ Object description
++-----------------------------------
++ collation ext_cine_coll
++ foreign-data wrapper ext_cine_fdw
++ materialized view ext_cine_mv
++ schema ext_cine_schema
++ sequence ext_cine_seq
++ server ext_cine_srv
++ table ext_cine_tab1
++ table ext_cine_tab2
++ table ext_cine_tab3
++(9 rows)
++
+diff --git a/src/test/modules/test_extensions/sql/test_extensions.sql b/src/test/modules/test_extensions/sql/test_extensions.sql
+index f505466..b3d4579 100644
+--- a/src/test/modules/test_extensions/sql/test_extensions.sql
++++ b/src/test/modules/test_extensions/sql/test_extensions.sql
+@@ -93,3 +93,113 @@ DROP TABLE test_ext4_tab;
+ DROP FUNCTION create_extension_with_temp_schema();
+ RESET client_min_messages;
+ \unset SHOW_CONTEXT
++
++-- It's generally bad style to use CREATE OR REPLACE unnecessarily.
++-- Test what happens if an extension does it anyway.
++-- Replacing a shell type or operator is sort of like CREATE OR REPLACE;
++-- check that too.
++
++CREATE FUNCTION ext_cor_func() RETURNS text
++ AS $$ SELECT 'ext_cor_func: original'::text $$ LANGUAGE sql;
++
++CREATE EXTENSION test_ext_cor; -- fail
++
++SELECT ext_cor_func();
++
++DROP FUNCTION ext_cor_func();
++
++CREATE VIEW ext_cor_view AS
++ SELECT 'ext_cor_view: original'::text AS col;
++
++CREATE EXTENSION test_ext_cor; -- fail
++
++SELECT ext_cor_func();
++
++SELECT * FROM ext_cor_view;
++
++DROP VIEW ext_cor_view;
++
++CREATE TYPE test_ext_type;
++
++CREATE EXTENSION test_ext_cor; -- fail
++
++DROP TYPE test_ext_type;
++
++-- this makes a shell "point <<@@ polygon" operator too
++CREATE OPERATOR @@>> ( PROCEDURE = poly_contain_pt,
++ LEFTARG = polygon, RIGHTARG = point,
++ COMMUTATOR = <<@@ );
++
++CREATE EXTENSION test_ext_cor; -- fail
++
++DROP OPERATOR <<@@ (point, polygon);
++
++CREATE EXTENSION test_ext_cor; -- now it should work
++
++SELECT ext_cor_func();
++
++SELECT * FROM ext_cor_view;
++
++SELECT 'x'::test_ext_type;
++
++SELECT point(0,0) <<@@ polygon(circle(point(0,0),1));
++
++\dx+ test_ext_cor
++
++--
++-- CREATE IF NOT EXISTS is an entirely unsound thing for an extension
++-- to be doing, but let's at least plug the major security hole in it.
++--
++
++CREATE COLLATION ext_cine_coll
++ ( LC_COLLATE = "C", LC_CTYPE = "C" );
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP COLLATION ext_cine_coll;
++
++CREATE MATERIALIZED VIEW ext_cine_mv AS SELECT 11 AS f1;
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP MATERIALIZED VIEW ext_cine_mv;
++
++CREATE FOREIGN DATA WRAPPER dummy;
++
++CREATE SERVER ext_cine_srv FOREIGN DATA WRAPPER dummy;
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP SERVER ext_cine_srv;
++
++CREATE SCHEMA ext_cine_schema;
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP SCHEMA ext_cine_schema;
++
++CREATE SEQUENCE ext_cine_seq;
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP SEQUENCE ext_cine_seq;
++
++CREATE TABLE ext_cine_tab1 (x int);
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP TABLE ext_cine_tab1;
++
++CREATE TABLE ext_cine_tab2 AS SELECT 42 AS y;
++
++CREATE EXTENSION test_ext_cine; -- fail
++
++DROP TABLE ext_cine_tab2;
++
++CREATE EXTENSION test_ext_cine;
++
++\dx+ test_ext_cine
++
++ALTER EXTENSION test_ext_cine UPDATE TO '1.1';
++
++\dx+ test_ext_cine
+diff --git a/src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql b/src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql
+new file mode 100644
+index 0000000..6dadfd2
+--- /dev/null
++++ b/src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql
+@@ -0,0 +1,26 @@
++/* src/test/modules/test_extensions/test_ext_cine--1.0--1.1.sql */
++-- complain if script is sourced in psql, rather than via ALTER EXTENSION
++\echo Use "ALTER EXTENSION test_ext_cine UPDATE TO '1.1'" to load this file. \quit
++
++--
++-- These are the same commands as in the 1.0 script; we expect them
++-- to do nothing.
++--
++
++CREATE COLLATION IF NOT EXISTS ext_cine_coll
++ ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
++
++CREATE MATERIALIZED VIEW IF NOT EXISTS ext_cine_mv AS SELECT 42 AS f1;
++
++CREATE SERVER IF NOT EXISTS ext_cine_srv FOREIGN DATA WRAPPER ext_cine_fdw;
++
++CREATE SCHEMA IF NOT EXISTS ext_cine_schema;
++
++CREATE SEQUENCE IF NOT EXISTS ext_cine_seq;
++
++CREATE TABLE IF NOT EXISTS ext_cine_tab1 (x int);
++
++CREATE TABLE IF NOT EXISTS ext_cine_tab2 AS SELECT 42 AS y;
++
++-- just to verify the script ran
++CREATE TABLE ext_cine_tab3 (z int);
+diff --git a/src/test/modules/test_extensions/test_ext_cine--1.0.sql b/src/test/modules/test_extensions/test_ext_cine--1.0.sql
+new file mode 100644
+index 0000000..01408ff
+--- /dev/null
++++ b/src/test/modules/test_extensions/test_ext_cine--1.0.sql
+@@ -0,0 +1,25 @@
++/* src/test/modules/test_extensions/test_ext_cine--1.0.sql */
++-- complain if script is sourced in psql, rather than via CREATE EXTENSION
++\echo Use "CREATE EXTENSION test_ext_cine" to load this file. \quit
++
++--
++-- CREATE IF NOT EXISTS is an entirely unsound thing for an extension
++-- to be doing, but let's at least plug the major security hole in it.
++--
++
++CREATE COLLATION IF NOT EXISTS ext_cine_coll
++ ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
++
++CREATE MATERIALIZED VIEW IF NOT EXISTS ext_cine_mv AS SELECT 42 AS f1;
++
++CREATE FOREIGN DATA WRAPPER ext_cine_fdw;
++
++CREATE SERVER IF NOT EXISTS ext_cine_srv FOREIGN DATA WRAPPER ext_cine_fdw;
++
++CREATE SCHEMA IF NOT EXISTS ext_cine_schema;
++
++CREATE SEQUENCE IF NOT EXISTS ext_cine_seq;
++
++CREATE TABLE IF NOT EXISTS ext_cine_tab1 (x int);
++
++CREATE TABLE IF NOT EXISTS ext_cine_tab2 AS SELECT 42 AS y;
+diff --git a/src/test/modules/test_extensions/test_ext_cine.control b/src/test/modules/test_extensions/test_ext_cine.control
+new file mode 100644
+index 0000000..ced713b
+--- /dev/null
++++ b/src/test/modules/test_extensions/test_ext_cine.control
+@@ -0,0 +1,3 @@
++comment = 'Test extension using CREATE IF NOT EXISTS'
++default_version = '1.0'
++relocatable = true
+diff --git a/src/test/modules/test_extensions/test_ext_cor--1.0.sql b/src/test/modules/test_extensions/test_ext_cor--1.0.sql
+new file mode 100644
+index 0000000..2e8d89c
+--- /dev/null
++++ b/src/test/modules/test_extensions/test_ext_cor--1.0.sql
+@@ -0,0 +1,20 @@
++/* src/test/modules/test_extensions/test_ext_cor--1.0.sql */
++-- complain if script is sourced in psql, rather than via CREATE EXTENSION
++\echo Use "CREATE EXTENSION test_ext_cor" to load this file. \quit
++
++-- It's generally bad style to use CREATE OR REPLACE unnecessarily.
++-- Test what happens if an extension does it anyway.
++
++CREATE OR REPLACE FUNCTION ext_cor_func() RETURNS text
++ AS $$ SELECT 'ext_cor_func: from extension'::text $$ LANGUAGE sql;
++
++CREATE OR REPLACE VIEW ext_cor_view AS
++ SELECT 'ext_cor_view: from extension'::text AS col;
++
++-- These are for testing replacement of a shell type/operator, which works
++-- enough like an implicit OR REPLACE to be important to check.
++
++CREATE TYPE test_ext_type AS ENUM('x', 'y');
++
++CREATE OPERATOR <<@@ ( PROCEDURE = pt_contained_poly,
++ LEFTARG = point, RIGHTARG = polygon );
+diff --git a/src/test/modules/test_extensions/test_ext_cor.control b/src/test/modules/test_extensions/test_ext_cor.control
+new file mode 100644
+index 0000000..0e972e5
+--- /dev/null
++++ b/src/test/modules/test_extensions/test_ext_cor.control
+@@ -0,0 +1,3 @@
++comment = 'Test extension using CREATE OR REPLACE'
++default_version = '1.0'
++relocatable = true
+--
+2.25.1
+
diff --git a/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb b/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb
index 1344d4eb00..860e821b20 100644
--- a/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb
+++ b/meta-oe/recipes-dbs/postgresql/postgresql_12.9.bb
@@ -8,6 +8,7 @@ SRC_URI += "\
file://0001-Improve-reproducibility.patch \
file://remove_duplicate.patch \
file://CVE-2022-1552.patch \
+ file://CVE-2022-2625.patch \
"
SRC_URI[sha256sum] = "89fda2de33ed04a98548e43f3ee5f15b882be17505d631fe0dd1a540a2b56dce"
diff --git a/meta-oe/recipes-devtools/flatbuffers/flatbuffers_1.12.0.bb b/meta-oe/recipes-devtools/flatbuffers/flatbuffers_1.12.0.bb
index 859d6a0b05..c4f3594f36 100644
--- a/meta-oe/recipes-devtools/flatbuffers/flatbuffers_1.12.0.bb
+++ b/meta-oe/recipes-devtools/flatbuffers/flatbuffers_1.12.0.bb
@@ -24,12 +24,17 @@ BUILD_CXXFLAGS += "-std=c++11 -fPIC"
# BUILD_TYPE=Release is required, otherwise flatc is not installed
EXTRA_OECMAKE += "\
-DCMAKE_BUILD_TYPE=Release \
- -DFLATBUFFERS_BUILD_TESTS=OFF \
+ -DFLATBUFFERS_BUILD_TESTS=OFF \
-DFLATBUFFERS_BUILD_SHAREDLIB=ON \
"
inherit cmake
+rm_flatc_cmaketarget_for_target() {
+ rm -f "${SYSROOT_DESTDIR}/${libdir}/cmake/flatbuffers/FlatcTargets.cmake"
+}
+SYSROOT_PREPROCESS_FUNCS:class-target += "rm_flatc_cmaketarget_for_target"
+
S = "${WORKDIR}/git"
FILES_${PN}-compiler = "${bindir}"
diff --git a/meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch b/meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch
new file mode 100644
index 0000000000..8a8a35b2dd
--- /dev/null
+++ b/meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch
@@ -0,0 +1,319 @@
+From 9563a2a08c007d78a6796b0232201bf7dc4a8103 Mon Sep 17 00:00:00 2001
+From: Hitendra Prajapati <hprajapati@mvista.com>
+Date: Wed, 16 Nov 2022 10:28:24 +0530
+Subject: [PATCH] CVE-2022-41741, CVE-2022-41742
+
+Upstream-Status: Backport [https://github.com/nginx/nginx/commit/6b022a5556af22b6e18532e547a6ae46b0d8c6ea]
+CVE: CVE-2022-41741, CVE-2022-41742
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+
+Mp4: disabled duplicate atoms.
+
+Most atoms should not appear more than once in a container. Previously,
+this was not enforced by the module, which could result in worker process
+crash, memory corruption and disclosure.
+---
+ src/http/modules/ngx_http_mp4_module.c | 147 +++++++++++++++++++++++++
+ 1 file changed, 147 insertions(+)
+
+diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
+index 618bf78..7b7184d 100644
+--- a/src/http/modules/ngx_http_mp4_module.c
++++ b/src/http/modules/ngx_http_mp4_module.c
+@@ -1076,6 +1076,12 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ return NGX_ERROR;
+ }
+
++ if (mp4->ftyp_atom.buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 ftyp atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
+
+ ftyp_atom = ngx_palloc(mp4->request->pool, atom_size);
+@@ -1134,6 +1140,12 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ return NGX_DECLINED;
+ }
+
++ if (mp4->moov_atom.buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 moov atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module);
+
+ if (atom_data_size > mp4->buffer_size) {
+@@ -1201,6 +1213,12 @@ ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom");
+
++ if (mp4->mdat_atom.buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 mdat atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ data = &mp4->mdat_data_buf;
+ data->file = &mp4->file;
+ data->in_file = 1;
+@@ -1327,6 +1345,12 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom");
+
++ if (mp4->mvhd_atom.buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 mvhd atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom_header = ngx_mp4_atom_header(mp4);
+ mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header;
+ mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header;
+@@ -1592,6 +1616,13 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 tkhd atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->tkhd_size = atom_size;
+
+ ngx_mp4_set_32value(tkhd_atom->size, atom_size);
+@@ -1630,6 +1661,12 @@ ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 mdia atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->mdia_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -1753,6 +1790,13 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 mdhd atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->mdhd_size = atom_size;
+ trak->timescale = timescale;
+
+@@ -1795,6 +1839,12 @@ ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 hdlr atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->hdlr_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -1823,6 +1873,12 @@ ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_MINF_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 minf atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->minf_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -1866,6 +1922,15 @@ ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf
++ || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf)
++ {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 vmhd/smhd atom in \"%s\"",
++ mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->vmhd_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -1897,6 +1962,15 @@ ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf
++ || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf)
++ {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 vmhd/smhd atom in \"%s\"",
++ mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->smhd_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -1928,6 +2002,12 @@ ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_DINF_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 dinf atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->dinf_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -1956,6 +2036,12 @@ ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_STBL_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stbl atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->stbl_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -2024,6 +2110,12 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+
+ trak = ngx_mp4_last_trak(mp4);
+
++ if (trak->out[NGX_HTTP_MP4_STSD_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stsd atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ atom = &trak->stsd_atom_buf;
+ atom->temporary = 1;
+ atom->pos = atom_header;
+@@ -2092,6 +2184,13 @@ ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_STTS_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stts atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->time_to_sample_entries = entries;
+
+ atom = &trak->stts_atom_buf;
+@@ -2297,6 +2396,13 @@ ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ "sync sample entries:%uD", entries);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_STSS_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stss atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->sync_samples_entries = entries;
+
+ atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t);
+@@ -2495,6 +2601,13 @@ ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ "composition offset entries:%uD", entries);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 ctts atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->composition_offset_entries = entries;
+
+ atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t);
+@@ -2698,6 +2811,13 @@ ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_STSC_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stsc atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->sample_to_chunk_entries = entries;
+
+ atom = &trak->stsc_atom_buf;
+@@ -3030,6 +3150,13 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ "sample uniform size:%uD, entries:%uD", size, entries);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf) {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stsz atom in \"%s\"", mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->sample_sizes_entries = entries;
+
+ atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t);
+@@ -3199,6 +3326,16 @@ ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ atom_end = atom_table + entries * sizeof(uint32_t);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf
++ || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf)
++ {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stco/co64 atom in \"%s\"",
++ mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->chunks = entries;
+
+ atom = &trak->stco_atom_buf;
+@@ -3383,6 +3520,16 @@ ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
+ atom_end = atom_table + entries * sizeof(uint64_t);
+
+ trak = ngx_mp4_last_trak(mp4);
++
++ if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf
++ || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf)
++ {
++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++ "duplicate mp4 stco/co64 atom in \"%s\"",
++ mp4->file.name.data);
++ return NGX_ERROR;
++ }
++
+ trak->chunks = entries;
+
+ atom = &trak->co64_atom_buf;
+--
+2.25.1
+
diff --git a/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb b/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb
index 09d58b8fb9..07e9f6ddbc 100644
--- a/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb
+++ b/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb
@@ -5,4 +5,6 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=52e384aaac868b755b93ad5535e2d075"
SRC_URI[md5sum] = "45a80f75336c980d240987badc3dcf60"
SRC_URI[sha256sum] = "f11c2a6dd1d3515736f0324857957db2de98be862461b5a542a3ac6188dbe32b"
-SRC_URI += "file://CVE-2019-20372.patch"
+SRC_URI += "file://CVE-2019-20372.patch \
+ file://CVE-2022-41741-CVE-2022-41742.patch \
+ "