summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-07-25 17:50:14 -0400
committerDan Winship <danw@gnome.org>2014-07-31 14:58:15 -0400
commit80715291ca183a72f5602a6a1a42535cce327677 (patch)
tree403eff410e9a076ab195a9504b2ed7da98147c6a
parent51a2cd2882133e20c4a894127b685ea18c5fe1d9 (diff)
downloadNetworkManager-danw/libnm-initial.tar.gz
libnm, libnm-utils: error out if mixed libnm/libnm-util symbols are detecteddanw/libnm-initial
If a program accidentally ends up linking in both libnm and libnm-util (presumably via different dependencies), error out immediately.
-rw-r--r--.gitignore1
-rw-r--r--libnm-core/nm-utils.c13
-rw-r--r--libnm-util/nm-utils.c13
-rw-r--r--libnm-util/tests/Makefile.am15
-rw-r--r--libnm-util/tests/test-general.c22
-rw-r--r--libnm-util/tests/test-libnm-linking.c44
6 files changed, 107 insertions, 1 deletions
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 <netinet/ether.h>
#include <linux/if_infiniband.h>
#include <uuid/uuid.h>
+#include <gmodule.h>
#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 <netinet/ether.h>
#include <linux/if_infiniband.h>
#include <uuid/uuid.h>
+#include <gmodule.h>
#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 <string.h>
#include <netinet/ether.h>
#include <linux/if_infiniband.h>
+#include <sys/wait.h>
#include <nm-utils.h>
@@ -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 <glib.h>
+#include <nm-utils.h>
+
+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 ();
+}