svn commit: r329247 - stable/11/usr.sbin/kldxref
Ed Maste
emaste at FreeBSD.org
Tue Feb 13 22:40:34 UTC 2018
Author: emaste
Date: Tue Feb 13 22:40:33 2018
New Revision: 329247
URL: https://svnweb.freebsd.org/changeset/base/329247
Log:
MFC r328052: kldxref: handle modules with md_cval at end of allocated secs
Attempting to retrieve an md_cval string from a kernel module with
kldxref would throw a offset error for modules created using lld, since
this value would be placed at the end of all allocated sections.
Add an ef_read_seg_string method to the ef interface, to allow reading
strings of varying size without attempting to read beyond the segment's
bounds.
PR: 224875
Submitted by: Mitchell Horne <mhorne063 at gmail.com>
Sponsored by: The FreeBSD Foundation
Modified:
stable/11/usr.sbin/kldxref/ef.c
stable/11/usr.sbin/kldxref/ef.h
stable/11/usr.sbin/kldxref/ef_obj.c
stable/11/usr.sbin/kldxref/kldxref.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/usr.sbin/kldxref/ef.c
==============================================================================
--- stable/11/usr.sbin/kldxref/ef.c Tue Feb 13 22:37:54 2018 (r329246)
+++ stable/11/usr.sbin/kldxref/ef.c Tue Feb 13 22:40:33 2018 (r329247)
@@ -88,6 +88,8 @@ static int ef_read_entry(elf_file_t ef, Elf_Off offset
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,
@@ -104,6 +106,7 @@ static struct elf_file_ops ef_file_ops = {
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,
@@ -492,6 +495,28 @@ ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t
if (error != 0)
return (error);
}
+ 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 || ofs == (Elf_Off)-1) {
+ if (ef->ef_verbose)
+ warnx("ef_seg_read_string(%s): bad offset (%lx:%ld)",
+ ef->ef_name, (long)offset, ofs);
+ return (EFAULT);
+ }
+
+ r = pread(ef->ef_fd, dest, len, ofs);
+ if (r < 0)
+ return (errno);
+ if (strnlen(dest, len) == len)
+ return (EFAULT);
+
return (0);
}
Modified: stable/11/usr.sbin/kldxref/ef.h
==============================================================================
--- stable/11/usr.sbin/kldxref/ef.h Tue Feb 13 22:37:54 2018 (r329246)
+++ stable/11/usr.sbin/kldxref/ef.h Tue Feb 13 22:40:33 2018 (r329247)
@@ -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 @@ struct elf_file_ops {
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,
Modified: stable/11/usr.sbin/kldxref/ef_obj.c
==============================================================================
--- stable/11/usr.sbin/kldxref/ef_obj.c Tue Feb 13 22:37:54 2018 (r329246)
+++ stable/11/usr.sbin/kldxref/ef_obj.c Tue Feb 13 22:40:33 2018 (r329247)
@@ -108,6 +108,8 @@ static int ef_obj_seg_read(elf_file_t ef, Elf_Off offs
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,
@@ -124,6 +126,7 @@ static struct elf_file_ops ef_obj_file_ops = {
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,
@@ -293,6 +296,27 @@ ef_obj_seg_read_rel(elf_file_t ef, Elf_Off offset, siz
return (error);
}
}
+ 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);
}
Modified: stable/11/usr.sbin/kldxref/kldxref.c
==============================================================================
--- stable/11/usr.sbin/kldxref/kldxref.c Tue Feb 13 22:37:54 2018 (r329246)
+++ stable/11/usr.sbin/kldxref/kldxref.c Tue Feb 13 22:40:33 2018 (r329247)
@@ -569,9 +569,8 @@ read_kld(char *filename, char *kldname)
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)
More information about the svn-src-stable-11
mailing list