Blame SOURCES/0005-nfct-remove-lazy-binding.patch

716360
From d18e2e7b13ce623da968e896c04813f9d3b8efbf Mon Sep 17 00:00:00 2001
716360
From: Pablo Neira Ayuso <pablo@netfilter.org>
716360
Date: Tue, 8 Mar 2022 23:05:39 +0100
716360
Subject: [PATCH] nfct: remove lazy binding
716360
716360
Since cd5135377ac4 ("conntrackd: cthelper: Set up userspace helpers when
716360
daemon starts"), userspace conntrack helpers do not depend on a previous
716360
invocation of nfct to set up the userspace helpers.
716360
716360
Move helper definitions to nfct-extensions/helper.c since existing
716360
deployments might still invoke nfct, even if not required anymore.
716360
716360
This patch was motivated by the removal of the lazy binding.
716360
716360
Phil Sutter says:
716360
716360
"For security purposes, distributions might want to pass -Wl,-z,now
716360
linker flags to all builds, thereby disabling lazy binding globally.
716360
716360
In the past, nfct relied upon lazy binding: It uses the helper objects'
716360
parsing functions without but doesn't provide all symbols the objects
716360
use."
716360
716360
Acked-by: Phil Sutter <phil@nwl.cc>
716360
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
716360
(cherry picked from commit dc454a657f57a5cf143fddc5c1dd87a510c1790a)
716360
(cherry picked from commit 4527e4fec140ff5480d4fbfb2916001d64a0f72a)
716360
---
716360
 configure.ac                 |   5 +-
716360
 include/Makefile.am          |   2 +-
716360
 include/helper.h             |   1 +
716360
 include/helpers/Makefile.am  |   1 +
716360
 include/helpers/ftp.h        |  14 +++
716360
 include/helpers/rpc.h        |  15 +++
716360
 include/helpers/sane.h       |  13 +++
716360
 include/helpers/tns.h        |   9 ++
716360
 src/Makefile.am              |   2 -
716360
 src/helpers.c                |   3 +-
716360
 src/helpers/Makefile.am      |   2 +-
716360
 src/helpers/ftp.c            |  12 +--
716360
 src/helpers/rpc.c            |  13 +--
716360
 src/helpers/sane.c           |  10 +-
716360
 src/helpers/tns.c            |   7 +-
716360
 src/nfct-extensions/helper.c | 184 ++++++++++++++++++++++++++++++++++-
716360
 16 files changed, 246 insertions(+), 47 deletions(-)
716360
 create mode 100644 include/helpers/Makefile.am
716360
 create mode 100644 include/helpers/ftp.h
716360
 create mode 100644 include/helpers/rpc.h
716360
 create mode 100644 include/helpers/sane.h
716360
 create mode 100644 include/helpers/tns.h
716360
716360
diff --git a/configure.ac b/configure.ac
716360
index 5388054e64a58..1e444508fdc3c 100644
716360
--- a/configure.ac
716360
+++ b/configure.ac
716360
@@ -78,15 +78,12 @@ AC_CHECK_HEADERS([linux/capability.h],, [AC_MSG_ERROR([Cannot find linux/capabib
716360
 AC_CHECK_HEADERS(arpa/inet.h)
716360
 AC_CHECK_FUNCS(inet_pton)
716360
 
716360
-# Let nfct use dlopen() on helper libraries without resolving all symbols.
716360
-AX_CHECK_LINK_FLAG([-Wl,-z,lazy], [AC_SUBST([LAZY_LDFLAGS], [-Wl,-z,lazy])])
716360
-
716360
 if test ! -z "$libdir"; then
716360
 	MODULE_DIR="\\\"$libdir/conntrack-tools/\\\""
716360
 	CFLAGS="$CFLAGS -DCONNTRACKD_LIB_DIR=$MODULE_DIR"
716360
 fi
716360
 
716360
-AC_CONFIG_FILES([Makefile src/Makefile include/Makefile include/linux/Makefile include/linux/netfilter/Makefile extensions/Makefile src/helpers/Makefile])
716360
+AC_CONFIG_FILES([Makefile src/Makefile include/Makefile include/helpers/Makefile include/linux/Makefile include/linux/netfilter/Makefile extensions/Makefile src/helpers/Makefile])
716360
 AC_OUTPUT
716360
 
716360
 echo "
716360
diff --git a/include/Makefile.am b/include/Makefile.am
716360
index 352054e9135bd..4741b50228eb9 100644
716360
--- a/include/Makefile.am
716360
+++ b/include/Makefile.am
716360
@@ -1,4 +1,4 @@
716360
-SUBDIRS = linux
716360
+SUBDIRS = linux helpers
716360
 
716360
 noinst_HEADERS = alarm.h jhash.h cache.h linux_list.h linux_rbtree.h \
716360
 		 sync.h conntrackd.h local.h udp.h tcp.h \
716360
diff --git a/include/helper.h b/include/helper.h
716360
index d15c1c62c0534..7353dfa9b2073 100644
716360
--- a/include/helper.h
716360
+++ b/include/helper.h
716360
@@ -56,6 +56,7 @@ extern int in4_pton(const char *src, int srclen, uint8_t *dst, int delim, const
716360
 extern int in6_pton(const char *src, int srclen, uint8_t *dst, int delim, const char **end);
716360
 
716360
 extern void helper_register(struct ctd_helper *helper);
716360
+struct ctd_helper *__helper_find(const char *helper_name, uint8_t l4proto);
716360
 struct ctd_helper *helper_find(const char *libdir_path, const char *name, uint8_t l4proto, int flags);
716360
 
716360
 #define min_t(type, x, y) ({			\
716360
diff --git a/include/helpers/Makefile.am b/include/helpers/Makefile.am
716360
new file mode 100644
716360
index 0000000000000..99a4257d2d061
716360
--- /dev/null
716360
+++ b/include/helpers/Makefile.am
716360
@@ -0,0 +1 @@
716360
+noinst_HEADERS = ftp.h  rpc.h  sane.h  tns.h
716360
diff --git a/include/helpers/ftp.h b/include/helpers/ftp.h
716360
new file mode 100644
716360
index 0000000000000..50e2d0c97946d
716360
--- /dev/null
716360
+++ b/include/helpers/ftp.h
716360
@@ -0,0 +1,14 @@
716360
+#ifndef _CTD_FTP_H
716360
+#define _CTD_FTP_H
716360
+
716360
+#define NUM_SEQ_TO_REMEMBER 2
716360
+
716360
+/* This structure exists only once per master */
716360
+struct ftp_info {
716360
+	/* Valid seq positions for cmd matching after newline */
716360
+	uint32_t seq_aft_nl[MYCT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
716360
+	/* 0 means seq_match_aft_nl not set */
716360
+	int seq_aft_nl_num[MYCT_DIR_MAX];
716360
+};
716360
+
716360
+#endif
716360
diff --git a/include/helpers/rpc.h b/include/helpers/rpc.h
716360
new file mode 100644
716360
index 0000000000000..b0b8d176fb542
716360
--- /dev/null
716360
+++ b/include/helpers/rpc.h
716360
@@ -0,0 +1,15 @@
716360
+#ifndef _CTD_RPC_H
716360
+#define _CTD_RPC_H
716360
+
716360
+struct rpc_info {
716360
+	/* XID */
716360
+	uint32_t xid;
716360
+	/* program */
716360
+	uint32_t pm_prog;
716360
+	/* program version */
716360
+	uint32_t pm_vers;
716360
+	/* transport protocol: TCP|UDP */
716360
+	uint32_t pm_prot;
716360
+};
716360
+
716360
+#endif
716360
diff --git a/include/helpers/sane.h b/include/helpers/sane.h
716360
new file mode 100644
716360
index 0000000000000..1e70ff636d60d
716360
--- /dev/null
716360
+++ b/include/helpers/sane.h
716360
@@ -0,0 +1,13 @@
716360
+#ifndef _CTD_SANE_H
716360
+#define _CTD_SANE_H
716360
+
716360
+enum sane_state {
716360
+	SANE_STATE_NORMAL,
716360
+	SANE_STATE_START_REQUESTED,
716360
+};
716360
+
716360
+struct nf_ct_sane_master {
716360
+	enum sane_state state;
716360
+};
716360
+
716360
+#endif
716360
diff --git a/include/helpers/tns.h b/include/helpers/tns.h
716360
new file mode 100644
716360
index 0000000000000..60dcf253657fc
716360
--- /dev/null
716360
+++ b/include/helpers/tns.h
716360
@@ -0,0 +1,9 @@
716360
+#ifndef _CTD_TNS_H
716360
+#define _CTD_TNS_H
716360
+
716360
+struct tns_info {
716360
+	/* Scan next DATA|REDIRECT packet */
716360
+	bool parse;
716360
+};
716360
+
716360
+#endif
716360
diff --git a/src/Makefile.am b/src/Makefile.am
716360
index a5b918d951327..9e47d2278a0d5 100644
716360
--- a/src/Makefile.am
716360
+++ b/src/Makefile.am
716360
@@ -35,8 +35,6 @@ if HAVE_CTHELPER
716360
 nfct_LDADD += ${LIBNETFILTER_CTHELPER_LIBS}
716360
 endif
716360
 
716360
-nfct_LDFLAGS = -export-dynamic ${LAZY_LDFLAGS}
716360
-
716360
 conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c queue_tx.c rbtree.c \
716360
 		    local.c log.c mcast.c udp.c netlink.c vector.c \
716360
 		    filter.c fds.c event.c process.c origin.c date.c \
716360
diff --git a/src/helpers.c b/src/helpers.c
716360
index 3e4e6c8553b8a..8ca78dc113fb7 100644
716360
--- a/src/helpers.c
716360
+++ b/src/helpers.c
716360
@@ -26,8 +26,7 @@ void helper_register(struct ctd_helper *helper)
716360
 	list_add(&helper->head, &helper_list);
716360
 }
716360
 
716360
-static struct ctd_helper *
716360
-__helper_find(const char *helper_name, uint8_t l4proto)
716360
+struct ctd_helper *__helper_find(const char *helper_name, uint8_t l4proto)
716360
 {
716360
 	struct ctd_helper *cur, *helper = NULL;
716360
 
716360
diff --git a/src/helpers/Makefile.am b/src/helpers/Makefile.am
716360
index d851d313e6fea..8f9c4ec556b66 100644
716360
--- a/src/helpers/Makefile.am
716360
+++ b/src/helpers/Makefile.am
716360
@@ -10,7 +10,7 @@ pkglib_LTLIBRARIES = ct_helper_amanda.la \
716360
 		     ct_helper_sane.la	\
716360
 		     ct_helper_ssdp.la
716360
 
716360
-HELPER_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS) $(LAZY_LDFLAGS)
716360
+HELPER_LDFLAGS = -avoid-version -module $(LIBNETFILTER_CONNTRACK_LIBS)
716360
 HELPER_CFLAGS = $(AM_CFLAGS) $(LIBNETFILTER_CONNTRACK_CFLAGS)
716360
 
716360
 ct_helper_amanda_la_SOURCES = amanda.c
716360
diff --git a/src/helpers/ftp.c b/src/helpers/ftp.c
716360
index c3aa28485b0f3..bd3f11788cc24 100644
716360
--- a/src/helpers/ftp.c
716360
+++ b/src/helpers/ftp.c
716360
@@ -35,17 +35,9 @@
716360
 #include <libnetfilter_queue/pktbuff.h>
716360
 #include <linux/netfilter.h>
716360
 
716360
-static bool loose; /* XXX: export this as config option. */
716360
-
716360
-#define NUM_SEQ_TO_REMEMBER 2
716360
+#include "helpers/ftp.h"
716360
 
716360
-/* This structure exists only once per master */
716360
-struct ftp_info {
716360
-	/* Valid seq positions for cmd matching after newline */
716360
-	uint32_t seq_aft_nl[MYCT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
716360
-	/* 0 means seq_match_aft_nl not set */
716360
-	int seq_aft_nl_num[MYCT_DIR_MAX];
716360
-};
716360
+static bool loose; /* XXX: export this as config option. */
716360
 
716360
 enum nf_ct_ftp_type {
716360
 	/* PORT command from client */
716360
diff --git a/src/helpers/rpc.c b/src/helpers/rpc.c
716360
index bd24dd3269c8e..83adf658521d4 100644
716360
--- a/src/helpers/rpc.c
716360
+++ b/src/helpers/rpc.c
716360
@@ -40,21 +40,12 @@
716360
 #include <libnetfilter_queue/pktbuff.h>
716360
 #include <linux/netfilter.h>
716360
 
716360
+#include "helpers/rpc.h"
716360
+
716360
 /* RFC 1050: RPC: Remote Procedure Call Protocol Specification Version 2 */
716360
 /* RFC 1014: XDR: External Data Representation Standard */
716360
 #define SUPPORTED_RPC_VERSION	2
716360
 
716360
-struct rpc_info {
716360
-	/* XID */
716360
-	uint32_t xid;
716360
-	/* program */
716360
-	uint32_t pm_prog;
716360
-	/* program version */
716360
-	uint32_t pm_vers;
716360
-	/* transport protocol: TCP|UDP */
716360
-	uint32_t pm_prot;
716360
-};
716360
-
716360
 /* So, this packet has hit the connection tracking matching code.
716360
    Mangle it, and change the expectation to match the new version. */
716360
 static unsigned int
716360
diff --git a/src/helpers/sane.c b/src/helpers/sane.c
716360
index c30f4ba18533e..5e02e4fc2c1c3 100644
716360
--- a/src/helpers/sane.c
716360
+++ b/src/helpers/sane.c
716360
@@ -38,11 +38,7 @@
716360
 #include <libnetfilter_queue/libnetfilter_queue_tcp.h>
716360
 #include <libnetfilter_queue/pktbuff.h>
716360
 #include <linux/netfilter.h>
716360
-
716360
-enum sane_state {
716360
-	SANE_STATE_NORMAL,
716360
-	SANE_STATE_START_REQUESTED,
716360
-};
716360
+#include "helpers/sane.h"
716360
 
716360
 struct sane_request {
716360
 	uint32_t RPC_code;
716360
@@ -60,10 +56,6 @@ struct sane_reply_net_start {
716360
 	/* other fields aren't interesting for conntrack */
716360
 };
716360
 
716360
-struct nf_ct_sane_master {
716360
-	enum sane_state state;
716360
-};
716360
-
716360
 static int
716360
 sane_helper_cb(struct pkt_buff *pkt, uint32_t protoff,
716360
 		 struct myct *myct, uint32_t ctinfo)
716360
diff --git a/src/helpers/tns.c b/src/helpers/tns.c
716360
index 2b4fed420afb0..d9c7ae693f3a7 100644
716360
--- a/src/helpers/tns.c
716360
+++ b/src/helpers/tns.c
716360
@@ -28,6 +28,8 @@
716360
 #include <libnetfilter_queue/pktbuff.h>
716360
 #include <linux/netfilter.h>
716360
 
716360
+#include "helpers/tns.h"
716360
+
716360
 /* TNS SQL*Net Version 2 */
716360
 enum tns_types {
716360
        TNS_TYPE_CONNECT        = 1,
716360
@@ -57,11 +59,6 @@ struct tns_redirect {
716360
        uint16_t data_len;
716360
 };
716360
 
716360
-struct tns_info {
716360
-       /* Scan next DATA|REDIRECT packet */
716360
-       bool parse;
716360
-};
716360
-
716360
 static int try_number(const char *data, size_t dlen, uint32_t array[],
716360
 		      int array_size, char sep, char term)
716360
 {
716360
diff --git a/src/nfct-extensions/helper.c b/src/nfct-extensions/helper.c
716360
index 0569827612f06..fdeb94c5e5172 100644
716360
--- a/src/nfct-extensions/helper.c
716360
+++ b/src/nfct-extensions/helper.c
716360
@@ -180,7 +180,7 @@ static int nfct_cmd_helper_add(struct mnl_socket *nl, int argc, char *argv[])
716360
 		return -1;
716360
 	}
716360
 
716360
-	helper = helper_find(CONNTRACKD_LIB_DIR, argv[3], l4proto, RTLD_LAZY);
716360
+	helper = __helper_find(argv[3], l4proto);
716360
 	if (helper == NULL) {
716360
 		nfct_perror("that helper is not supported");
716360
 		return -1;
716360
@@ -430,7 +430,7 @@ nfct_cmd_helper_disable(struct mnl_socket *nl, int argc, char *argv[])
716360
 		return -1;
716360
 	}
716360
 
716360
-	helper = helper_find(CONNTRACKD_LIB_DIR, argv[3], l4proto, RTLD_LAZY);
716360
+	helper = __helper_find(argv[3], l4proto);
716360
 	if (helper == NULL) {
716360
 		nfct_perror("that helper is not supported");
716360
 		return -1;
716360
@@ -468,7 +468,187 @@ static struct nfct_extension helper = {
716360
 	.parse_params	= nfct_helper_parse_params,
716360
 };
716360
 
716360
+/*
716360
+ * supported helpers: to set up helpers via nfct, the following definitions are
716360
+ * provided for backward compatibility reasons since conntrackd does not depend
716360
+ * on nfct anymore to set up the userspace helpers.
716360
+ */
716360
+
716360
+static struct ctd_helper amanda_helper = {
716360
+	.name		= "amanda",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name			= "amanda",
716360
+			.expect_max		= 3,
716360
+			.expect_timeout		= 180,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper dhcpv6_helper = {
716360
+	.name		= "dhcpv6",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name			= "dhcpv6",
716360
+			.expect_max		= 1,
716360
+			.expect_timeout		= 300,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+#include "helpers/ftp.h"
716360
+
716360
+static struct ctd_helper ftp_helper = {
716360
+	.name		= "ftp",
716360
+	.l4proto	= IPPROTO_TCP,
716360
+	.priv_data_len	= sizeof(struct ftp_info),
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name			= "ftp",
716360
+			.expect_max		= 1,
716360
+			.expect_timeout		= 300,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper mdns_helper = {
716360
+	.name		= "mdns",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.priv_data_len	= 0,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name		= "mdns",
716360
+			.expect_max	= 8,
716360
+			.expect_timeout = 30,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+#include "helpers/rpc.h"
716360
+
716360
+static struct ctd_helper rpc_helper_tcp = {
716360
+	.name		= "rpc",
716360
+	.l4proto	= IPPROTO_TCP,
716360
+	.priv_data_len	= sizeof(struct rpc_info),
716360
+	.policy		= {
716360
+		{
716360
+			.name			= "rpc",
716360
+			.expect_max		= 1,
716360
+			.expect_timeout		= 300,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper rpc_helper_udp = {
716360
+	.name		= "rpc",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.priv_data_len	= sizeof(struct rpc_info),
716360
+	.policy		= {
716360
+		{
716360
+			.name			= "rpc",
716360
+			.expect_max		= 1,
716360
+			.expect_timeout		= 300,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+#include "helpers/sane.h"
716360
+
716360
+static struct ctd_helper sane_helper = {
716360
+	.name		= "sane",
716360
+	.l4proto	= IPPROTO_TCP,
716360
+	.priv_data_len	= sizeof(struct nf_ct_sane_master),
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name			= "sane",
716360
+			.expect_max		= 1,
716360
+			.expect_timeout		= 5 * 60,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper slp_helper = {
716360
+	.name		= "slp",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.priv_data_len	= 0,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name		= "slp",
716360
+			.expect_max	= 8,
716360
+			.expect_timeout = 16, /* default CONFIG_MC_MAX + 1 */
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper ssdp_helper_udp = {
716360
+	.name		= "ssdp",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.priv_data_len	= 0,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name		= "ssdp",
716360
+			.expect_max	= 8,
716360
+			.expect_timeout = 5 * 60,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper ssdp_helper_tcp = {
716360
+	.name		= "ssdp",
716360
+	.l4proto	= IPPROTO_TCP,
716360
+	.priv_data_len	= 0,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name		= "ssdp",
716360
+			.expect_max	= 8,
716360
+			.expect_timeout = 5 * 60,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+static struct ctd_helper tftp_helper = {
716360
+	.name		= "tftp",
716360
+	.l4proto	= IPPROTO_UDP,
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name			= "tftp",
716360
+			.expect_max		= 1,
716360
+			.expect_timeout		= 5 * 60,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
+#include "helpers/tns.h"
716360
+
716360
+static struct ctd_helper tns_helper = {
716360
+	.name		= "tns",
716360
+	.l4proto	= IPPROTO_TCP,
716360
+	.priv_data_len	= sizeof(struct tns_info),
716360
+	.policy		= {
716360
+		[0] = {
716360
+			.name		= "tns",
716360
+			.expect_max	= 1,
716360
+			.expect_timeout = 300,
716360
+		},
716360
+	},
716360
+};
716360
+
716360
 static void __init helper_init(void)
716360
 {
716360
+	helper_register(&amanda_helper);
716360
+	helper_register(&dhcpv6_helper);
716360
+	helper_register(&ftp_helper);
716360
+	helper_register(&mdns_helper);
716360
+	helper_register(&rpc_helper_tcp);
716360
+	helper_register(&rpc_helper_udp);
716360
+	helper_register(&sane_helper);
716360
+	helper_register(&slp_helper);
716360
+	helper_register(&ssdp_helper_udp);
716360
+	helper_register(&ssdp_helper_tcp);
716360
+	helper_register(&tftp_helper);
716360
+	helper_register(&tns_helper);
716360
+
716360
 	nfct_extension_register(&helper);
716360
 }
716360
-- 
716360
2.34.1
716360