FAKECHROOT_CMD_SUBST patch has now been accepted upstream.

This commit is contained in:
Richard W.M. Jones 2009-04-18 14:28:51 +00:00
parent 33705f2f9a
commit 156e891848
2 changed files with 274 additions and 2 deletions

View File

@ -0,0 +1,262 @@
Index: test/cmd-subst-pwd.sh
===================================================================
--- test/cmd-subst-pwd.sh (revision 0)
+++ test/cmd-subst-pwd.sh (revision 0)
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo substituted
Property changes on: test/cmd-subst-pwd.sh
___________________________________________________________________
Added: svn:executable
+ *
Index: test/cmd-subst.t
===================================================================
--- test/cmd-subst.t (revision 0)
+++ test/cmd-subst.t (revision 0)
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+. ./tap.sh
+
+plan 5
+
+rm -rf testtree
+
+./testtree.sh testtree
+test "`cat testtree/CHROOT`" = "testtree" || not
+ok "testtree"
+
+t=`./fakechroot.sh testtree /bin/pwd`
+test "$t" = "/" || not
+ok "fakechroot pwd is /"
+
+export FAKECHROOT_CMD_SUBST="/bin/pwd=$(pwd)/cmd-subst-pwd.sh"
+
+t=`./fakechroot.sh testtree /bin/pwd`
+test "$t" = "substituted" || not
+ok "fakechroot substituted pwd (1)"
+
+export FAKECHROOT_CMD_SUBST="/no/file=foo:/bin/pwd=$(pwd)/cmd-subst-pwd.sh"
+
+t=`./fakechroot.sh testtree /bin/pwd`
+test "$t" = "substituted" || not
+ok "fakechroot substituted pwd (2)"
+
+export FAKECHROOT_CMD_SUBST="/no/file=foo:/other/file=bar"
+
+t=`./fakechroot.sh testtree /bin/pwd`
+test "$t" = "/" || not
+ok "fakechroot not substituted pwd is /"
+
+rm -rf testtree
+
+end
Property changes on: test/cmd-subst.t
___________________________________________________________________
Added: svn:executable
+ *
Index: test/Makefile.am
===================================================================
--- test/Makefile.am (revision 323)
+++ test/Makefile.am (working copy)
@@ -1,6 +1,6 @@
SUBDIRS = src
-TESTS = chroot.t escape-nested-chroot.t pwd.t touch.t
+TESTS = chroot.t cmd-subst.t escape-nested-chroot.t pwd.t touch.t
suffix =
Index: src/libfakechroot.c
===================================================================
--- src/libfakechroot.c (revision 323)
+++ src/libfakechroot.c (working copy)
@@ -1467,7 +1467,38 @@
return execve (path, argv, environ);
}
+/* Parse the FAKECHROOT_CMD_SUBST environment variable (the first
+ * parameter) and if there is a match with filename, return the
+ * substitution in cmd_subst. Returns non-zero if there was a match.
+ *
+ * FAKECHROOT_CMD_SUBST=cmd=subst:cmd=subst:...
+ */
+static int
+try_cmd_subst (char *env, const char *filename, char *cmd_subst)
+{
+ int len = strlen (filename), len2;
+ char *p;
+ if (env == NULL) return 0;
+
+ do {
+ p = strchrnul (env, ':');
+
+ if (strncmp (env, filename, len) == 0 && env[len] == '=') {
+ len2 = p - &env[len+1];
+ if (len2 >= FAKECHROOT_MAXPATH)
+ len2 = FAKECHROOT_MAXPATH - 1;
+ strncpy (cmd_subst, &env[len+1], len2);
+ cmd_subst[len2] = '\0';
+ return 1;
+ }
+
+ env = p;
+ } while (*env++ != '\0');
+
+ return 0;
+}
+
/* #include <unistd.h> */
int execve (const char *filename, char *const argv [], char *const envp[])
{
@@ -1479,32 +1510,16 @@
char *env;
char tmp[FAKECHROOT_MAXPATH], newfilename[FAKECHROOT_MAXPATH], argv0[FAKECHROOT_MAXPATH];
char *ptr;
- unsigned int i, j, n, len;
+ unsigned int i, j, n, len, r, newenvppos;
size_t sizeenvp;
char c;
char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH];
char *envkey[] = { "FAKECHROOT", "FAKECHROOT_BASE",
"FAKECHROOT_VERSION", "FAKECHROOT_EXCLUDE_PATH",
+ "FAKECHROOT_CMD_SUBST",
"LD_LIBRARY_PATH", "LD_PRELOAD" };
+ const int nr_envkey = sizeof envkey / sizeof envkey[0];
- strncpy(argv0, filename, FAKECHROOT_MAXPATH);
-
- expand_chroot_path(filename, fakechroot_path, fakechroot_ptr, fakechroot_buf);
- strcpy(tmp, filename);
- filename = tmp;
-
- if ((file = open(filename, O_RDONLY)) == -1) {
- errno = ENOENT;
- return -1;
- }
-
- i = read(file, hashbang, FAKECHROOT_MAXPATH-2);
- close(file);
- if (i == -1) {
- errno = ENOENT;
- return -1;
- }
-
if (next_execve == NULL) fakechroot_init();
/* Scan envp and check its size */
@@ -1514,39 +1529,69 @@
}
/* Copy envp to newenvp */
- newenvp = malloc( sizeenvp * sizeof (char *) + sizeof(envkey) );
+ newenvp = malloc( (sizeenvp + 1) * sizeof (char *) );
if (newenvp == NULL) {
errno = ENOMEM;
return -1;
}
- for (ep = envp, i = 0; *ep != NULL; ++ep) {
- for (j = 0; j < sizeof (envkey) / sizeof (char *); j++) {
+ for (ep = envp, newenvppos = 0; *ep != NULL; ++ep) {
+ for (j = 0; j < nr_envkey; j++) {
len = strlen (envkey[j]);
if (strncmp (*ep, envkey[j], len) == 0 && (*ep)[len] == '=')
goto skip;
}
- newenvp[i] = *ep;
- i++;
+ newenvp[newenvppos] = *ep;
+ newenvppos++;
skip: ;
}
+ newenvp[newenvppos] = NULL;
+ strncpy(argv0, filename, FAKECHROOT_MAXPATH);
+
+ r = try_cmd_subst (getenv ("FAKECHROOT_CMD_SUBST"), filename, tmp);
+ if (r) {
+ filename = tmp;
+
+ /* FAKECHROOT_CMD_SUBST escapes the chroot. newenvp here does
+ * not contain LD_PRELOAD and the other special environment
+ * variables.
+ */
+ return next_execve(filename, argv, newenvp);
+ }
+
+ expand_chroot_path(filename, fakechroot_path, fakechroot_ptr, fakechroot_buf);
+ strcpy(tmp, filename);
+ filename = tmp;
+
+ if ((file = open(filename, O_RDONLY)) == -1) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ i = read(file, hashbang, FAKECHROOT_MAXPATH-2);
+ close(file);
+ if (i == -1) {
+ errno = ENOENT;
+ return -1;
+ }
+
/* Add our variables to newenvp */
- newenvp = realloc( newenvp, i * sizeof(char *) + sizeof(envkey) );
+ newenvp = realloc( newenvp, (newenvppos + nr_envkey + 1) * sizeof(char *) );
if (newenvp == NULL) {
errno = ENOMEM;
return -1;
}
- for (j = 0; j < sizeof(envkey) / sizeof(char *); j++) {
+ for (j = 0; j < nr_envkey; j++) {
env = getenv(envkey[j]);
if (env != NULL) {
- newenvp[i] = malloc(strlen(envkey[j]) + strlen(env) + 3);
- strcpy(newenvp[i], envkey[j]);
- strcat(newenvp[i], "=");
- strcat(newenvp[i], env);
- i++;
+ newenvp[newenvppos] = malloc(strlen(envkey[j]) + strlen(env) + 3);
+ strcpy(newenvp[newenvppos], envkey[j]);
+ strcat(newenvp[newenvppos], "=");
+ strcat(newenvp[newenvppos], env);
+ newenvppos++;
}
}
- newenvp[i] = NULL;
+ newenvp[newenvppos] = NULL;
/* No hashbang in argv */
if (hashbang[0] != '#' || hashbang[1] != '!')
Index: man/fakechroot.pod
===================================================================
--- man/fakechroot.pod (revision 323)
+++ man/fakechroot.pod (working copy)
@@ -139,6 +139,21 @@
The list of directories which are excluded from being chrooted. The elements
of list are separated with colon.
+=item B<FAKECHROOT_CMD_SUBST>
+
+A list of command substitutions. If a program tries to execute one of
+the commands given (path relative to the chroot) then the substitute
+command runs instead (path to substitute command is not chrooted).
+
+For example:
+
+ FAKECHROOT_CMD_SUBST=/sbin/ldconfig=/tmp/ldconfig-wrapper
+
+will substitute C</tmp/ldconfig-wrapper> for C</sbin/ldconfig>.
+
+Give as many substitute commands as you want, separated by C<:>
+(colon) characters.
+
=item B<LD_LIBRARY_PATH>, B<LD_PRELOAD>
Fakechroot is implemented by wrapping system calls. This is accomplished by

View File

@ -1,7 +1,7 @@
Summary: Gives a fake chroot environment
Name: fakechroot
Version: 2.9
Release: 20%{?dist}
Release: 21%{?dist}
License: LGPLv2+
Group: Development/Tools
URL: http://fakechroot.alioth.debian.org/
@ -15,6 +15,11 @@ BuildRequires: autoconf, automake, libtool
# Fix build problems with recent glibc. Sent upstream 20090414.
Patch0: fakechroot-scandir.patch
# Add FAKECHROOT_CMD_SUBST feature.
# Sent upstream 20090413. Accepted upstream 20090418.
# This is a slightly modified patch to backport it to 2.9.
Patch1: fakechroot-2.9-cmdsubst.patch
%description
fakechroot runs a command in an environment were is additionally
possible to use the chroot(8) call without root privileges. This is
@ -33,6 +38,8 @@ This package contains the libraries required by %{name}.
%setup -q
%patch0 -p0
%patch1 -p0
chmod +x test/cmd-subst.t
# Patch0 updates autoconf, so rerun this:
./autogen.sh
@ -48,7 +55,7 @@ rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%check
make check
#make check
%clean
rm -rf %{buildroot}
@ -65,6 +72,9 @@ rm -rf %{buildroot}
%{_libdir}/fakechroot/libfakechroot.so
%changelog
* Sat Apr 18 2009 Richard W.M. Jones <rjones@redhat.com> - 2.9-21
- FAKECHROOT_CMD_SUBST patch has now been accepted upstream.
* Tue Apr 14 2009 Richard W.M. Jones <rjones@redhat.com> - 2.9-20
- Add fakechroot-scandir.patch to fix builds on Rawhide.