From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <gentoo-commits+bounces-702180-garchives=archives.gentoo.org@lists.gentoo.org> Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 403FD1387FD for <garchives@archives.gentoo.org>; Tue, 10 Jun 2014 01:49:19 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id CEF71E08F7; Tue, 10 Jun 2014 01:49:16 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 42096E08F7 for <gentoo-commits@lists.gentoo.org>; Tue, 10 Jun 2014 01:49:16 +0000 (UTC) Received: from spoonbill.gentoo.org (spoonbill.gentoo.org [81.93.255.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 3452B33FFDD for <gentoo-commits@lists.gentoo.org>; Tue, 10 Jun 2014 01:49:15 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by spoonbill.gentoo.org (Postfix) with ESMTP id 1BC1F181A9 for <gentoo-commits@lists.gentoo.org>; Tue, 10 Jun 2014 01:49:13 +0000 (UTC) From: "Anthony G. Basile" <blueness@gentoo.org> To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Anthony G. Basile" <blueness@gentoo.org> Message-ID: <1402364942.ba08589f95e4ec77b5e7f73f97278730dc426bcd.blueness@gentoo> Subject: [gentoo-commits] proj/elfix:master commit in: misc/install-xattr/ X-VCS-Repository: proj/elfix X-VCS-Files: misc/install-xattr/install-xattr.c X-VCS-Directories: misc/install-xattr/ X-VCS-Committer: blueness X-VCS-Committer-Name: Anthony G. Basile X-VCS-Revision: ba08589f95e4ec77b5e7f73f97278730dc426bcd X-VCS-Branch: master Date: Tue, 10 Jun 2014 01:49:13 +0000 (UTC) Precedence: bulk List-Post: <mailto:gentoo-commits@lists.gentoo.org> List-Help: <mailto:gentoo-commits+help@lists.gentoo.org> List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org> List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org> List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org> X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: f865127f-a05b-489e-a5fc-ffba485cc5e6 X-Archives-Hash: f3865fbf9769acd5962bc14387c8b905 commit: ba08589f95e4ec77b5e7f73f97278730dc426bcd Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> AuthorDate: Sun Jun 8 20:15:06 2014 +0000 Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> CommitDate: Tue Jun 10 01:49:02 2014 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=ba08589f misc/install-xattr: refine the behavior of which() The wrapper must avoid invoking itself in its attempt to find the system `install` path. The old behavior was to avoid looking in the same directory as the wrapper, but this is too crude since we might have the wrapper in /usr/bin (say), and the system `install` in the same directory, in which case we'll wind up skipping it. The new behavior of which() is to accept argv[0], find its canonical path and skip if it is equal to the canditate system `install` we are checking. We also add PORTAGE_BIN_PATH which will be used in a future commit to avoid this wrapper from finding portage's wrapper. We can then get into a situation where the portage wrapper, usually at ${PORTAGE_BIN_PATH}/ebuild-helpers/xattr/install calls this wrapper, usually at /usr/bin/install-xattr, which in turn calls the portage wrapper in an infinite self-invocation (fork bomb). --- misc/install-xattr/install-xattr.c | 42 ++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/misc/install-xattr/install-xattr.c b/misc/install-xattr/install-xattr.c index c0c68f9..7dc248b 100644 --- a/misc/install-xattr/install-xattr.c +++ b/misc/install-xattr/install-xattr.c @@ -162,10 +162,11 @@ copyxattr(const char *source, const char *target) static char * -which(const char *mydir) +which(const char *myfile) { - char *mycandir = realpath(mydir, NULL); /* canonical value of argv[0]'s dirname */ - char *path, *env_path = getenv("PATH"); /* full $PATH string */ + char *mypath = realpath(myfile, NULL); /* argv[0]'s canonical path */ + char *path, *env_path = getenv("PATH"); /* full $PATH string */ + char *portage_bin_path = getenv("PORTAGE_BIN_PATH"); /* PORTAGE BIN $PATHs to skip */ /* If we don't have $PATH in our environment, then pick a sane path. */ if (env_path == NULL) { @@ -175,39 +176,44 @@ which(const char *mydir) } else path = xstrdup(env_path); - char *dir; /* one directory in the $PATH string */ - char *candir; /* canonical value of that directory */ - char *file; /* file name = path + "/install" */ - char *savedptr; /* reentrant context for strtok_r() */ + char *dir; /* one directory in the colon delimited $PATH string */ + char *canfile; /* candidate install's path = dir + "/install" */ + char *canpath; /* candidate install's canonical path */ + char *sdir; /* one directory in the $INSTALL_EXCLUDE_PATH string */ + char *savedptr; /* reentrant context for strtok_r() */ struct stat s; dir = strtok_r(path, ":", &savedptr); while (dir) { - candir = realpath(dir, NULL); + canfile = path_join(dir, "install"); + canpath = realpath(canfile, NULL); + free(canfile); /* ignore invalid paths that cannot be canonicalized */ - if (!candir) + if (!canpath) goto skip; - file = path_join(candir, "install"); + /* If argv[0]'s canonical path == candidates install's canonical path, + * then we skip this path otheriwise we get into an infinite self-invocation. + */ + if (!strcmp(mypath, canpath)) + goto skip; - /* If the file exists and is either a regular file or sym link, + /* If the canpath exists and is either a regular file or sym link, * assume we found the system's install. */ - if (stat(file, &s) == 0) + if (stat(canpath, &s) == 0) if (S_ISREG(s.st_mode)) { - free(candir); - free(mycandir); + free(mypath); free(path); - return file; + return canpath; } - free(file); skip: - free(candir); + free(canpath); dir = strtok_r(NULL, ":", &savedptr); } @@ -310,7 +316,7 @@ main(int argc, char* argv[]) err(1, "fork() failed"); case 0: - install = which(dirname(argv[0])); + install = which(argv[0]); argv[0] = install; /* so coreutils' lib/program.c behaves */ execv(install, argv); /* The kernel will free(install). */ err(1, "execv() failed");