diff options
Diffstat (limited to 'debian/patches/exec_filename_fix.patch')
-rw-r--r-- | debian/patches/exec_filename_fix.patch | 144 |
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) |