From d8e8a90fd151d131666d9d72bd6d40d356f4bdf0 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 11 Dec 2013 16:13:11 -0500 Subject: [PATCH] Ticket 47601 - Plugin library path validation prevents intentional loading of out-of-tree modules Bug Description: The fix for ticket 47384 does not allow plugins to have their shared libs stored anywhere else but in the default location. Fix Description: Allow plugin paths that are not in the default area if the absolute path has been specified, and the library can be opened. https://fedorahosted.org/389/ticket/47601 Reviewed by: rmeggins(Thanks!) --- Makefile.am | 3 ++- Makefile.in | 6 ++++-- ldap/servers/slapd/dynalib.c | 2 +- ldap/servers/slapd/fedse.c | 9 ++++++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index bfa42f5..26174bf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,6 +65,7 @@ PCRE_LINK = @pcre_lib@ -lpcre NETSNMP_LINK = @netsnmp_lib@ @netsnmp_link@ PAM_LINK = -lpam KERBEROS_LINK = $(kerberos_lib) +DLOPEN_LINK = -ldl LIBSOCKET=@LIBSOCKET@ LIBNSL=@LIBNSL@ @@ -1462,7 +1463,7 @@ ns_slapd_SOURCES = ldap/servers/slapd/abandon.c \ ns_slapd_CPPFLAGS = $(AM_CPPFLAGS) @sasl_inc@ @openldap_inc@ @ldapsdk_inc@ @nss_inc@ \ @nspr_inc@ @svrcore_inc@ -ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) \ +ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) $(DLOPEN_LINK) \ $(NSPR_LINK) $(SASL_LINK) $(SVRCORE_LINK) $(LIBNSL) $(LIBSOCKET) $(THREADLIB) # We need to link ns-slapd with the C++ compiler on HP-UX since we load # some C++ shared libraries (such as icu). diff --git a/Makefile.in b/Makefile.in index fb4f2a9..3b6e477 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1063,7 +1063,8 @@ ns_slapd_DEPENDENCIES = libslapd.la libldaputil.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_pwdhash_bin_OBJECTS = \ ldap/servers/slapd/tools/pwdhash_bin-pwenc.$(OBJEXT) pwdhash_bin_OBJECTS = $(am_pwdhash_bin_OBJECTS) @@ -1548,6 +1549,7 @@ PCRE_LINK = @pcre_lib@ -lpcre NETSNMP_LINK = @netsnmp_lib@ @netsnmp_link@ PAM_LINK = -lpam KERBEROS_LINK = $(kerberos_lib) +DLOPEN_LINK = -ldl #------------------------ # Generated Sources @@ -2783,7 +2785,7 @@ ns_slapd_SOURCES = ldap/servers/slapd/abandon.c \ ns_slapd_CPPFLAGS = $(AM_CPPFLAGS) @sasl_inc@ @openldap_inc@ @ldapsdk_inc@ @nss_inc@ \ @nspr_inc@ @svrcore_inc@ -ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) \ +ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) $(DLOPEN_LINK) \ $(NSPR_LINK) $(SASL_LINK) $(SVRCORE_LINK) $(LIBNSL) $(LIBSOCKET) $(THREADLIB) @HPUX_FALSE@ns_slapd_LINK = $(LINK) diff --git a/ldap/servers/slapd/dynalib.c b/ldap/servers/slapd/dynalib.c index 0448537..367fbba 100644 --- a/ldap/servers/slapd/dynalib.c +++ b/ldap/servers/slapd/dynalib.c @@ -107,7 +107,7 @@ sym_load_with_flags( char *libpath, char *symbol, char *plugin, int report_error } if (PR_SUCCESS != PR_Access(libpath, PR_ACCESS_READ_OK)) { - if (strncmp(libpath, PLUGINDIR, strlen(PLUGINDIR))) { + if (strncmp(libpath, PLUGINDIR, strlen(PLUGINDIR)) && libpath[0] != '/') { libSpec.value.pathname = slapi_get_plugin_name(PLUGINDIR, libpath); } else { libSpec.value.pathname = slapi_get_plugin_name(NULL, libpath); diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c index cb6c2ed..0b537bb 100644 --- a/ldap/servers/slapd/fedse.c +++ b/ldap/servers/slapd/fedse.c @@ -67,6 +67,7 @@ #include #include #include +#include #include "slap.h" #include "fe.h" @@ -1921,7 +1922,6 @@ check_plugin_path(Slapi_PBlock *pb, { /* check for invalid nsslapd-pluginPath */ char **vals = slapi_entry_attr_get_charray (e, ATTR_PLUGIN_PATH); - int plugindir_len = sizeof(PLUGINDIR)-1; int j = 0; int rc = SLAPI_DSE_CALLBACK_OK; @@ -1930,6 +1930,7 @@ check_plugin_path(Slapi_PBlock *pb, vals = slapi_entry_attr_get_charray (entryBefore, ATTR_PLUGIN_PATH); } for (j = 0; vals && vals[j]; j++) { + void *handle; char *full_path = NULL; char *resolved_path = NULL; char *res = NULL; @@ -1942,10 +1943,12 @@ check_plugin_path(Slapi_PBlock *pb, resolved_path = slapi_ch_malloc(strlen(full_path) + 1); res = realpath( full_path, resolved_path ); if (res) { - if (strncmp(PLUGINDIR, resolved_path, plugindir_len) != 0) { + if ((handle = dlopen(res, RTLD_NOW)) == NULL) { *returncode = LDAP_UNWILLING_TO_PERFORM; - PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Invalid plugin path"); + PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Invalid plugin path - failed to open library"); rc = SLAPI_DSE_CALLBACK_ERROR; + } else { + dlclose(handle); } } else { *returncode = LDAP_UNWILLING_TO_PERFORM; -- 1.7.1