Signed-off-by: Alexey Gladkov <gladkov.alexey@xxxxxxxxx> --- elfops.c | 8 +++--- elfops.h | 4 +- elfops_core.c | 8 +++--- modinfo.c | 15 ++++++----- modprobe.c | 2 +- zlibsupport.c | 69 ++++++++++++++++++++++++++++++-------------------------- zlibsupport.h | 17 ++++++++++++- 7 files changed, 71 insertions(+), 52 deletions(-) diff --git a/elfops.c b/elfops.c index 10e80ea..3468265 100644 --- a/elfops.c +++ b/elfops.c @@ -74,11 +74,11 @@ struct elf_file *grab_elf_file(const char *pathname) errno = ENOMEM; goto fail_free_file; } - file->data = grab_file(pathname, &file->len); - if (!file->data) + + if (grab_file(pathname, &file->fdata) < 0) goto fail_free_pathname; - switch (elf_ident(file->data, file->len, &file->conv)) { + switch (elf_ident(file->fdata.data, file->fdata.size, &file->conv)) { case ELFCLASS32: file->ops = &mod_ops32; break; @@ -108,7 +108,7 @@ void release_elf_file(struct elf_file *file) if (!file) return; - release_file(file->data, file->len); + release_file(&file->fdata); free(file->pathname); free(file); diff --git a/elfops.h b/elfops.h index 52c1fd7..fd4b014 100644 --- a/elfops.h +++ b/elfops.h @@ -3,6 +3,7 @@ #include <stdio.h> #include <stdint.h> #include "logging.h" +#include "zlibsupport.h" /* All the icky stuff to do with manipulating 64 and 32-bit modules belongs here. */ @@ -29,8 +30,7 @@ struct elf_file int conv; /* File contents and length. */ - void *data; - unsigned long len; + struct grab_data fdata; }; /* Tables extracted from module by ops->fetch_tables(). */ diff --git a/elfops_core.c b/elfops_core.c index 7150d39..8b8ed77 100644 --- a/elfops_core.c +++ b/elfops_core.c @@ -23,8 +23,8 @@ static void *PERBIT(get_section)(struct elf_file *module, ElfPERBIT(Shdr) **sechdr, unsigned long *secsize) { - void *data = module->data; - unsigned long len = module->len; + void *data = module->fdata.data; + unsigned long len = module->fdata.size; int conv = module->conv; ElfPERBIT(Ehdr) *hdr; @@ -229,7 +229,7 @@ static struct string_table *PERBIT(load_dep_syms)(struct elf_file *module, } num_syms = size / sizeof(syms[0]); - hdr = module->data; + hdr = module->fdata.data; conv = module->conv; if (versions) { versions_size = num_syms; @@ -332,7 +332,7 @@ static void PERBIT(fetch_tables)(struct elf_file *module, ElfPERBIT(Shdr) *sechdrs; int conv; - hdr = module->data; + hdr = module->fdata.data; conv = module->conv; sechdrs = (void *)hdr + END(hdr->e_shoff, conv); diff --git a/modinfo.c b/modinfo.c index 1dd8469..9ae40f2 100644 --- a/modinfo.c +++ b/modinfo.c @@ -189,7 +189,7 @@ static struct elf_file *grab_module(const char *name, const char *basedir) { char *data; - unsigned long size; + struct grab_data fdata; struct utsname buf; char *depname, *p, *moddir; struct elf_file *module; @@ -213,16 +213,17 @@ static struct elf_file *grab_module(const char *name, /* Search for it in modules.dep. */ nofail_asprintf(&depname, "%s/%s", moddir, "modules.dep"); - data = grab_file(depname, &size); - if (!data) { + if (grab_file(depname, &fdata) < 0) { error("modinfo: could not open %s\n", depname); free(depname); return NULL; } free(depname); - for (p = data; p < data + size; p = next_line(p, data + size)) { - if (name_matches(p, data + size, name)) { + data = fdata.data; + + for (p = data; p < data + fdata.size; p = next_line(p, data + fdata.size)) { + if (name_matches(p, data + fdata.size, name)) { int namelen = strcspn(p, ":"); const char *dir; char *filename; @@ -238,7 +239,7 @@ static struct elf_file *grab_module(const char *name, } else { filename = strndup(p, namelen); } - release_file(data, size); + release_file(&fdata); module = grab_elf_file(filename); if (!module) error("modinfo: could not open %s: %s\n", @@ -247,7 +248,7 @@ static struct elf_file *grab_module(const char *name, return module; } } - release_file(data, size); + release_file(&fdata); error("modinfo: could not find module %s\n", name); return NULL; } diff --git a/modprobe.c b/modprobe.c index 5464f45..edf60d6 100644 --- a/modprobe.c +++ b/modprobe.c @@ -1792,7 +1792,7 @@ static int insmod(struct list_head *list, goto out_elf_file; /* request kernel linkage */ - ret = init_module(module->data, module->len, opts); + ret = init_module(module->fdata.data, module->fdata.size, opts); if (ret != 0) { if (errno == EEXIST) { if (flags & mit_first_time) diff --git a/zlibsupport.c b/zlibsupport.c index fc58f16..8936c7f 100644 --- a/zlibsupport.c +++ b/zlibsupport.c @@ -20,81 +20,86 @@ #ifdef CONFIG_USE_ZLIB #include <zlib.h> -static void *grab_contents(gzFile *gzfd, unsigned long *size) +static int grab_contents(gzFile *gzfd, struct grab_data *fdata) { unsigned int max = 16384; - void *buffer = NOFAIL(malloc(max)); int ret; - *size = 0; - while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) { - *size += ret; - if (*size == max) - buffer = NOFAIL(realloc(buffer, max *= 2)); + fdata->data = NOFAIL(malloc(max)); + fdata->size = 0; + + while ((ret = gzread(gzfd, fdata->data + fdata->size, max - fdata->size)) > 0) { + fdata->size += ret; + if (fdata->size == max) + fdata->data = NOFAIL(realloc(fdata->data, max *= 2)); } if (ret < 0) { - free(buffer); - buffer = NULL; + free(fdata->data); + fdata->data = NULL; + return -1; } - return buffer; + return 0; } /* gzopen handles uncompressed files transparently. */ -void *grab_file(const char *filename, unsigned long *size) +int grab_file(const char *filename, struct grab_data *fdata) { gzFile gzfd; - void *buffer; errno = 0; gzfd = gzopen(filename, "rb"); if (!gzfd) { if (errno == ENOMEM) fatal("Memory allocation failure in gzopen\n"); - return NULL; + return -1; + } + if (grab_contents(gzfd, fdata) < 0) { + gzclose(gzfd); + return -1; } - buffer = grab_contents(gzfd, size); + fdata->type = GZIP_FILE; gzclose(gzfd); - return buffer; + return 0; } -void release_file(void *data, unsigned long size) +void release_file(struct grab_data *fdata) { - free(data); + free(fdata->data); } #else /* ... !CONFIG_USE_ZLIB */ -static void *grab_fd(int fd, unsigned long *size) +static void *grab_fd(int fd, struct grab_data *fdata) { struct stat st; - void *map; int ret; ret = fstat(fd, &st); if (ret < 0) - return NULL; - *size = st.st_size; - map = mmap(0, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) - map = NULL; - return map; + return -1; + fdata->size = st.st_size; + fdata->data = mmap(0, fdata->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + if (fdata->data == MAP_FAILED) + fdata->data = NULL; + return 0; } -void *grab_file(const char *filename, unsigned long *size) +int grab_file(const char *filename, struct grab_data *fdata) { int fd; - void *map; fd = open(filename, O_RDONLY, 0); if (fd < 0) - return NULL; - map = grab_fd(fd, size); + return -1; + if (grab_fd(fd, fdata) < 0) + return -1; + fdata->type = PLAIN_FILE; close(fd); - return map; + return 0; } -void release_file(void *data, unsigned long size) +void release_file(struct grab_data *fdata) { - munmap(data, size); + munmap(fdata->data, fdata->size); } #endif diff --git a/zlibsupport.h b/zlibsupport.h index 9ab0703..3eb4c2d 100644 --- a/zlibsupport.h +++ b/zlibsupport.h @@ -1,10 +1,23 @@ #ifndef _ZLIB_SUPPORT_H #define _ZLIB_SUPPORT_H +enum file_type +{ + PLAIN_FILE, + GZIP_FILE +}; + +struct grab_data +{ + enum file_type type; + unsigned long size; + void *data; +}; + /* Grab file. Decompresses if that is supported. Returns NULL on error. */ -extern void *grab_file(const char *filename, unsigned long *size); +extern int grab_file(const char *filename, struct grab_data *fdata); /* Free it up. */ -extern void release_file(void *data, unsigned long size); +extern void release_file(struct grab_data *fdata); #endif /* _ZLIB_SUPPORT_H */ -- 1.7.3.5 -- To unsubscribe from this list: send the line "unsubscribe linux-modules" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html