Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Feb 2018 22:40:33 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r329247 - stable/11/usr.sbin/kldxref
Message-ID:  <201802132240.w1DMeX2m051789@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802132240.w1DMeX2m051789>