summaryrefslogtreecommitdiff
path: root/debian/patches/exec_filename_fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/exec_filename_fix.patch')
-rw-r--r--debian/patches/exec_filename_fix.patch144
1 files changed, 144 insertions, 0 deletions
diff --git a/debian/patches/exec_filename_fix.patch b/debian/patches/exec_filename_fix.patch
new file mode 100644
index 00000000..71836d9b
--- /dev/null
+++ b/debian/patches/exec_filename_fix.patch
@@ -0,0 +1,144 @@
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+
+This patch is an amendment of exec_filename_exec.patch.
+
+If file_name_exec is not given, check_hashbang will try to locate the
+file. If argv[0] contains a '/', the file path is assumed to be
+absolute and it will try to open the file. Otherwise, the file is
+searched in the PATH. In either case, the resulting file identity port
+is compared to the identity port of the original file handle passed to
+check_hashbang.
+
+exec_filename_exec.patch explicitly provides the script files path in
+file_name_exec. According to the comment, if this path is provided, it
+is assumed to be the path to the script file and no attempt at
+locating the script file is done. However, the identity ports are
+still compared. This cannot succeed if fakeroot or chroot is used,
+because the process doing the exec and thus the initial file lookup is
+running in the chrooted environment, while the exec server is not.
+
+Fix this by skipping the identity test if file_name_exec is provided.
+
+* exec/hashexec.c (check_hashbang): Skip the file identity test if the
+ file_name_exec is provided.
+---
+ exec/hashexec.c | 91 ++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 50 insertions(+), 41 deletions(-)
+
+--- a/exec/hashexec.c
++++ b/exec/hashexec.c
+@@ -231,11 +231,12 @@ check_hashbang (struct execdata *e,
+ else if (! (flags & EXEC_SECURE))
+ {
+ /* Try to figure out the file's name. If FILE_NAME_EXEC
+- is not NULL, then it's the file's name. Otherwise we
+- guess that if ARGV[0] contains a slash, it might be
+- the name of the file; and that if it contains no slash,
+- looking for files named by ARGV[0] in the `PATH'
+- environment variable might find it. */
++ is not NULL and not the empty string, then it's the
++ file's name. Otherwise we guess that if ARGV[0]
++ contains a slash, it might be the name of the file;
++ and that if it contains no slash, looking for files
++ named by ARGV[0] in the `PATH' environment variable
++ might find it. */
+
+ error_t error;
+ char *name;
+@@ -271,51 +272,59 @@ check_hashbang (struct execdata *e,
+ return err;
+ }
+
+- error = io_identity (file, &fileid, &filefsid, &fileno);
+- if (error)
+- goto out;
+- mach_port_deallocate (mach_task_self (), filefsid);
+-
+- if (memchr (argv, '\0', argvlen) == NULL)
+- {
+- name = alloca (argvlen + 1);
+- bcopy (argv, name, argvlen);
+- name[argvlen] = '\0';
+- }
+- else
+- name = argv;
+-
+ if (file_name_exec && file_name_exec[0] != '\0')
+- error = lookup (name = file_name_exec, 0, &name_file);
+- else if (strchr (name, '/') != NULL)
+- error = lookup (name, 0, &name_file);
+- else if ((error = hurd_catch_signal
+- (sigmask (SIGBUS) | sigmask (SIGSEGV),
+- (vm_address_t) envp, (vm_address_t) envp + envplen,
+- &search_path, SIG_ERR)))
+- name_file = MACH_PORT_NULL;
+-
+- if (!error && name_file != MACH_PORT_NULL)
++ name = file_name_exec;
++ else
+ {
+- mach_port_t id, fsid;
+- ino_t ino;
+- error = io_identity (name_file, &id, &fsid, &ino);
+- mach_port_deallocate (mach_task_self (), name_file);
+- if (!error)
++ /* Try to locate the file. */
++ error = io_identity (file, &fileid, &filefsid, &fileno);
++ if (error)
++ goto out;
++ mach_port_deallocate (mach_task_self (), filefsid);
++
++ if (memchr (argv, '\0', argvlen) == NULL)
+ {
+- mach_port_deallocate (mach_task_self (), fsid);
+- mach_port_deallocate (mach_task_self (), id);
++ name = alloca (argvlen + 1);
++ bcopy (argv, name, argvlen);
++ name[argvlen] = '\0';
+ }
+- if (!error && id == fileid)
++ else
++ name = argv;
++
++ if (strchr (name, '/') != NULL)
++ error = lookup (name, 0, &name_file);
++ else if ((error = hurd_catch_signal
++ (sigmask (SIGBUS) | sigmask (SIGSEGV),
++ (vm_address_t) envp, (vm_address_t) envp + envplen,
++ &search_path, SIG_ERR)))
++ name_file = MACH_PORT_NULL;
++
++ /* See whether we found the right file. */
++ if (!error && name_file != MACH_PORT_NULL)
+ {
+- file_name = name;
+- free_file_name = free_name;
++ mach_port_t id, fsid;
++ ino_t ino;
++ error = io_identity (name_file, &id, &fsid, &ino);
++ mach_port_deallocate (mach_task_self (), name_file);
++ if (!error)
++ {
++ mach_port_deallocate (mach_task_self (), fsid);
++ mach_port_deallocate (mach_task_self (), id);
++ if (id != fileid)
++ error = 1;
++ }
+ }
+- else if (free_name)
+- free (name);
++
++ mach_port_deallocate (mach_task_self (), fileid);
+ }
+
+- mach_port_deallocate (mach_task_self (), fileid);
++ if (!error)
++ {
++ file_name = name;
++ free_file_name = free_name;
++ }
++ else if (free_name)
++ free (name);
+ }
+
+ if (file_name == NULL)