From nobody@FreeBSD.org  Sun Mar  6 19:56:55 2011
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id EE5BB106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  6 Mar 2011 19:56:55 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id C2DE68FC14
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  6 Mar 2011 19:56:55 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p26JutdV064888
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 6 Mar 2011 19:56:55 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id p26JutYe064887;
	Sun, 6 Mar 2011 19:56:55 GMT
	(envelope-from nobody)
Message-Id: <201103061956.p26JutYe064887@red.freebsd.org>
Date: Sun, 6 Mar 2011 19:56:55 GMT
From: "Devon H. O'Dell" <devon.odell@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: imgact_shell integer underflow when argv[0] is longer than interp + path
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         155321
>Category:       kern
>Synopsis:       imgact_shell integer underflow when argv[0] is longer than interp + path
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Mar 06 20:00:18 UTC 2011
>Closed-Date:    Sun Mar 13 10:09:01 UTC 2011
>Last-Modified:  Sun Mar 13 10:10:10 UTC 2011
>Originator:     Devon H. O'Dell
>Release:        8-STABLE
>Organization:
>Environment:
FreeBSD bigdisk.dho.apt 8.2-STABLE FreeBSD 8.2-STABLE #8: Sun Mar  6 14:20:26 EST 2011     root@bigdisk.dho.apt:/usr/src/sys/amd64/compile/BIGDISK  amd64

>Description:
In debugging a problem with Go calling execve(2), it appears that the actual bug is in the FreeBSD kernel implementation in imgact_shell. Specifically, it is entirely valid for argv[0] to be longer than the length of the path (treated as "fname" in this function). We have a workaround in Go, but this should be fixed in the kernel.
>How-To-Repeat:
Russ Cox wrote a quick to demonstrate the issue:

$ cat execve.c
#include <unistd.h>
#include <stdio.h>

int
main(int argc, char **argv, char **environ)
{
       execve(argv[1], argv+2, environ);
       perror("execve");
       return 1;
}
$ cat shellscript
#!/bin/echo
$ gcc execve.c
$ cp /bin/ls .
$ ./a.out ls /bogus/ls
a.out           execve.c        ls              shellscript
$ ./a.out shellscript asdf
shellscript
$ ./a.out shellscript /bogus/shellscript
shellscript
$ ./a.out shellscript /bin/echo-shellscript
shellscript
$ ./a.out shellscript /bin/echo-shellscript1
execve: Argument list too long

>Fix:
Patch attached.

Patch attached with submission follows:

Index: sys/kern/imgact_shell.c
===================================================================
--- sys/kern/imgact_shell.c	(revision 219345)
+++ sys/kern/imgact_shell.c	(working copy)
@@ -195,16 +195,19 @@
 	length = (imgp->args->argc == 0) ? 0 :
 	    strlen(imgp->args->begin_argv) + 1;		/* bytes to delete */
 
-	if (offset - length > imgp->args->stringspace) {
-		if (sname != NULL)
-			sbuf_delete(sname);
-		return (E2BIG);
+	if (offset >= length) {
+		if (offset - length > imgp->args->stringspace) {
+			if (sname != NULL)
+				sbuf_delete(sname);
+			return (E2BIG);
+		}
+
+		bcopy(imgp->args->begin_argv + length, imgp->args->begin_argv + offset,
+		    imgp->args->endp - (imgp->args->begin_argv + length));
+
+		offset -= length;		/* calculate actual adjustment */
 	}
 
-	bcopy(imgp->args->begin_argv + length, imgp->args->begin_argv + offset,
-	    imgp->args->endp - (imgp->args->begin_argv + length));
-
-	offset -= length;		/* calculate actual adjustment */
 	imgp->args->begin_envv += offset;
 	imgp->args->endp += offset;
 	imgp->args->stringspace -= offset;


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->kib 
Responsible-Changed-By: kib 
Responsible-Changed-When: Sun Mar 6 21:02:05 UTC 2011 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=155321 

From: "Devon H. O'Dell" <devon.odell@gmail.com>
To: FreeBSD-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org
Cc:  
Subject: Re: kern/155321: imgact_shell integer underflow when argv[0] is
 longer than interp + path
Date: Sun, 6 Mar 2011 16:14:03 -0500

 --001636c5a9edd929c2049dd6dbdb
 Content-Type: text/plain; charset=ISO-8859-1
 
 Actually, kib@ points out that this isn't quite correct; the correct
 fix should indeed be a 1-liner, attached.
 
 --dho
 
 --001636c5a9edd929c2049dd6dbdb
 Content-Type: text/plain; charset=US-ASCII; name="imgact_shell.txt"
 Content-Disposition: attachment; filename="imgact_shell.txt"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_gkygm51u0
 
 SW5kZXg6IHN5cy9rZXJuL2ltZ2FjdF9zaGVsbC5jCj09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIHN5cy9rZXJuL2lt
 Z2FjdF9zaGVsbC5jCShyZXZpc2lvbiAyMTkzNDUpCisrKyBzeXMva2Vybi9pbWdhY3Rfc2hlbGwu
 Ywkod29ya2luZyBjb3B5KQpAQCAtMTk1LDcgKzE5NSw3IEBACiAJbGVuZ3RoID0gKGltZ3AtPmFy
 Z3MtPmFyZ2MgPT0gMCkgPyAwIDoKIAkgICAgc3RybGVuKGltZ3AtPmFyZ3MtPmJlZ2luX2FyZ3Yp
 ICsgMTsJCS8qIGJ5dGVzIHRvIGRlbGV0ZSAqLwogCi0JaWYgKG9mZnNldCAtIGxlbmd0aCA+IGlt
 Z3AtPmFyZ3MtPnN0cmluZ3NwYWNlKSB7CisJaWYgKG9mZnNldCA+IGxlbmd0aCAmJiBvZmZzZXQg
 LSBsZW5ndGggPiBpbWdwLT5hcmdzLT5zdHJpbmdzcGFjZSkgewogCQlpZiAoc25hbWUgIT0gTlVM
 TCkKIAkJCXNidWZfZGVsZXRlKHNuYW1lKTsKIAkJcmV0dXJuIChFMkJJRyk7Cg==
 --001636c5a9edd929c2049dd6dbdb--

From: "Devon H. O'Dell" <devon.odell@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/155321: imgact_shell integer underflow when argv[0] is
 longer than interp + path
Date: Sun, 6 Mar 2011 16:19:05 -0500

 --001636426603d57a0f049dd6ed7e
 Content-Type: text/plain; charset=ISO-8859-1
 
 Actually, kib@ points out that this isn't quite correct; the correct
 fix should indeed be a 1-liner, attached.
 
 --dho
 
 --001636426603d57a0f049dd6ed7e
 Content-Type: text/plain; charset=US-ASCII; name="imgact_shell.txt"
 Content-Disposition: attachment; filename="imgact_shell.txt"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_gkygsf3g1
 
 SW5kZXg6IHN5cy9rZXJuL2ltZ2FjdF9zaGVsbC5jCj09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIHN5cy9rZXJuL2lt
 Z2FjdF9zaGVsbC5jCShyZXZpc2lvbiAyMTkzNDUpCisrKyBzeXMva2Vybi9pbWdhY3Rfc2hlbGwu
 Ywkod29ya2luZyBjb3B5KQpAQCAtMTk1LDcgKzE5NSw3IEBACiAJbGVuZ3RoID0gKGltZ3AtPmFy
 Z3MtPmFyZ2MgPT0gMCkgPyAwIDoKIAkgICAgc3RybGVuKGltZ3AtPmFyZ3MtPmJlZ2luX2FyZ3Yp
 ICsgMTsJCS8qIGJ5dGVzIHRvIGRlbGV0ZSAqLwogCi0JaWYgKG9mZnNldCAtIGxlbmd0aCA+IGlt
 Z3AtPmFyZ3MtPnN0cmluZ3NwYWNlKSB7CisJaWYgKG9mZnNldCA+IGxlbmd0aCAmJiBvZmZzZXQg
 LSBsZW5ndGggPiBpbWdwLT5hcmdzLT5zdHJpbmdzcGFjZSkgewogCQlpZiAoc25hbWUgIT0gTlVM
 TCkKIAkJCXNidWZfZGVsZXRlKHNuYW1lKTsKIAkJcmV0dXJuIChFMkJJRyk7Cg==
 --001636426603d57a0f049dd6ed7e--

From: "Devon H. O'Dell" <devon.odell@gmail.com>
To: Oliver Pinter <oliver.pntr@gmail.com>
Cc: FreeBSD-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org
Subject: Re: kern/155321: imgact_shell integer underflow when argv[0] is
 longer than interp + path
Date: Sun, 6 Mar 2011 17:57:05 -0500

 Yeah, this has been a bug for quite some time.
 
 --dho
 
 2011/3/6 Oliver Pinter <oliver.pntr@gmail.com>:
 > under 7.4 exist too this problem
 >
 > XXX@XXX test> gcc execve.c
 > XXX@XXX test> cp /bin/ls .
 > XXX@XXX test> ./a.out ls /tmp/test/ls
 > a.out =A0 =A0 =A0 =A0 =A0 execve.c =A0 =A0 =A0 =A0ls =A0 =A0 =A0 =A0 =A0 =
 =A0 =A0shellscript
 > XXX@XXX test> ./a.out shellscript asdf
 > shellscript
 > XXX@XXX test> ./a.out shellscript /tmp/test/
 > a.out* =A0 =A0 =A0 execve.c =A0 =A0 ls* =A0 =A0 =A0 =A0 =A0shellscript*
 > XXX@XXX test> ./a.out shellscript /tmp/test/ls
 > shellscript
 > XXX@XXX test> ./a.out shellscript /tmp/test/shellscript
 > shellscript
 > XXX@XXX test> ./a.out shellscript /bin/echo-shellscript
 > shellscript
 > XXX@XXX test> ./a.out shellscript /bin/echo-shellscript1
 > execve: Argument list too long
 > XXX@XXX test> uname -a
 > FreeBSD XXX 7.4-STABLE FreeBSD 7.4-STABLE #71 r219301+472ccf9: Sun Mar
 > =A06 19:16:46 CET 2011 =A0 =A0 XXX@XXX:/usr/obj/usr/src/sys/stable =A0amd=
 64
 >
 >
 > On 3/6/11, Devon H. O'Dell <devon.odell@gmail.com> wrote:
 >> Actually, kib@ points out that this isn't quite correct; the correct
 >> fix should indeed be a 1-liner, attached.
 >>
 >> --dho
 >>
 >

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/155321: commit references a PR
Date: Sun,  6 Mar 2011 22:59:42 +0000 (UTC)

 Author: kib
 Date: Sun Mar  6 22:59:30 2011
 New Revision: 219352
 URL: http://svn.freebsd.org/changeset/base/219352
 
 Log:
   The execution of the shebang script requires putting interpreter path,
   possible option and script path in the place of argv[0] supplied to
   execve(2).  It is possible and valid for the substitution to be shorter
   then the argv[0].
   
   Avoid signed underflow in this case.
   
   Submitted by:	Devon H. O'Dell <devon.odell gmail com>
   PR:	kern/155321
   MFC after:	1 week
 
 Modified:
   head/sys/kern/imgact_shell.c
 
 Modified: head/sys/kern/imgact_shell.c
 ==============================================================================
 --- head/sys/kern/imgact_shell.c	Sun Mar  6 22:56:14 2011	(r219351)
 +++ head/sys/kern/imgact_shell.c	Sun Mar  6 22:59:30 2011	(r219352)
 @@ -195,7 +195,7 @@ exec_shell_imgact(imgp)
  	length = (imgp->args->argc == 0) ? 0 :
  	    strlen(imgp->args->begin_argv) + 1;		/* bytes to delete */
  
 -	if (offset - length > imgp->args->stringspace) {
 +	if (offset > imgp->args->stringspace + length) {
  		if (sname != NULL)
  			sbuf_delete(sname);
  		return (E2BIG);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: Oliver Pinter <oliver.pntr@gmail.com>
To: "Devon H. O'Dell" <devon.odell@gmail.com>
Cc: FreeBSD-gnats-submit@freebsd.org, freebsd-bugs@freebsd.org
Subject: Re: kern/155321: imgact_shell integer underflow when argv[0] is
 longer than interp + path
Date: Sun, 6 Mar 2011 23:54:51 +0100

 under 7.4 exist too this problem
 
 XXX@XXX test> gcc execve.c
 XXX@XXX test> cp /bin/ls .
 XXX@XXX test> ./a.out ls /tmp/test/ls
 a.out           execve.c        ls              shellscript
 XXX@XXX test> ./a.out shellscript asdf
 shellscript
 XXX@XXX test> ./a.out shellscript /tmp/test/
 a.out*       execve.c     ls*          shellscript*
 XXX@XXX test> ./a.out shellscript /tmp/test/ls
 shellscript
 XXX@XXX test> ./a.out shellscript /tmp/test/shellscript
 shellscript
 XXX@XXX test> ./a.out shellscript /bin/echo-shellscript
 shellscript
 XXX@XXX test> ./a.out shellscript /bin/echo-shellscript1
 execve: Argument list too long
 XXX@XXX test> uname -a
 FreeBSD XXX 7.4-STABLE FreeBSD 7.4-STABLE #71 r219301+472ccf9: Sun Mar
  6 19:16:46 CET 2011     XXX@XXX:/usr/obj/usr/src/sys/stable  amd64
 
 
 On 3/6/11, Devon H. O'Dell <devon.odell@gmail.com> wrote:
 > Actually, kib@ points out that this isn't quite correct; the correct
 > fix should indeed be a 1-liner, attached.
 >
 > --dho
 >
State-Changed-From-To: open->patched 
State-Changed-By: linimon 
State-Changed-When: Mon Mar 7 05:02:32 UTC 2011 
State-Changed-Why:  
set as MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=155321 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/155321: commit references a PR
Date: Sun, 13 Mar 2011 09:37:08 +0000 (UTC)

 Author: kib
 Date: Sun Mar 13 09:36:52 2011
 New Revision: 219594
 URL: http://svn.freebsd.org/changeset/base/219594
 
 Log:
   MFC r219352:
   The execution of the shebang script requires putting interpreter path,
   possible option and script path in the place of argv[0] supplied to
   execve(2).  It is possible and valid for the substitution to be shorter
   then the argv[0].
   
   Avoid signed underflow in this case.
   
   PR:     kern/155321
 
 Modified:
   stable/8/sys/kern/imgact_shell.c
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
 
 Modified: stable/8/sys/kern/imgact_shell.c
 ==============================================================================
 --- stable/8/sys/kern/imgact_shell.c	Sun Mar 13 08:59:46 2011	(r219593)
 +++ stable/8/sys/kern/imgact_shell.c	Sun Mar 13 09:36:52 2011	(r219594)
 @@ -191,7 +191,7 @@ exec_shell_imgact(imgp)
  	length = (imgp->args->argc == 0) ? 0 :
  	    strlen(imgp->args->begin_argv) + 1;		/* bytes to delete */
  
 -	if (offset - length > imgp->args->stringspace) {
 +	if (offset > imgp->args->stringspace + length) {
  		if (sname != NULL)
  			sbuf_delete(sname);
  		return (E2BIG);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: kib 
State-Changed-When: Sun Mar 13 10:08:40 UTC 2011 
State-Changed-Why:  
Merged to 8 && 7. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=155321 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/155321: commit references a PR
Date: Sun, 13 Mar 2011 10:08:21 +0000 (UTC)

 Author: kib
 Date: Sun Mar 13 10:08:02 2011
 New Revision: 219595
 URL: http://svn.freebsd.org/changeset/base/219595
 
 Log:
   MFC r219352:
   The execution of the shebang script requires putting interpreter path,
   possible option and script path in the place of argv[0] supplied to
   execve(2).  It is possible and valid for the substitution to be shorter
   then the argv[0].
   
   Avoid signed underflow in this case.
   
   PR:     kern/155321
 
 Modified:
   stable/7/sys/kern/imgact_shell.c
 Directory Properties:
   stable/7/sys/   (props changed)
   stable/7/sys/cddl/contrib/opensolaris/   (props changed)
   stable/7/sys/contrib/dev/acpica/   (props changed)
   stable/7/sys/contrib/pf/   (props changed)
 
 Modified: stable/7/sys/kern/imgact_shell.c
 ==============================================================================
 --- stable/7/sys/kern/imgact_shell.c	Sun Mar 13 09:36:52 2011	(r219594)
 +++ stable/7/sys/kern/imgact_shell.c	Sun Mar 13 10:08:02 2011	(r219595)
 @@ -179,7 +179,7 @@ exec_shell_imgact(imgp)
  	length = (imgp->args->argc == 0) ? 0 :
  	    strlen(imgp->args->begin_argv) + 1;		/* bytes to delete */
  
 -	if (offset - length > imgp->args->stringspace)
 +	if (offset > imgp->args->stringspace + length) {
  		return (E2BIG);
  
  	bcopy(imgp->args->begin_argv + length, imgp->args->begin_argv + offset,
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
