]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: Introduce xtables_fini()
authorPhil Sutter <phil@nwl.cc>
Tue, 5 May 2020 11:56:11 +0000 (13:56 +0200)
committerPhil Sutter <phil@nwl.cc>
Mon, 11 May 2020 12:28:29 +0000 (14:28 +0200)
Record handles of loaded shared objects in a linked list and dlclose()
them from the newly introduced function. While functionally not
necessary, this clears up valgrind's memcheck output when also
displaying reachable memory.

Since this is an extra function that doesn't change the existing API,
increment both current and age.

Signed-off-by: Phil Sutter <phil@nwl.cc>
14 files changed:
configure.ac
include/xtables.h
iptables/ip6tables-standalone.c
iptables/iptables-restore.c
iptables/iptables-save.c
iptables/iptables-standalone.c
iptables/xtables-arp-standalone.c
iptables/xtables-eb.c
iptables/xtables-monitor.c
iptables/xtables-restore.c
iptables/xtables-save.c
iptables/xtables-standalone.c
iptables/xtables-translate.c
libxtables/xtables.c

index 27e90703c9adac46fce6f734206865cb2b7ab15b..02f6481ca52edf5717fd2a70d69b8451573ba7a5 100644 (file)
@@ -2,8 +2,8 @@
 AC_INIT([iptables], [1.8.4])
 
 # See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=14
-libxtables_vage=2
+libxtables_vcurrent=15
+libxtables_vage=3
 
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_HEADERS([config.h])
index 4aa084a1a2a30704e48b269d461257f3ce444fff..5044dd08e86d366bd973012f775fb32bc032fd33 100644 (file)
@@ -448,6 +448,7 @@ extern struct xtables_match *xtables_matches;
 extern struct xtables_target *xtables_targets;
 
 extern void xtables_init(void);
+extern void xtables_fini(void);
 extern void xtables_set_nfproto(uint8_t);
 extern void *xtables_calloc(size_t, size_t);
 extern void *xtables_malloc(size_t);
index 35d2d9a51f57529f4ef56d54bf6e183191ff4493..105b83ba54010d5b67517bca75763d939418d2ff 100644 (file)
@@ -64,6 +64,8 @@ ip6tables_main(int argc, char *argv[])
                ip6tc_free(handle);
        }
 
+       xtables_fini();
+
        if (!ret) {
                if (errno == EINVAL) {
                        fprintf(stderr, "ip6tables: %s. "
index fea04842d38c80347b98871b74054cd8b7e7bfaa..cc2c2b8b100865a0ddeb9233416ef98c0dde88eb 100644 (file)
@@ -372,7 +372,7 @@ static const struct iptables_restore_cb ipt_restore_cb = {
 int
 iptables_restore_main(int argc, char *argv[])
 {
-       int c;
+       int c, ret;
 
        iptables_globals.program_name = "iptables-restore";
        c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
@@ -387,7 +387,10 @@ iptables_restore_main(int argc, char *argv[])
        init_extensions4();
 #endif
 
-       return ip46tables_restore_main(&ipt_restore_cb, argc, argv);
+       ret = ip46tables_restore_main(&ipt_restore_cb, argc, argv);
+
+       xtables_fini();
+       return ret;
 }
 #endif
 
@@ -403,7 +406,7 @@ static const struct iptables_restore_cb ip6t_restore_cb = {
 int
 ip6tables_restore_main(int argc, char *argv[])
 {
-       int c;
+       int c, ret;
 
        ip6tables_globals.program_name = "ip6tables-restore";
        c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
@@ -418,6 +421,9 @@ ip6tables_restore_main(int argc, char *argv[])
        init_extensions6();
 #endif
 
-       return ip46tables_restore_main(&ip6t_restore_cb, argc, argv);
+       ret = ip46tables_restore_main(&ip6t_restore_cb, argc, argv);
+
+       xtables_fini();
+       return ret;
 }
 #endif
index c7251e35ad763fe39a142375af275c04f9517f34..4efd66673f5dea5b518a52b3807b2d47040ca4d0 100644 (file)
@@ -218,6 +218,8 @@ struct iptables_save_cb ipt_save_cb = {
 int
 iptables_save_main(int argc, char *argv[])
 {
+       int ret;
+
        iptables_globals.program_name = "iptables-save";
        if (xtables_init_all(&iptables_globals, NFPROTO_IPV4) < 0) {
                fprintf(stderr, "%s/%s Failed to initialize xtables\n",
@@ -230,7 +232,10 @@ iptables_save_main(int argc, char *argv[])
        init_extensions4();
 #endif
 
-       return do_iptables_save(&ipt_save_cb, argc, argv);
+       ret = do_iptables_save(&ipt_save_cb, argc, argv);
+
+       xtables_fini();
+       return ret;
 }
 #endif /* ENABLE_IPV4 */
 
@@ -259,6 +264,8 @@ struct iptables_save_cb ip6t_save_cb = {
 int
 ip6tables_save_main(int argc, char *argv[])
 {
+       int ret;
+
        ip6tables_globals.program_name = "ip6tables-save";
        if (xtables_init_all(&ip6tables_globals, NFPROTO_IPV6) < 0) {
                fprintf(stderr, "%s/%s Failed to initialize xtables\n",
@@ -271,6 +278,9 @@ ip6tables_save_main(int argc, char *argv[])
        init_extensions6();
 #endif
 
-       return do_iptables_save(&ip6t_save_cb, argc, argv);
+       ret = do_iptables_save(&ip6t_save_cb, argc, argv);
+
+       xtables_fini();
+       return ret;
 }
 #endif /* ENABLE_IPV6 */
index c211fb7399dac8ce2ecdd5bffe2b9e6f14cf9553..8c67ea4d9a2fb5f1de35c7de4fc05ca09610251a 100644 (file)
@@ -64,6 +64,8 @@ iptables_main(int argc, char *argv[])
                iptc_free(handle);
        }
 
+       xtables_fini();
+
        if (!ret) {
                if (errno == EINVAL) {
                        fprintf(stderr, "iptables: %s. "
index eca7bb979b967b86b98ed9ca5c4ddee97dcac0aa..04cf7dccc820671cd475ad580dd8c74d5c2b7d2e 100644 (file)
@@ -56,6 +56,7 @@ int xtables_arp_main(int argc, char *argv[])
                ret = nft_commit(&h);
 
        nft_fini(&h);
+       xtables_fini();
 
        if (!ret)
                fprintf(stderr, "arptables: %s\n", nft_strerror(errno));
index 0df1345ae5cd359160fda873a8795da577f1f9c2..5764d1803cba7dab7459dd9ae5978a6bcc2c8419 100644 (file)
@@ -767,6 +767,7 @@ void nft_fini_eb(struct nft_handle *h)
        free(opts);
 
        nft_fini(h);
+       xtables_fini();
 }
 
 int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
index c2b31dbaa07958b8723d4d8cc67df25a53984613..57def83e2eea066a700cae81ec78749579fbb5fc 100644 (file)
@@ -688,6 +688,8 @@ int xtables_monitor_main(int argc, char *argv[])
        }
        mnl_socket_close(nl);
 
+       xtables_fini();
+
        return EXIT_SUCCESS;
 }
 
index 0d6fd64271f516727f69c9df010407be3330e2a6..a3bb4f00e79c6ca624df1047138533ca22c45df7 100644 (file)
@@ -391,6 +391,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
        xtables_restore_parse(&h, &p);
 
        nft_fini(&h);
+       xtables_fini();
        fclose(p.in);
        return 0;
 }
@@ -473,6 +474,7 @@ int xtables_arp_restore_main(int argc, char *argv[])
        nft_init_arp(&h, "arptables-restore");
        xtables_restore_parse(&h, &p);
        nft_fini(&h);
+       xtables_fini();
 
        return 0;
 }
index 0ce66e5d15cee1a9c4cfed8022a11b11fc068f23..bb3d8cd336c38ea33f0be5d205321f8c472623ff 100644 (file)
@@ -244,6 +244,7 @@ xtables_save_main(int family, int argc, char *argv[],
 
        ret = do_output(&h, tablename, &d);
        nft_fini(&h);
+       xtables_fini();
        if (dump)
                exit(0);
 
index 022d5dd44abbf12b555bc3506feba2069930505c..dd6fb7919d2e18292fbc49ab8a04a5b1af9e2cbe 100644 (file)
@@ -72,6 +72,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
                ret = nft_commit(&h);
 
        nft_fini(&h);
+       xtables_fini();
 
        if (!ret) {
                if (errno == EINVAL) {
index 76ad7eb69eca91f80599ea7a7a5ed53bbae80d63..5aa42496b5a481b50760bea51d2cd33cad7ce159 100644 (file)
@@ -509,6 +509,7 @@ static int xtables_xlate_main(int family, const char *progname, int argc,
                fprintf(stderr, "Translation not implemented\n");
 
        nft_fini(&h);
+       xtables_fini();
        exit(!ret);
 }
 
@@ -563,6 +564,7 @@ static int xtables_restore_xlate_main(int family, const char *progname,
        printf("# Completed on %s", ctime(&now));
 
        nft_fini(&h);
+       xtables_fini();
        fclose(p.in);
        exit(0);
 }
index 777c2b08e9896850cd0285a3246581acf2e5e188..7fe42580f9b70201e7578d7ea118856a609075a1 100644 (file)
@@ -206,6 +206,38 @@ struct xtables_target *xtables_targets;
 static bool xtables_fully_register_pending_match(struct xtables_match *me);
 static bool xtables_fully_register_pending_target(struct xtables_target *me);
 
+/* registry for loaded shared objects to close later */
+struct dlreg {
+       struct dlreg *next;
+       void *handle;
+};
+static struct dlreg *dlreg = NULL;
+
+static int dlreg_add(void *handle)
+{
+       struct dlreg *new = malloc(sizeof(*new));
+
+       if (!new)
+               return -1;
+
+       new->handle = handle;
+       new->next = dlreg;
+       dlreg = new;
+       return 0;
+}
+
+static void dlreg_free(void)
+{
+       struct dlreg *next;
+
+       while (dlreg) {
+               next = dlreg->next;
+               dlclose(dlreg->handle);
+               free(dlreg);
+               dlreg = next;
+       }
+}
+
 void xtables_init(void)
 {
        xtables_libdir = getenv("XTABLES_LIBDIR");
@@ -233,6 +265,11 @@ void xtables_init(void)
        xtables_libdir = XTABLES_LIBDIR;
 }
 
+void xtables_fini(void)
+{
+       dlreg_free();
+}
+
 void xtables_set_nfproto(uint8_t nfproto)
 {
        switch (nfproto) {
@@ -567,6 +604,8 @@ static void *load_extension(const char *search_path, const char *af_prefix,
                        next = dir + strlen(dir);
 
                for (prefix = all_prefixes; *prefix != NULL; ++prefix) {
+                       void *handle;
+
                        snprintf(path, sizeof(path), "%.*s/%s%s.so",
                                 (unsigned int)(next - dir), dir,
                                 *prefix, name);
@@ -578,11 +617,14 @@ static void *load_extension(const char *search_path, const char *af_prefix,
                                        strerror(errno));
                                return NULL;
                        }
-                       if (dlopen(path, RTLD_NOW) == NULL) {
+                       handle = dlopen(path, RTLD_NOW);
+                       if (handle == NULL) {
                                fprintf(stderr, "%s: %s\n", path, dlerror());
                                break;
                        }
 
+                       dlreg_add(handle);
+
                        if (is_target)
                                ptr = xtables_find_target(name, XTF_DONT_LOAD);
                        else