From a0fb3098ccbc2d19db0d839086137f8fe3868bfd Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Wed, 7 May 2025 18:58:11 +0100 Subject: [PATCH] libkmod: return the errno from kmod_elf_new() Rework the function signature and return the error code instead of the stripped module. Thus we no longer explicitly set errno. Reference: https://github.com/kmod-project/kmod/issues/244 Signed-off-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/346 Signed-off-by: Lucas De Marchi --- libkmod/libkmod-elf.c | 16 +++++++--------- libkmod/libkmod-file.c | 6 +++++- libkmod/libkmod-internal.h | 2 +- testsuite/init_module.c | 6 ++++-- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c index 9b2ceca7..0fc95348 100644 --- a/libkmod/libkmod-elf.c +++ b/libkmod/libkmod-elf.c @@ -305,7 +305,7 @@ static void kmod_elf_save_sections(struct kmod_elf *elf) } } -struct kmod_elf *kmod_elf_new(const void *memory, off_t size) +int kmod_elf_new(const void *memory, off_t size, struct kmod_elf **out_elf) { struct kmod_elf *elf; size_t shdrs_size, shdr_size; @@ -318,15 +318,13 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size) assert_cc(sizeof(uint32_t) == sizeof(Elf64_Word)); elf = malloc(sizeof(struct kmod_elf)); - if (elf == NULL) { - return NULL; - } + if (elf == NULL) + return -ENOMEM; err = elf_identify(elf, memory, size); if (err < 0) { free(elf); - errno = -err; - return NULL; + return err; } elf->memory = memory; @@ -388,12 +386,12 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size) } kmod_elf_save_sections(elf); - return elf; + *out_elf = elf; + return 0; invalid: free(elf); - errno = EINVAL; - return NULL; + return -EINVAL; } void kmod_elf_unref(struct kmod_elf *elf) diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c index 0eeb00a4..23057fa6 100644 --- a/libkmod/libkmod-file.c +++ b/libkmod/libkmod-file.c @@ -71,7 +71,11 @@ struct kmod_elf *kmod_file_get_elf(struct kmod_file *file) return NULL; } - file->elf = kmod_elf_new(file->memory, file->size); + err = kmod_elf_new(file->memory, file->size, &file->elf); + if (err) { + errno = -err; + return NULL; + } return file->elf; } diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index be26e0d2..17e6e5f5 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -152,7 +152,7 @@ struct kmod_modversion { const char *symbol; }; -_nonnull_all_ struct kmod_elf *kmod_elf_new(const void *memory, off_t size); +_must_check_ _nonnull_all_ int kmod_elf_new(const void *memory, off_t size, struct kmod_elf **elf); _nonnull_all_ void kmod_elf_unref(struct kmod_elf *elf); _must_check_ _nonnull_all_ const void *kmod_elf_get_memory(const struct kmod_elf *elf); _must_check_ _nonnull_all_ int kmod_elf_get_modinfo_strings(const struct kmod_elf *elf, char ***array); diff --git a/testsuite/init_module.c b/testsuite/init_module.c index ccb43b0c..35630d89 100644 --- a/testsuite/init_module.c +++ b/testsuite/init_module.c @@ -239,9 +239,11 @@ long init_module(void *mem, unsigned long len, const char *args) return -1; } - elf = kmod_elf_new(mem, len); - if (elf == NULL) + err = kmod_elf_new(mem, len, &elf); + if (err < 0) { + errno = -err; return -1; + } err = kmod_elf_get_section(elf, ".gnu.linkonce.this_module", &off, &bufsize); buf = (const char *)kmod_elf_get_memory(elf) + off; -- 2.47.2