87788da1b1
Resolves: #711066
224 lines
6.5 KiB
Diff
224 lines
6.5 KiB
Diff
diff -upr tcsh-6.18.01_orig/config.h.in tcsh-6.18.01_work/config.h.in
|
|
--- tcsh-6.18.01_orig/config.h.in 2013-04-23 14:10:52.181655679 +0200
|
|
+++ tcsh-6.18.01_work/config.h.in 2013-04-23 14:14:33.715035808 +0200
|
|
@@ -36,6 +36,9 @@
|
|
/* Define to 1 if you have the `dup2' function. */
|
|
#undef HAVE_DUP2
|
|
|
|
+/* Define to 1 if you have the <elf.h> header file. */
|
|
+#undef HAVE_ELF_H
|
|
+
|
|
/* Define to 1 if you have the <features.h> header file. */
|
|
#undef HAVE_FEATURES_H
|
|
|
|
@@ -96,6 +99,9 @@
|
|
/* Define to 1 if you have the <paths.h> header file. */
|
|
#undef HAVE_PATHS_H
|
|
|
|
+/* Define to 1 if you have the `pread' function. */
|
|
+#undef HAVE_PREAD
|
|
+
|
|
/* Define to 1 if you have the `sbrk' function. */
|
|
#undef HAVE_SBRK
|
|
|
|
diff -upr tcsh-6.18.01_orig/configure.in tcsh-6.18.01_work/configure.in
|
|
--- tcsh-6.18.01_orig/configure.in 2013-04-23 14:10:52.157655645 +0200
|
|
+++ tcsh-6.18.01_work/configure.in 2013-04-23 14:13:53.226958044 +0200
|
|
@@ -306,7 +306,7 @@ AC_SEARCH_LIBS(catgets, catgets)
|
|
AM_ICONV
|
|
|
|
dnl Checks for header files
|
|
-AC_CHECK_HEADERS([auth.h crypt.h features.h inttypes.h paths.h] dnl
|
|
+AC_CHECK_HEADERS([auth.h crypt.h elf.h features.h inttypes.h paths.h] dnl
|
|
[shadow.h stdint.h utmp.h utmpx.h])
|
|
AC_CHECK_HEADERS([wchar.h],
|
|
[AC_CHECK_SIZEOF([wchar_t], [], [dnl
|
|
@@ -388,7 +388,8 @@ AC_CHECK_FUNC([setlocale], [have_setloca
|
|
AC_CHECK_FUNC([catgets], [have_catgets=yes], [have_catgets=no])
|
|
AC_CHECK_FUNCS([dup2 getauthid getcwd gethostname getpwent] dnl
|
|
[getutent getutxent mallinfo memmove memset mkstemp nice] dnl
|
|
- [nl_langinfo sbrk setpgid setpriority strerror strstr sysconf wcwidth])
|
|
+ [nl_langinfo pread sbrk setpgid setpriority strerror strstr] dnl
|
|
+ [sysconf wcwidth])
|
|
AC_FUNC_GETPGRP
|
|
AC_FUNC_MBRTOWC
|
|
if test "x${cross_compiling}" != xyes ; then
|
|
diff -upr tcsh-6.18.01_orig/sh.err.c tcsh-6.18.01_work/sh.err.c
|
|
--- tcsh-6.18.01_orig/sh.err.c 2013-04-23 14:10:52.160655649 +0200
|
|
+++ tcsh-6.18.01_work/sh.err.c 2013-04-23 14:15:33.347155943 +0200
|
|
@@ -189,7 +189,8 @@ char *seterr = NULL; /* Holds last err
|
|
#define ERR_INVALID 133
|
|
#define ERR_BADCOLORVAR 134
|
|
#define ERR_EOF 135
|
|
-#define NO_ERRORS 136
|
|
+#define ERR_ELFINTERP 136
|
|
+#define NO_ERRORS 137
|
|
|
|
static const char *elst[NO_ERRORS] INIT_ZERO_STRUCT;
|
|
|
|
@@ -367,6 +368,7 @@ errinit(void)
|
|
elst[ERR_BADJOB] = CSAVS(1, 136, "No such job (badjob)");
|
|
elst[ERR_BADCOLORVAR] = CSAVS(1, 137, "Unknown colorls variable `%c%c'");
|
|
elst[ERR_EOF] = CSAVS(1, 138, "Unexpected end of file");
|
|
+ elst[ERR_ELFINTERP] = CSAVS(1, 139, "No such ELF interpreter");
|
|
}
|
|
|
|
/* Cleanup data. */
|
|
diff -upr tcsh-6.18.01_orig/sh.exec.c tcsh-6.18.01_work/sh.exec.c
|
|
--- tcsh-6.18.01_orig/sh.exec.c 2013-04-23 14:10:52.156655643 +0200
|
|
+++ tcsh-6.18.01_work/sh.exec.c 2013-04-23 14:35:43.561578622 +0200
|
|
@@ -40,6 +40,10 @@ RCSID("$tcsh: sh.exec.c,v 3.79 2011/02/2
|
|
#include <nt.const.h>
|
|
#endif /*WINNT_NATIVE*/
|
|
|
|
+#ifdef HAVE_ELF_H
|
|
+#include <elf.h>
|
|
+#endif /*HAVE_ELF_H*/
|
|
+
|
|
/*
|
|
* C shell
|
|
*/
|
|
@@ -509,6 +513,142 @@ texec(Char *sf, Char **st)
|
|
case 0: /* execv fails and returns 0! */
|
|
#endif /* _IBMR2 */
|
|
case ENOENT:
|
|
+#ifdef HAVE_ELF_H
|
|
+ /*
|
|
+ * If dynamically linked ELF binary is not executed and exists,
|
|
+ * the real reason ENOENT is that ELF interpreter is missing.
|
|
+ *
|
|
+ * Written by Ulrich Drepper for bash
|
|
+ * adopted by Fridolin Pokorny <fpokorny@redhat.com>
|
|
+ */
|
|
+ if ((fd = xopen(f, O_RDONLY|O_LARGEFILE)) != -1) {
|
|
+ int nread;
|
|
+ char *sample;
|
|
+ int offset = -1;
|
|
+ int sample_size;
|
|
+
|
|
+ /* Inspect 32 and 64 ELF */
|
|
+ if (sizeof(Elf64_Ehdr) > sizeof(Elf32_Ehdr))
|
|
+ sample_size = sizeof(Elf64_Ehdr);
|
|
+ else
|
|
+ sample_size = sizeof(Elf32_Ehdr);
|
|
+
|
|
+ sample = xmalloc(sample_size);
|
|
+
|
|
+ if (sample != 0 &&
|
|
+ (nread = xread(fd, sample, sample_size)) == sample_size) {
|
|
+ if (memcmp(sample, ELFMAG, SELFMAG) == 0) {
|
|
+ if (sample[EI_CLASS] == ELFCLASS32 &&
|
|
+ sample_size >= 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 = xmalloc(nphdr * ehdr.e_phentsize);
|
|
+ if(phdr != NULL) {
|
|
+#ifdef HAVE_PREAD
|
|
+ nread = pread(fd, phdr, nphdr * ehdr.e_phentsize,
|
|
+ ehdr.e_phoff);
|
|
+#else /* !HAVE_PREAD */
|
|
+ if (lseek(fd, ehdr.e_phoff, SEEK_SET) != -1)
|
|
+ nread = read(fd, phdr,
|
|
+ nphdr * ehdr.e_phentsize);
|
|
+ else
|
|
+ nread = -1;
|
|
+#endif /* HAVE_PREAD */
|
|
+ if (nread == nphdr * ehdr.e_phentsize) {
|
|
+ while (nphdr-- > 0) {
|
|
+ if (phdr[nphdr].p_type == PT_INTERP) {
|
|
+ offset = phdr[nphdr].p_offset;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ xfree(phdr);
|
|
+ }
|
|
+ } else if (sample[EI_CLASS] == ELFCLASS64 &&
|
|
+ sample_size >= 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 = xmalloc(nphdr * ehdr.e_phentsize);
|
|
+ if (phdr != NULL) {
|
|
+#ifdef HAVE_PREAD
|
|
+ nread = pread (fd, phdr, nphdr * ehdr.e_phentsize,
|
|
+ ehdr.e_phoff);
|
|
+#else /* !HAVE_PREAD */
|
|
+ if (lseek(fd, ehdr.e_phoff, SEEK_SET) != -1)
|
|
+ nread = read (fd, phdr,
|
|
+ nphdr * ehdr.e_phentsize);
|
|
+ else
|
|
+ nread = -1;
|
|
+#endif /* HAVE_PREAD */
|
|
+ if (nread == nphdr * ehdr.e_phentsize) {
|
|
+ while (nphdr-- > 0) {
|
|
+ if (phdr[nphdr].p_type == PT_INTERP) {
|
|
+ offset = phdr[nphdr].p_offset;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ xfree (phdr);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (offset != -1) {
|
|
+ size_t maxlen = 0;
|
|
+ size_t actlen = 0;
|
|
+ char *interp = NULL;
|
|
+
|
|
+ do {
|
|
+ if (actlen == maxlen) {
|
|
+ char *newinterp = xrealloc(interp, maxlen += 200);
|
|
+ if (newinterp == NULL) {
|
|
+ actlen = 0;
|
|
+ break;
|
|
+ }
|
|
+ interp = newinterp;
|
|
+#ifdef HAVE_PREAD
|
|
+ actlen = pread (fd, interp, maxlen, offset);
|
|
+#else /* !HAVE_PREAD */
|
|
+ if (lseek (fd, offset, SEEK_SET) != -1)
|
|
+ actlen = read (fd, interp, maxlen);
|
|
+ else
|
|
+ actlen = -1;
|
|
+#endif /* HAVE_PREAD */
|
|
+ }
|
|
+ } while (actlen > 0 &&
|
|
+ memchr (interp, '\0', actlen) == NULL);
|
|
+
|
|
+ if (actlen > 0) {
|
|
+ xclose (fd);
|
|
+ xfree (interp);
|
|
+ setname(f);
|
|
+ stderror(ERR_NAME | ERR_ELFINTERP);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ xfree(sample);
|
|
+ }
|
|
+#endif /* HAVE_ELF_H */
|
|
break;
|
|
|
|
default:
|