From owner-svn-src-stable-11@freebsd.org Wed Aug 15 01:24:44 2018 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 644DB106D42A; Wed, 15 Aug 2018 01:24:44 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 16E9971922; Wed, 15 Aug 2018 01:24:44 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ECCBC2376E; Wed, 15 Aug 2018 01:24:43 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w7F1Oh26064292; Wed, 15 Aug 2018 01:24:43 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w7F1OhGo064291; Wed, 15 Aug 2018 01:24:43 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201808150124.w7F1OhGo064291@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Wed, 15 Aug 2018 01:24:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r337825 - stable/11/usr.bin/apply X-SVN-Group: stable-11 X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: stable/11/usr.bin/apply X-SVN-Commit-Revision: 337825 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Aug 2018 01:24:44 -0000 Author: kevans Date: Wed Aug 15 01:24:43 2018 New Revision: 337825 URL: https://svnweb.freebsd.org/changeset/base/337825 Log: MFC r337504: apply(1): Fix magic number substitution with a magic space Using a space as the magic character would result in problems if the command started with a number: - For a 'valid' number n, n < size of argv, it would erroneously get replaced with that argument; e.g. `apply -a ' ' -d 1rm x => `execxrm x` - For an 'invalid' number n, n >= size of argv, it would segfault. e.g. `apply -a ' ' 2to3 test.py` would try to access argv[2] This problem occurred because apply(1) would prepend "exec " to the command string before doing the actual magic number replacements, so it would come across "exec 2to3 1" and assume that the " 2" is also a magic number to be replaced. Re-work this to instead just append "exec " to the command sbuf and workaround the ugliness. This also simplifies stuff in the process. PR: 226948 Modified: stable/11/usr.bin/apply/apply.c Directory Properties: stable/11/ (props changed) Modified: stable/11/usr.bin/apply/apply.c ============================================================================== --- stable/11/usr.bin/apply/apply.c Wed Aug 15 00:15:40 2018 (r337824) +++ stable/11/usr.bin/apply/apply.c Wed Aug 15 01:24:43 2018 (r337825) @@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$"); #include #include -#define EXEC "exec " +#define ISMAGICNO(p) \ + (p)[0] == magic && isdigit((unsigned char)(p)[1]) && (p)[1] != '0' static int exec_shell(const char *, const char *, const char *); static void usage(void); @@ -63,8 +64,9 @@ main(int argc, char *argv[]) { struct sbuf *cmdbuf; long arg_max; - int ch, debug, i, magic, n, nargs, offset, rval; + int ch, debug, i, magic, n, nargs, rval; size_t cmdsize; + char buf[4]; char *cmd, *name, *p, *shell, *slashp, *tmpshell; debug = 0; @@ -73,7 +75,7 @@ main(int argc, char *argv[]) while ((ch = getopt(argc, argv, "a:d0123456789")) != -1) switch (ch) { case 'a': - if (optarg[1] != '\0') + if (optarg[0] == '\0' || optarg[1] != '\0') errx(1, "illegal magic character specification"); magic = optarg[0]; @@ -103,7 +105,7 @@ main(int argc, char *argv[]) * largest one. */ for (n = 0, p = argv[0]; *p != '\0'; ++p) - if (p[0] == magic && isdigit(p[1]) && p[1] != '0') { + if (ISMAGICNO(p)) { ++p; if (p[0] - '0' > n) n = p[0] - '0'; @@ -132,28 +134,19 @@ main(int argc, char *argv[]) * Allocate enough space to hold the maximum command. Save the * size to pass to snprintf(). */ - cmdsize = sizeof(EXEC) - 1 + strlen(argv[0]) - + 9 * (sizeof(" %1") - 1) + 1; - if ((cmd = malloc(cmdsize)) == NULL) - err(1, NULL); - if (n == 0) { + cmdsize = strlen(argv[0]) + 9 * (sizeof(" %1") - 1) + 1; + if ((cmd = malloc(cmdsize)) == NULL) + err(1, NULL); + strlcpy(cmd, argv[0], cmdsize); + /* If nargs not set, default to a single argument. */ if (nargs == -1) nargs = 1; - p = cmd; - offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]); - if ((size_t)offset >= cmdsize) - errx(1, "snprintf() failed"); - p += offset; - cmdsize -= offset; for (i = 1; i <= nargs; i++) { - offset = snprintf(p, cmdsize, " %c%d", magic, i); - if ((size_t)offset >= cmdsize) - errx(1, "snprintf() failed"); - p += offset; - cmdsize -= offset; + snprintf(buf, sizeof(buf), " %c%d", magic, i); + strlcat(cmd, buf, cmdsize); } /* @@ -163,9 +156,8 @@ main(int argc, char *argv[]) if (nargs == 0) nargs = 1; } else { - offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]); - if ((size_t)offset >= cmdsize) - errx(1, "snprintf() failed"); + if ((cmd = strdup(argv[0])) == NULL) + err(1, NULL); nargs = n; } @@ -182,9 +174,10 @@ main(int argc, char *argv[]) */ for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) { sbuf_clear(cmdbuf); + sbuf_cat(cmdbuf, "exec "); /* Expand command argv references. */ for (p = cmd; *p != '\0'; ++p) { - if (p[0] == magic && isdigit(p[1]) && p[1] != '0') { + if (ISMAGICNO(p)) { if (sbuf_cat(cmdbuf, argv[(++p)[0] - '0']) == -1) errc(1, ENOMEM, "sbuf");