From: Lucas De Marchi Date: Sat, 30 Nov 2024 06:38:11 +0000 (-0600) Subject: libkmod/zlib: Allow to load libz.so on demand X-Git-Tag: v34~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8f00f7bc527fa38a9ed6f652ec01a8eef85dc88;p=thirdparty%2Fkmod.git libkmod/zlib: Allow to load libz.so on demand Use dlfcn helpers to load libz once it's needed. Signed-off-by: Lucas De Marchi Reviewed-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/262 --- diff --git a/libkmod/libkmod-file-zlib.c b/libkmod/libkmod-file-zlib.c index a7e27b80..fd382939 100644 --- a/libkmod/libkmod-file-zlib.c +++ b/libkmod/libkmod-file-zlib.c @@ -3,6 +3,9 @@ * Copyright © 2024 Intel Corporation */ +/* TODO: replace with build system define once supported */ +#define DLSYM_LOCALLY_ENABLED 0 + #include #include #include @@ -20,6 +23,24 @@ #define READ_STEP (4 * 1024 * 1024) +#define DL_SYMBOL_TABLE(M) \ + M(gzclose) \ + M(gzdopen) \ + M(gzerror) \ + M(gzread) + +DL_SYMBOL_TABLE(DECLARE_SYM) + +static int dlopen_zlib(void) +{ + static void *dl = NULL; + + if (!DLSYM_LOCALLY_ENABLED) + return 0; + + return dlsym_many(&dl, "libz.so.1", DL_SYMBOL_TABLE(DLSYM_ARG) NULL); +} + int kmod_file_load_zlib(struct kmod_file *file) { _cleanup_free_ unsigned char *p = NULL; @@ -28,12 +49,19 @@ int kmod_file_load_zlib(struct kmod_file *file) gzFile gzf; int gzfd; + ret = dlopen_zlib(); + if (ret < 0) { + ERR(file->ctx, "zlib: can't load and resolve symbols (%s)", + strerror(-ret)); + return -EINVAL; + } + errno = 0; gzfd = fcntl(file->fd, F_DUPFD_CLOEXEC, 3); if (gzfd < 0) return -errno; - gzf = gzdopen(gzfd, "rb"); /* takes ownership of the fd */ + gzf = sym_gzdopen(gzfd, "rb"); /* takes ownership of the fd */ if (gzf == NULL) { close(gzfd); return -errno; @@ -52,12 +80,12 @@ int kmod_file_load_zlib(struct kmod_file *file) p = tmp; } - r = gzread(gzf, p + did, total - did); + r = sym_gzread(gzf, p + did, total - did); if (r == 0) break; else if (r < 0) { int gzerr; - const char *gz_errmsg = gzerror(gzf, &gzerr); + const char *gz_errmsg = sym_gzerror(gzf, &gzerr); ERR(file->ctx, "gzip: %s\n", gz_errmsg); @@ -70,11 +98,11 @@ int kmod_file_load_zlib(struct kmod_file *file) file->memory = TAKE_PTR(p); file->size = did; - gzclose(gzf); + sym_gzclose(gzf); return 0; error: - gzclose(gzf); /* closes the gzfd */ + sym_gzclose(gzf); return ret; }