use uv_dlopen() instead of dlopen() when linking DNSRPZ

take advantage of libuv's shared library handling capability
when linking to a DNSRPS library.  (see b396f55586 and 37b9511ce1
for prior related work.)
This commit is contained in:
Evan Hunt 2024-08-22 16:01:50 -07:00 committed by Ondřej Surý
parent d7bff3c0f9
commit dc13333957
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
5 changed files with 36 additions and 69 deletions

View file

@ -67,8 +67,8 @@ rpz_dnsrps_CPPFLAGS = \
rpz_dnsrps_LDADD = \
$(LDADD) \
$(LIBDNS_LIBS) \
$(DLOPEN_LIBS)
$(LIBUV_LIBS) \
$(LIBDNS_LIBS)
# Longer running tests are listed (and executed) first to take the most
# advantage of parallel execution.

View file

@ -9,4 +9,4 @@ AM_CFLAGS += -Wall -pedantic -Wno-zero-length-array
noinst_LTLIBRARIES = libdummyrpz.la
libdummyrpz_la_SOURCES= dummylib.c test-data.c trpz.h test-data.h
libdummyrpz_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -rpath $(abs_builddir)
LDADD += -lpthread $(DLOPEN_LIBS)
LDADD += -lpthread

View file

@ -108,9 +108,6 @@ AC_PROG_MKDIR_P
# Initialize libtool
LT_INIT([disable-static dlopen pic-only])
DLOPEN_LIBS="$lt_cv_dlopen_libs"
AC_SUBST(DLOPEN_LIBS)
AS_IF([test "$enable_static" != "no" && test "$enable_developer" != "yes"],
[AC_MSG_ERROR([Static linking is not supported as it disables dlopen() and certain security features (e.g. RELRO, ASLR)])])

View file

@ -35,7 +35,7 @@
librpz_t *librpz = NULL;
librpz_emsg_t librpz_lib_open_emsg;
static void *librpz_handle = NULL;
static uv_lib_t librpz_handle;
#define RPSDB_MAGIC ISC_MAGIC('R', 'P', 'Z', 'F')
#define VALID_RPSDB(rpsdb) ((rpsdb)->common.impmagic == RPSDB_MAGIC)
@ -134,7 +134,6 @@ dns_dnsrps_server_create(const char *librpz_path) {
INSIST(clist == NULL);
INSIST(librpz == NULL);
INSIST(librpz_handle == NULL);
/*
* Notice if librpz is available.
@ -171,14 +170,7 @@ dns_dnsrps_server_destroy(void) {
#if DNSRPS_LIB_OPEN == 2
if (librpz != NULL) {
INSIST(librpz_handle != NULL);
if (dlclose(librpz_handle) != 0) {
isc_log_write(DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB,
DNS_RPZ_ERROR_LEVEL,
"dnsrps: dlclose(): %s", dlerror());
}
librpz_handle = NULL;
librpz = NULL;
librpz_lib_close(&librpz, &librpz_handle);
}
#endif
}

View file

@ -43,6 +43,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include <uv.h>
/*
* Allow either ordinary or dlopen() linking.
@ -852,71 +853,48 @@ extern librpz_t *librpz;
* @return address of interface structure or NULL on failure
*/
static inline librpz_t *
librpz_lib_open(librpz_emsg_t *emsg, void **dl_handle, const char *path) {
void *handle;
librpz_t *new_librpz;
librpz_lib_open(librpz_emsg_t *emsg, uv_lib_t *lib, const char *path) {
librpz_t *new_librpz = NULL;
int r;
emsg->c[0] = '\0';
/*
* Close a previously opened handle on librpz.so.
*/
if (dl_handle != NULL && *dl_handle != NULL) {
if (dlclose(*dl_handle) != 0) {
snprintf(emsg->c, sizeof(librpz_emsg_t),
"dlopen(NULL): %s", dlerror());
return (NULL);
}
*dl_handle = NULL;
}
/*
* First try the main executable of the process in case it was
* linked to librpz.
* Do not worry if we cannot search the main executable of the process.
*/
handle = dlopen(NULL, RTLD_NOW | RTLD_LOCAL);
if (handle != NULL) {
new_librpz = dlsym(handle, LIBRPZ_DEF_STR);
if (new_librpz != NULL) {
if (dl_handle != NULL) {
*dl_handle = handle;
handle = NULL;
}
return (new_librpz);
}
if (dlclose(handle) != 0) {
snprintf(emsg->c, sizeof(librpz_emsg_t),
"dlsym(NULL, " LIBRPZ_DEF_STR "): %s",
dlerror());
return (NULL);
}
}
if (path == NULL || path[0] == '\0') {
snprintf(emsg->c, sizeof(librpz_emsg_t),
"librpz not linked and no dlopen() path provided");
"path to librpz not provided");
return (NULL);
}
handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (handle == NULL) {
snprintf(emsg->c, sizeof(librpz_emsg_t), "dlopen(%s): %s", path,
dlerror());
r = uv_dlopen(path, lib);
if (r != 0) {
const char *errmsg = uv_dlerror(lib);
if (errmsg == NULL) {
errmsg = "unknown error";
}
snprintf(emsg->c, sizeof(librpz_emsg_t), "uv_dlopen(%s): %s",
path, errmsg);
uv_dlclose(lib);
return (NULL);
}
new_librpz = dlsym(handle, LIBRPZ_DEF_STR);
if (new_librpz != NULL) {
if (dl_handle != NULL) {
*dl_handle = handle;
handle = NULL;
r = uv_dlsym(lib, LIBRPZ_DEF_STR, (void **)&new_librpz);
if (r != 0) {
const char *errmsg = uv_dlerror(lib);
if (errmsg == NULL) {
errmsg = "returned function pointer is NULL";
}
return (new_librpz);
uv_dlclose(lib);
snprintf(emsg->c, sizeof(librpz_emsg_t),
"dlsym(%s, " LIBRPZ_DEF_STR "): %s", path, errmsg);
return (NULL);
}
snprintf(emsg->c, sizeof(librpz_emsg_t),
"dlsym(%s, " LIBRPZ_DEF_STR "): %s", path, dlerror());
dlclose(handle);
return (NULL);
return (new_librpz);
}
static inline void
librpz_lib_close(librpz_t **rpz, uv_lib_t *lib) {
*rpz = NULL;
uv_dlclose(lib);
}
#elif defined(LIBRPZ_LIB_OPEN)
/*