[FreeBSD-Announce] FreeBSD Security Advisory FreeBSD-SA-18:12.elf

Konstantin Belousov kostikbel at gmail.com
Mon Oct 8 11:20:45 UTC 2018


On Mon, Oct 08, 2018 at 12:04:29PM +0200, Dag-Erling Smørgrav wrote:
> Konstantin Belousov <kostikbel at gmail.com> writes:
> > Dag-Erling Smørgrav <des at des.no> writes:
> > > The string isn't just unterminated, though.  It's actually longer than
> > > the section.  To be precise, "/lib/ld-linux.so.2" is 18 characters long,
> > > plus NUL makes 19.  The section is supposed to be 17 bytes long.  I
> > > don't mind forgiving a missing NUL, but I'm not comfortable with reading
> > > past the end of the section, and it worries me that Linux doesn't care.
> > Apparently it was not Linux.  Look at the astro/google-earth/Makefile
> > before r425359.
> 
> Ah, I see.  The port used sed to edit the file in-place instead of using
> a tool that understands Elf and would have adjusted the section length.
Really this cannot be done, as well as overriding the interpreter name
with the longer string, since other segments are not movable.

> But it doesn't any more, probably because the linux_base ports install
> ld-lsb.so.3, so what's the issue?  And regardless, your patch wouldn't
> have helped in this case, since it would only have copied the first 17
> characters ("/lib/ld-linux.so.", missing the final 2) to the new buffer.
> So what is the rationale for the patch?
The mailed patch was based on some mis-calculations on my part,
I did off-by-one twice apparently.

Below is the the latest version which I did before I discovered the ports'
Makefile hack.  After I did, I abandoned the intent to commit it.

diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index f4302d46665..1ef6028005e 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -872,9 +872,26 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
 				interp = __DECONST(char *, imgp->image_header) +
 				    phdr[i].p_offset;
 				if (interp[interp_name_len - 1] != '\0') {
-					uprintf("Invalid PT_INTERP\n");
-					error = ENOEXEC;
-					goto ret;
+					/*
+					 * ELF specification requires
+					 * that PT_INTERP contained
+					 * NUL-terminated string.  If
+					 * it is not, try to find the
+					 * end of line and still
+					 * execute the binary.
+					 */
+					for (; interp_name_len <=
+					    PAGE_SIZE - phdr[i].p_offset &&
+					    interp[interp_name_len - 1] != '\0';
+					    interp_name_len++)
+						;
+					if (interp[interp_name_len - 1] !=
+					    '\0') {
+						uprintf("Invalid PT_INTERP: "
+						    "no NUL termination\n");
+						error = ENOEXEC;
+						goto ret;
+					}
 				}
 			}
 			break;


More information about the freebsd-security mailing list