summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/elf-util.c4
-rw-r--r--src/shared/elf-util.h3
-rw-r--r--src/shared/meson.build2
-rw-r--r--src/shared/pcre2-dlopen.c44
-rw-r--r--src/shared/pcre2-dlopen.h18
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);