Subject: kern/18334: argc = 0 causes rtld null pointer deref
To: None <gnats-bugs@gnats.netbsd.org>
From: None <xs@kittenz.org>
List: netbsd-bugs
Date: 09/19/2002 10:58:14
>Number:         18334
>Category:       kern
>Synopsis:       argc = 0 causes rtld null pointer deref
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Sep 19 03:01:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD 1.6F
>Organization:
>Environment:
System: NetBSD stasis 1.6F NetBSD 1.6F (STASIS) #6: Fri Sep 13 17:07:18 BST 2002 xs@stasis:/usr/src/sys/arch/i386/compile/STASIS i386
Architecture: i386
Machine: i386

/usr/src/libexec/ld.elf_so/rtld.c:
     $NetBSD: rtld.c,v 1.52 2002/08/09 10:03:08 soren Exp $

/sys/kern/kern_exec.c:
     $NetBSD: kern_exec.c,v 1.152 2002/04/23 15:11:25 christos Exp $
>Description:

The kernel does not enforce the following part of the execve(2) man page: 

     The argument argv is a pointer to a null-terminated array of character
     pointers to null-terminated character strings.  These strings construct
     the argument list to be made available to the new process.	 At least one
                                                                 ^^^^^^^^^^^^
     argument must be present in the array; by custom, the first element
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     should be the name of the executed program (for example, the last compo-
     nent of path).

hence any dynamically linked program can be segfaulted because the rtld
assumes argv[0] is a valid address in rtld() where it invokes strrchr
on argv[0] to determine a value for __progname. Other code in rtld()
explicitly permits a NULL argv[0] though..

>How-To-Repeat:
$ cat rtld-core.c
#include <unistd.h>

int
main(int argc, char *argv[])
{
	char *args[] = { NULL };

	execv(argv[1], args);
	return 1;
}

$ make rtld-core
$ export LD_DEBUG=1; ./rtld-core ./rtld-core
...
relocating objects
doing copy relocations
Segmentation fault (core dumped)

>Fix:
Force argc to be at least 1 in sys_execve() and/or make rtld() deal
with argc == 0 correctly.

Index: kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.152
diff -u -r1.152 kern_exec.c
--- kern_exec.c	2002/04/23 15:11:25	1.152
+++ kern_exec.c	2002/09/13 16:18:23
@@ -434,6 +434,10 @@
 		cpp++;
 		argc++;
 	}
+	if (argc < 1) {
+		error = EINVAL;
+		goto bad;
+	}
 
 	envc = 0;
 	/* environment need not be there */

>Release-Note:
>Audit-Trail:
>Unformatted: