From owner-freebsd-bugs@FreeBSD.ORG Wed Feb 15 05:20:05 2012 Return-Path: <owner-freebsd-bugs@FreeBSD.ORG> Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EEACD106566B for <freebsd-bugs@hub.freebsd.org>; Wed, 15 Feb 2012 05:20:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id C62688FC0C for <freebsd-bugs@hub.freebsd.org>; Wed, 15 Feb 2012 05:20:05 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q1F5K56q098410 for <freebsd-bugs@freefall.freebsd.org>; Wed, 15 Feb 2012 05:20:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q1F5K54b098409; Wed, 15 Feb 2012 05:20:05 GMT (envelope-from gnats) Resent-Date: Wed, 15 Feb 2012 05:20:05 GMT Resent-Message-Id: <201202150520.q1F5K54b098409@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Matthew Story <matthewstory@gmail.com> Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 54708106566B for <freebsd-gnats-submit@FreeBSD.org>; Wed, 15 Feb 2012 05:16:35 +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 359858FC0C for <freebsd-gnats-submit@FreeBSD.org>; Wed, 15 Feb 2012 05:16:35 +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 q1F5GYN8090635 for <freebsd-gnats-submit@FreeBSD.org>; Wed, 15 Feb 2012 05:16:34 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id q1F5GY1b090633; Wed, 15 Feb 2012 05:16:34 GMT (envelope-from nobody) Message-Id: <201202150516.q1F5GY1b090633@red.freebsd.org> Date: Wed, 15 Feb 2012 05:16:34 GMT From: Matthew Story <matthewstory@gmail.com> To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/165164: [PATCH][bin] xargs incorrect pointer passed to waitchildren function X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports <freebsd-bugs.freebsd.org> List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/freebsd-bugs>, <mailto:freebsd-bugs-request@freebsd.org?subject=unsubscribe> List-Archive: <http://lists.freebsd.org/pipermail/freebsd-bugs> List-Post: <mailto:freebsd-bugs@freebsd.org> List-Help: <mailto:freebsd-bugs-request@freebsd.org?subject=help> List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/freebsd-bugs>, <mailto:freebsd-bugs-request@freebsd.org?subject=subscribe> X-List-Received-Date: Wed, 15 Feb 2012 05:20:06 -0000 >Number: 165164 >Category: bin >Synopsis: [PATCH][bin] xargs incorrect pointer passed to waitchildren function >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Feb 15 05:20:05 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Matthew Story >Release: 9.0 >Organization: >Environment: FreeBSD matt9fromouterspace 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 3 07:15:25 UTC 2012 root@obrian.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: *argv is manipulated in main to account for Jflag replacement strings (moving argv into av, and leaving *argv a pointer to the first argument following a Jflag replacement string argument || NULL if Jflag not set): if (*argv == NULL) cnt = strlen(*bxp++ = echo); else { do { if (Jflag && strcmp(*argv, replstr) == 0) { char **avj; jfound = 1; argv++; for (avj = argv; *avj; avj++) cnt += strlen(*avj) + 1; break; } cnt += strlen(*bxp++ = *argv) + 1; } while (*++argv != NULL); } *argv is then passed to parse_input, which passes *av to prerun, which in turn passes *av (locally argv) to waitchildren for diagnostic purposes, while the calls from parse_input itself pass *argv to waitchildren for diagnostic purposes. This incongruity means that calls directly from parse_input (only in cases after EOF has been seen) take either NULL or the first argument after a Jflag string argument as utility name for diagnostic purposes, leading to output like: xargs: (null): No such file or directory >How-To-Repeat: Found this issue after applying patch from PR 165155, which provides POSIX-compliant diagnostic information on exit 255 and children terminated by signals. Condition exists, but is masked for the most part by a race on line 568 (WNOHANG wait immediately following vfork, execvp), if you comment out that line: /* waitchildren(*argv, 0); */ You will reliably see the following behavior: $ # this will work unless you have a this_does_not_exist in your PATH $ echo "hi" | ./xargs -P10 -n1 this_does_not_exist xargs: (null): No such file or directory $ # this should read: xargs: hi: No such file or directory $ echo "this_does_not_exist" | ./xargs -J % % sh xargs: sh: No such file or directory You can alternalively apply the patch from PR 165155, and the following will always yield the (null) error condition: $ jot - 1 10 | ./xargs -P10 -n12 sh -c 'sleep 1; exit 255' xargs: (null): exited with status 255, aborting This issue should be resolved prior to patching PR 165155, I will make a note in that ticket as well. Following applying the patch: $ echo "hi" | ./xargs blah xargs: blah: No such file or directory $ echo "hi" | ./xargs -J % % sh xargs: hi: No such file or directory And for the PR 165155 case: $ jot - 1 10 | ./xargs -P10 -n12 sh -c 'sleep 1; exit 255' xargs: sh: exited with status 255, aborting >Fix: Apply patch. This program looks like it needs a larger re-factor, but the solution provided in the patch is to send *av to waitchildren instead of *argv (which is a pointer to the first argument following a Jflag replacement string || null) to make the behavior congruent with the argument list passed to prerun (locally argv). Patch attached with submission follows: --- a/usr.bin/xargs/xargs.c 2012-02-14 22:54:29.000000000 -0500 +++ b/usr.bin/xargs/xargs.c 2012-02-14 16:46:37.000000000 -0500 @@ -281,7 +281,7 @@ case EOF: /* No arguments since last exec. */ if (p == bbp) { - waitchildren(*argv, 1); + waitchildren(*av, 1); exit(rval); } goto arg1; @@ -368,7 +368,7 @@ } prerun(argc, av); if (ch == EOF || foundeof) { - waitchildren(*argv, 1); + waitchildren(*av, 1); exit(rval); } p = bbp; >Release-Note: >Audit-Trail: >Unformatted: