From 80715291ca183a72f5602a6a1a42535cce327677 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 25 Jul 2014 17:50:14 -0400 Subject: libnm, libnm-utils: error out if mixed libnm/libnm-util symbols are detected If a program accidentally ends up linking in both libnm and libnm-util (presumably via different dependencies), error out immediately. --- .gitignore | 1 + libnm-core/nm-utils.c | 13 +++++++++++ libnm-util/nm-utils.c | 13 +++++++++++ libnm-util/tests/Makefile.am | 15 +++++++++++- libnm-util/tests/test-general.c | 22 ++++++++++++++++++ libnm-util/tests/test-libnm-linking.c | 44 +++++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 libnm-util/tests/test-libnm-linking.c diff --git a/.gitignore b/.gitignore index 0ad930a320..2c3ccc4c6a 100644 --- a/.gitignore +++ b/.gitignore @@ -193,6 +193,7 @@ valgrind-*.log /libnm-util/tests/test-crypto /libnm-util/tests/test-settings-defaults /libnm-util/tests/test-general +/libnm-util/tests/test-libnm-linking /libnm-util/tests/test-need-secrets /libnm-util/tests/test-secrets /libnm-util/tests/test-setting-8021x diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 9be9077e25..4c3a89f744 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "nm-utils.h" #include "nm-utils-private.h" @@ -201,6 +202,18 @@ get_encodings_for_lang (const char *lang, /* init, deinit for libnm_util */ +static void __attribute__((constructor)) +_check_symbols (void) +{ + GModule *self; + gpointer func; + + self = g_module_open (NULL, 0); + if (g_module_symbol (self, "nm_util_get_private", &func)) + g_error ("libnm-util symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); + g_module_close (self); +} + static gboolean initialized = FALSE; /** diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 9c96601c90..a5113538dd 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "nm-utils.h" #include "nm-utils-private.h" @@ -202,6 +203,18 @@ get_encodings_for_lang (const char *lang, /* init, deinit for libnm_util */ +static void __attribute__((constructor)) +_check_symbols (void) +{ + GModule *self; + gpointer func; + + self = g_module_open (NULL, 0); + if (g_module_symbol (self, "nm_device_state_get_type", &func)) + g_error ("libnm symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); + g_module_close (self); +} + static gboolean initialized = FALSE; /** diff --git a/libnm-util/tests/Makefile.am b/libnm-util/tests/Makefile.am index 2b3366fcd7..3acc4fcc9a 100644 --- a/libnm-util/tests/Makefile.am +++ b/libnm-util/tests/Makefile.am @@ -9,6 +9,7 @@ AM_CPPFLAGS = \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + -DBUILD_DIR=\"$(abs_builddir)\" \ -DTEST_CERT_DIR=\"$(top_srcdir)/libnm-util/tests/certs/\" noinst_PROGRAMS = \ @@ -17,7 +18,8 @@ noinst_PROGRAMS = \ test-secrets \ test-general \ test-setting-8021x \ - test-setting-dcb + test-setting-dcb \ + test-libnm-linking test_settings_defaults_SOURCES = \ test-settings-defaults.c @@ -51,6 +53,8 @@ test_general_LDADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS) +test_general_DEPENDENCIES = test-libnm-linking + test_setting_8021x_SOURCES = \ test-setting-8021x.c @@ -67,6 +71,15 @@ test_setting_dcb_LDADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS) +test_libnm_linking_SOURCES = \ + test-libnm-linking.c + +test_libnm_linking_LDADD = \ + $(top_builddir)/libnm/libnm.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) + check-local: test-crypto test-setting-8021x # Private key and CA certificate in the same file (PEM) $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test_key_and_cert.pem "test" diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 877c38a316..b3d358de3a 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -2445,6 +2446,25 @@ test_connection_normalize_virtual_iface_name (void) g_object_unref (con); } +static void +test_libnm_linking (void) +{ + char *argv[] = { "./test-libnm-linking", NULL }; + char *out, *err; + int status; + GError *error = NULL; + + g_spawn_sync (BUILD_DIR, argv, NULL, G_SPAWN_DEFAULT, NULL, NULL, + &out, &err, &status, &error); + g_assert_no_error (error); + + g_assert (WIFSIGNALED (status)); + + g_assert (strstr (err, "Mixing libnm") != NULL); + g_free (out); + g_free (err); +} + NMTST_DEFINE (); int main (int argc, char **argv) @@ -2520,6 +2540,8 @@ int main (int argc, char **argv) test_setting_wireless_security_changed_signal (); test_setting_802_1x_changed_signal (); + test_libnm_linking (); + base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); g_free (base); diff --git a/libnm-util/tests/test-libnm-linking.c b/libnm-util/tests/test-libnm-linking.c new file mode 100644 index 0000000000..dd81d1cfc5 --- /dev/null +++ b/libnm-util/tests/test-libnm-linking.c @@ -0,0 +1,44 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + * + */ + +#include +#include + +extern GType nm_state_get_type (void); + +int +main (int argc, char **argv) +{ + /* If we reach main(), then the test has failed. */ + g_printerr ("libnm/libnm-util constructor failed to detect symbol mixing\n"); + + /* This is just to ensure that both libnm.so and libnm-util.so get pulled + * in; libnm-util doesn't have "nm_state_get_type" and libnm doesn't have + * "nm_utils_slist_free". (We intentionally choose different symbols than the + * ones that the libraries check for.) + */ + nm_state_get_type (); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + nm_utils_slist_free (NULL, g_free); + G_GNUC_END_IGNORE_DEPRECATIONS; + + g_assert_not_reached (); +} -- cgit v1.2.1