Projects
Factory:RISC-V:Base
bash
_service:tar_scm:bash-2.05a-interpreter.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:bash-2.05a-interpreter.patch of Package bash
From 34497c50a8497148e3b0232659f58ffaf4931b06 Mon Sep 17 00:00:00 2001 From: liujian <liujianliu.liu@huawei.com> Date: Mon, 31 May 2021 21:46:41 +0800 Subject: [PATCH] bash-2.05a-interpreter --- config.h.in | 6 +++ configure.ac | 2 +- execute_cmd.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) diff --git a/config.h.in b/config.h.in index ab316d4..11d1d68 100644 --- a/config.h.in +++ b/config.h.in @@ -775,6 +775,9 @@ /* Define if you have the pselect function. */ #undef HAVE_PSELECT +/* Define if you have the pread function. */ +#undef HAVE_PREAD + /* Define if you have the putenv function. */ #undef HAVE_PUTENV @@ -981,6 +984,9 @@ /* Define if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H +/* Define if you have the <elf.h> header file. */ +#undef HAVE_ELF_H + /* Define if you have the <grp.h> header file. */ #undef HAVE_GRP_H diff --git a/configure.ac b/configure.ac index 2fe3e7d..f1b7f1b 100644 --- a/configure.ac +++ b/configure.ac @@ -827,7 +827,7 @@ dnl checks for system calls AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getentropy getgroups \ gethostname getpagesize getpeername getrandom getrlimit \ getrusage gettimeofday kill killpg lstat pselect readlink \ - select setdtablesize setitimer tcgetpgrp uname ulimit waitpid) + select setdtablesize setitimer tcgetpgrp uname ulimit waitpid pread) AC_REPLACE_FUNCS(rename) dnl checks for c library functions diff --git a/execute_cmd.c b/execute_cmd.c index d2a0dd7..374843d 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -41,6 +41,10 @@ # include <unistd.h> #endif +#ifdef HAVE_ELF_H +# include <elf.h> +#endif + #include "posixtime.h" #if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE) @@ -5832,6 +5836,14 @@ shell_execve (command, args, env) { /* The file has the execute bits set, but the kernel refuses to run it for some reason. See why. */ +#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H) + int fd = open (command, O_RDONLY); + + if (fd >= 0) + sample_len = read (fd, sample, sizeof (sample)); + else + sample_len = -1; +#endif #if defined (HAVE_HASH_BANG_EXEC) READ_SAMPLE_BUF (command, sample, sample_len); if (sample_len > 0) @@ -5841,6 +5853,7 @@ shell_execve (command, args, env) char *interp; int ilen; + close (fd); interp = getinterp (sample, sample_len, (int *)NULL); ilen = strlen (interp); errno = i; @@ -5856,6 +5869,137 @@ shell_execve (command, args, env) return (EX_NOEXEC); } #endif +#if defined (HAVE_ELF_H) + if (i == ENOENT + && sample_len > EI_NIDENT + && memcmp (sample, ELFMAG, SELFMAG) == 0) + { + off_t offset = -1; + + /* It is an ELF file. Now determine whether it is dynamically + linked and if yes, get the offset of the interpreter + string. */ + if (sample[EI_CLASS] == ELFCLASS32 + && sample_len > sizeof (Elf32_Ehdr)) + { + Elf32_Ehdr ehdr; + Elf32_Phdr *phdr; + int nphdr; + + /* We have to copy the data since the sample buffer + might not be aligned correctly to be accessed as + an Elf32_Ehdr struct. */ + memcpy (&ehdr, sample, sizeof (Elf32_Ehdr)); + + nphdr = ehdr.e_phnum; + phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize); + if (phdr != NULL) + { +#ifdef HAVE_PREAD + sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize, + ehdr.e_phoff); +#else + if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1) + sample_len = read (fd, phdr, + nphdr * ehdr.e_phentsize); + else + sample_len = -1; +#endif + if (sample_len == nphdr * ehdr.e_phentsize) + while (nphdr-- > 0) + if (phdr[nphdr].p_type == PT_INTERP) + { + offset = phdr[nphdr].p_offset; + break; + } + free (phdr); + } + } + else if (sample[EI_CLASS] == ELFCLASS64 + && sample_len > sizeof (Elf64_Ehdr)) + { + Elf64_Ehdr ehdr; + Elf64_Phdr *phdr; + int nphdr; + + /* We have to copy the data since the sample buffer + might not be aligned correctly to be accessed as + an Elf64_Ehdr struct. */ + memcpy (&ehdr, sample, sizeof (Elf64_Ehdr)); + + nphdr = ehdr.e_phnum; + phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize); + if (phdr != NULL) + { +#ifdef HAVE_PREAD + sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize, + ehdr.e_phoff); +#else + if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1) + sample_len = read (fd, phdr, + nphdr * ehdr.e_phentsize); + else + sample_len = -1; +#endif + if (sample_len == nphdr * ehdr.e_phentsize) + while (nphdr-- > 0) + if (phdr[nphdr].p_type == PT_INTERP) + { + offset = phdr[nphdr].p_offset; + break; + } + free (phdr); + } + } + + if (offset != -1) + { + size_t maxlen = 0; + size_t actlen = 0; + char *interp = NULL; + + do + { + if (actlen == maxlen) + { + char *newinterp = realloc (interp, maxlen += 200); + if (newinterp == NULL) + { + actlen = 0; + break; + } + interp = newinterp; + +#ifdef HAVE_PREAD + actlen = pread (fd, interp, maxlen, offset); +#else + if (lseek (fd, offset, SEEK_SET) != -1) + actlen = read (fd, interp, maxlen); + else + actlen = -1; +#endif + } + } + while (actlen > 0 && memchr (interp, '\0', actlen) == NULL); + + if (actlen > 0) + { + close (fd); + errno = i; + sys_error ("%s: %s: bad ELF interpreter", command, + interp); + free (interp); + return (EX_NOEXEC); + } + + free (interp); + } + } +#endif +#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H) + close (fd); +#endif + errno = i; file_error (command); } -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2