Index: usr.sbin/kldxref/ef.h =================================================================== --- usr.sbin/kldxref/ef.h +++ usr.sbin/kldxref/ef.h @@ -21,6 +21,8 @@ (ef)->ef_ops->seg_read((ef)->ef_ef, offset, len, dest) #define EF_SEG_READ_REL(ef, offset, len, dest) \ (ef)->ef_ops->seg_read_rel((ef)->ef_ef, offset, len, dest) +#define EF_SEG_READ_STRING(ef, offset, len, dest) \ + (ef)->ef_ops->seg_read_string((ef)->ef_ef, offset, len, dest) #define EF_SEG_READ_ENTRY(ef, offset, len, ptr) \ (ef)->ef_ops->seg_read_entry((ef)->kf_ef, offset, len, ptr) #define EF_SEG_READ_ENTRY_REL(ef, offset, len, ptr) \ @@ -44,6 +46,8 @@ int (*seg_read)(elf_file_t ef, Elf_Off offset, size_t len, void *dest); int (*seg_read_rel)(elf_file_t ef, Elf_Off offset, size_t len, void *dest); + int (*seg_read_string)(elf_file_t, Elf_Off offset, size_t len, + char *dest); int (*seg_read_entry)(elf_file_t ef, Elf_Off offset, size_t len, void**ptr); int (*seg_read_entry_rel)(elf_file_t ef, Elf_Off offset, size_t len, Index: usr.sbin/kldxref/ef.c =================================================================== --- usr.sbin/kldxref/ef.c +++ usr.sbin/kldxref/ef.c @@ -90,6 +90,8 @@ static int ef_seg_read(elf_file_t ef, Elf_Off offset, size_t len, void *dest); static int ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len, void *dest); +static int ef_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, + char *dest); static int ef_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void **ptr); static int ef_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len, @@ -106,6 +108,7 @@ ef_read_entry, ef_seg_read, ef_seg_read_rel, + ef_seg_read_string, ef_seg_read_entry, ef_seg_read_entry_rel, ef_symaddr, @@ -497,6 +500,33 @@ return (0); } +static int +ef_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, char *dest) +{ + u_long ofs = ef_get_offset(ef, offset); + ssize_t r; + + if (ofs == 0) { + if (ef->ef_verbose) + warnx("ef_seg_read_string(%s): zero offset (%lx:%ld)", + ef->ef_name, (long)offset, ofs); + return EFAULT; + } + + if (ofs != (Elf_Off)-1) { + if (lseek(ef->ef_fd, ofs, SEEK_SET) == -1) + return EIO; + } + + r = read(ef->ef_fd, dest, len); + if (r < 0) + return EIO; + if (strnlen(dest, len) == len) + return EFAULT; + + return (0); +} + static int ef_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void**ptr) { Index: usr.sbin/kldxref/ef_obj.c =================================================================== --- usr.sbin/kldxref/ef_obj.c +++ usr.sbin/kldxref/ef_obj.c @@ -110,6 +110,8 @@ void *dest); static int ef_obj_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len, void *dest); +static int ef_obj_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, + char *dest); static int ef_obj_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void **ptr); static int ef_obj_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len, @@ -126,6 +128,7 @@ ef_obj_read_entry, ef_obj_seg_read, ef_obj_seg_read_rel, + ef_obj_seg_read_string, ef_obj_seg_read_entry, ef_obj_seg_read_entry_rel, ef_obj_symaddr, @@ -298,6 +301,27 @@ return (0); } +static int +ef_obj_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, char *dest) +{ + + if (offset >= ef->size) { + if (ef->ef_verbose) + warnx("ef_obj_seg_read_string(%s): bad offset (%lx)", + ef->ef_name, (long)offset); + return (EFAULT); + } + + if (ef->size - offset < len) + len = ef->size - offset; + + if (strnlen(ef->address + offset, len) == len) + return (EFAULT); + + memcpy(dest, ef->address + offset, len); + return (0); +} + static int ef_obj_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void **ptr) { Index: usr.sbin/kldxref/kldxref.c =================================================================== --- usr.sbin/kldxref/kldxref.c +++ usr.sbin/kldxref/kldxref.c @@ -571,9 +571,8 @@ check(EF_SEG_READ_REL(&ef, (Elf_Off)*p, sizeof(md), &md)); p++; - check(EF_SEG_READ(&ef, (Elf_Off)md.md_cval, + check(EF_SEG_READ_STRING(&ef, (Elf_Off)md.md_cval, sizeof(cval), cval)); - cval[MAXMODNAME] = '\0'; parse_entry(&md, cval, &ef, kldname); } if (error)