diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/elf-util.c | 4 | ||||
-rw-r--r-- | src/shared/elf-util.h | 3 | ||||
-rw-r--r-- | src/shared/meson.build | 2 | ||||
-rw-r--r-- | src/shared/pcre2-dlopen.c | 44 | ||||
-rw-r--r-- | src/shared/pcre2-dlopen.h | 18 |
5 files changed, 69 insertions, 2 deletions
diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index 8cb4a99298..cc0fce56d9 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -80,7 +80,7 @@ unsigned int (*sym_elf_version)(unsigned int); GElf_Phdr *(*sym_gelf_getphdr)(Elf *, int, GElf_Phdr *); size_t (*sym_gelf_getnote)(Elf_Data *, size_t, GElf_Nhdr *, size_t *, size_t *); -static int dlopen_dw(void) { +int dlopen_dw(void) { int r; r = dlopen_many_sym_or_warn( @@ -123,7 +123,7 @@ static int dlopen_dw(void) { return 1; } -static int dlopen_elf(void) { +int dlopen_elf(void) { int r; r = dlopen_many_sym_or_warn( diff --git a/src/shared/elf-util.h b/src/shared/elf-util.h index cf3d9be128..b28e64cea6 100644 --- a/src/shared/elf-util.h +++ b/src/shared/elf-util.h @@ -4,6 +4,9 @@ #include "json.h" #if HAVE_ELFUTILS +int dlopen_dw(void); +int dlopen_elf(void); + /* Parse an ELF object in a forked process, so that errors while iterating over * untrusted and potentially malicious data do not propagate to the main caller's process. * If fork_disable_dump, the child process will not dump core if it crashes. */ diff --git a/src/shared/meson.build b/src/shared/meson.build index 66715e00c3..dfa025deec 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -243,6 +243,8 @@ shared_sources = files(''' parse-argument.h parse-socket-bind-item.c parse-socket-bind-item.h + pcre2-dlopen.c + pcre2-dlopen.h pe-header.h pkcs11-util.c pkcs11-util.h diff --git a/src/shared/pcre2-dlopen.c b/src/shared/pcre2-dlopen.c new file mode 100644 index 0000000000..475d7eb26d --- /dev/null +++ b/src/shared/pcre2-dlopen.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "dlfcn-util.h" +#include "log.h" +#include "pcre2-dlopen.h" + +#if HAVE_PCRE2 +static void *pcre2_dl = NULL; + +pcre2_match_data* (*sym_pcre2_match_data_create)(uint32_t, pcre2_general_context *); +void (*sym_pcre2_match_data_free)(pcre2_match_data *); +void (*sym_pcre2_code_free)(pcre2_code *); +pcre2_code* (*sym_pcre2_compile)(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, pcre2_compile_context *); +int (*sym_pcre2_get_error_message)(int, PCRE2_UCHAR *, PCRE2_SIZE); +int (*sym_pcre2_match)(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, pcre2_match_data *, pcre2_match_context *); +PCRE2_SIZE* (*sym_pcre2_get_ovector_pointer)(pcre2_match_data *); + +int dlopen_pcre2(void) { + /* So here's something weird: PCRE2 actually renames the symbols exported by the library via C + * macros, so that the exported symbols carry a suffix "_8" but when used from C the suffix is + * gone. In the argument list below we ignore this mangling. Surprisingly (at least to me), we + * actually get away with that. That's because DLSYM_ARG() useses STRINGIFY() to generate a string + * version of the symbol name, and that resolves the macro mapping implicitly already, so that the + * string actually contains the "_8" suffix already due to that and we don't have to append it + * manually anymore. C is weird. 🤯 */ + + return dlopen_many_sym_or_warn( + &pcre2_dl, "libpcre2-8.so.0", LOG_ERR, + DLSYM_ARG(pcre2_match_data_create), + DLSYM_ARG(pcre2_match_data_free), + DLSYM_ARG(pcre2_code_free), + DLSYM_ARG(pcre2_compile), + DLSYM_ARG(pcre2_get_error_message), + DLSYM_ARG(pcre2_match), + DLSYM_ARG(pcre2_get_ovector_pointer)); +} + +#else + +int dlopen_pcre2(void) { + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "PCRE2 support is not compiled in."); +} +#endif diff --git a/src/shared/pcre2-dlopen.h b/src/shared/pcre2-dlopen.h new file mode 100644 index 0000000000..1306334144 --- /dev/null +++ b/src/shared/pcre2-dlopen.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#if HAVE_PCRE2 + +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> + +extern pcre2_match_data* (*sym_pcre2_match_data_create)(uint32_t, pcre2_general_context *); +extern void (*sym_pcre2_match_data_free)(pcre2_match_data *); +extern void (*sym_pcre2_code_free)(pcre2_code *); +extern pcre2_code* (*sym_pcre2_compile)(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, pcre2_compile_context *); +extern int (*sym_pcre2_get_error_message)(int, PCRE2_UCHAR *, PCRE2_SIZE); +extern int (*sym_pcre2_match)(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, pcre2_match_data *, pcre2_match_context *); +extern PCRE2_SIZE* (*sym_pcre2_get_ovector_pointer)(pcre2_match_data *); +#endif + +int dlopen_pcre2(void); |