-
Notifications
You must be signed in to change notification settings - Fork 360
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libselinux: add build time option to drop hard dependency on libpcre2
Currently libselinux links to libpcre2. The regex library is used in the file backend of the selabel database for file context path matching. Some client applications using libselinux might not use that selabel functionality, but they still require to load libpcre2. Examples are dbus-broker and sshd (where openssh only uses the selabel interfaces to create ~/.ssh with the default context). Add a build time option, USE_PCRE2_DLSYM, to drop the hard dependency on libpcre2 and only load it, if actually needed, at runtime via dlopen(3). Since loading the database for the file backend takes a couple of milliseconds performance is not a concern. Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
- Loading branch information
Showing
5 changed files
with
220 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#include "regex_dlsym.h" | ||
|
||
#ifdef USE_PCRE2_DLSYM | ||
|
||
#include "callbacks.h" | ||
#include "selinux_internal.h" | ||
|
||
#include <dlfcn.h> | ||
#include <pthread.h> | ||
|
||
|
||
#define DLSYM_FUNC(symbol) typeof(symbol)* sym_##symbol = NULL | ||
|
||
#define DLSYM_RESOLVE(handle, symbol) do { \ | ||
sym_##symbol = dlsym(handle, #symbol); \ | ||
if (!sym_##symbol) { \ | ||
selinux_log(SELINUX_ERROR, "Failed to resolve symbol %s: %s\n", #symbol, dlerror()); \ | ||
goto err; \ | ||
} \ | ||
} while(0) | ||
|
||
DLSYM_FUNC(pcre2_code_free_8); | ||
DLSYM_FUNC(pcre2_compile_8); | ||
DLSYM_FUNC(pcre2_config_8); | ||
DLSYM_FUNC(pcre2_get_error_message_8); | ||
DLSYM_FUNC(pcre2_match_8); | ||
DLSYM_FUNC(pcre2_match_data_create_from_pattern_8); | ||
DLSYM_FUNC(pcre2_match_data_free_8); | ||
DLSYM_FUNC(pcre2_pattern_info_8); | ||
DLSYM_FUNC(pcre2_serialize_decode_8); | ||
DLSYM_FUNC(pcre2_serialize_encode_8); | ||
DLSYM_FUNC(pcre2_serialize_free_8); | ||
DLSYM_FUNC(pcre2_serialize_get_number_of_codes_8); | ||
|
||
static void *libpcre2_handle = NULL; | ||
static pthread_mutex_t libpcre2_lock = PTHREAD_MUTEX_INITIALIZER; | ||
|
||
|
||
static void *load_impl(void) { | ||
void *handle; | ||
|
||
handle = dlopen("libpcre2-8.so", RTLD_LAZY); | ||
if (!handle) { | ||
handle = dlopen("libpcre2-8.so.0", RTLD_LAZY); | ||
if (!handle) { | ||
selinux_log(SELINUX_ERROR, "Failed to load libpcre2-8: %s\n", dlerror()); | ||
return NULL; | ||
} | ||
} | ||
|
||
DLSYM_RESOLVE(handle, pcre2_code_free_8); | ||
DLSYM_RESOLVE(handle, pcre2_compile_8); | ||
DLSYM_RESOLVE(handle, pcre2_config_8); | ||
DLSYM_RESOLVE(handle, pcre2_get_error_message_8); | ||
DLSYM_RESOLVE(handle, pcre2_match_8); | ||
DLSYM_RESOLVE(handle, pcre2_match_data_create_from_pattern_8); | ||
DLSYM_RESOLVE(handle, pcre2_match_data_free_8); | ||
DLSYM_RESOLVE(handle, pcre2_pattern_info_8); | ||
DLSYM_RESOLVE(handle, pcre2_serialize_decode_8); | ||
DLSYM_RESOLVE(handle, pcre2_serialize_encode_8); | ||
DLSYM_RESOLVE(handle, pcre2_serialize_free_8); | ||
DLSYM_RESOLVE(handle, pcre2_serialize_get_number_of_codes_8); | ||
|
||
return handle; | ||
|
||
err: | ||
sym_pcre2_code_free_8 = NULL; | ||
sym_pcre2_compile_8 = NULL; | ||
sym_pcre2_config_8 = NULL; | ||
sym_pcre2_get_error_message_8 = NULL; | ||
sym_pcre2_match_8 = NULL; | ||
sym_pcre2_match_data_create_from_pattern_8 = NULL; | ||
sym_pcre2_match_data_free_8 = NULL; | ||
sym_pcre2_pattern_info_8 = NULL; | ||
sym_pcre2_serialize_decode_8 = NULL; | ||
sym_pcre2_serialize_encode_8 = NULL; | ||
sym_pcre2_serialize_free_8 = NULL; | ||
sym_pcre2_serialize_get_number_of_codes_8 = NULL; | ||
|
||
if (handle) | ||
dlclose(handle); | ||
return NULL; | ||
} | ||
|
||
int regex_pcre2_load(void) { | ||
void *handle; | ||
|
||
handle = __atomic_load_n(&libpcre2_handle, __ATOMIC_ACQUIRE); | ||
if (handle) | ||
return 0; | ||
|
||
__pthread_mutex_lock(&libpcre2_lock); | ||
|
||
/* Check if another thread validated the context while we waited on the mutex */ | ||
handle = __atomic_load_n(&libpcre2_handle, __ATOMIC_ACQUIRE); | ||
if (handle) { | ||
__pthread_mutex_unlock(&libpcre2_lock); | ||
return 0; | ||
} | ||
|
||
handle = load_impl(); | ||
if (handle) | ||
__atomic_store_n(&libpcre2_handle, handle, __ATOMIC_RELEASE); | ||
|
||
__pthread_mutex_unlock(&libpcre2_lock); | ||
|
||
return handle ? 0 : -1; | ||
} | ||
|
||
#endif /* USE_PCRE2_DLSYM */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef LIBSELINUX_REGEX_DLSYM_H | ||
#define LIBSELINUX_REGEX_DLSYM_H | ||
|
||
#ifdef USE_PCRE2 | ||
|
||
#ifdef USE_PCRE2_DLSYM | ||
|
||
#include <stdint.h> | ||
|
||
#include <pcre2.h> | ||
|
||
|
||
int regex_pcre2_load(void); | ||
|
||
#define DLSYM_PROTO(symbol) extern typeof(symbol)* sym_##symbol | ||
DLSYM_PROTO(pcre2_code_free_8); | ||
DLSYM_PROTO(pcre2_compile_8); | ||
DLSYM_PROTO(pcre2_config_8); | ||
DLSYM_PROTO(pcre2_get_error_message_8); | ||
DLSYM_PROTO(pcre2_match_8); | ||
DLSYM_PROTO(pcre2_match_data_create_from_pattern_8); | ||
DLSYM_PROTO(pcre2_match_data_free_8); | ||
DLSYM_PROTO(pcre2_pattern_info_8); | ||
DLSYM_PROTO(pcre2_serialize_decode_8); | ||
DLSYM_PROTO(pcre2_serialize_encode_8); | ||
DLSYM_PROTO(pcre2_serialize_free_8); | ||
DLSYM_PROTO(pcre2_serialize_get_number_of_codes_8); | ||
#undef DLSYM_PROTO | ||
|
||
#undef pcre2_code_free | ||
#define pcre2_code_free sym_pcre2_code_free_8 | ||
#undef pcre2_compile | ||
#define pcre2_compile sym_pcre2_compile_8 | ||
#undef pcre2_config | ||
#define pcre2_config sym_pcre2_config_8 | ||
#undef pcre2_get_error_message | ||
#define pcre2_get_error_message sym_pcre2_get_error_message_8 | ||
#undef pcre2_match | ||
#define pcre2_match sym_pcre2_match_8 | ||
#undef pcre2_match_data_create_from_pattern | ||
#define pcre2_match_data_create_from_pattern sym_pcre2_match_data_create_from_pattern_8 | ||
#undef pcre2_match_data_free | ||
#define pcre2_match_data_free sym_pcre2_match_data_free_8 | ||
#undef pcre2_pattern_info | ||
#define pcre2_pattern_info sym_pcre2_pattern_info_8 | ||
#undef pcre2_serialize_decode | ||
#define pcre2_serialize_decode sym_pcre2_serialize_decode_8 | ||
#undef pcre2_serialize_encode | ||
#define pcre2_serialize_encode sym_pcre2_serialize_encode_8 | ||
#undef pcre2_serialize_free | ||
#define pcre2_serialize_free sym_pcre2_serialize_free_8 | ||
#undef pcre2_serialize_get_number_of_codes | ||
#define pcre2_serialize_get_number_of_codes sym_pcre2_serialize_get_number_of_codes_8 | ||
|
||
#else | ||
|
||
static inline int regex_pcre2_load(void) | ||
{ | ||
return 0; | ||
} | ||
|
||
#endif /* USE_PCRE2_DLSYM */ | ||
|
||
#endif /* USE_PCRE2 */ | ||
#endif /* LIBSELINUX_REGEX_DLSYM_H */ |