]>
Commit | Line | Data |
---|---|---|
56ba7d19 MT |
1 | diff -up bash-4.2-rc2/config.h.in.interpreter bash-4.2-rc2/config.h.in |
2 | --- bash-4.2-rc2/config.h.in.interpreter 2011-02-09 07:59:21.000000000 +0100 | |
3 | +++ bash-4.2-rc2/config.h.in 2011-02-09 07:59:21.000000000 +0100 | |
4 | @@ -706,6 +706,9 @@ | |
5 | /* Define if you have the pathconf function. */ | |
6 | #undef HAVE_PATHCONF | |
7 | ||
8 | +/* Define if you have the pread function. */ | |
9 | +#undef HAVE_PREAD | |
10 | + | |
11 | /* Define if you have the putenv function. */ | |
12 | #undef HAVE_PUTENV | |
13 | ||
14 | @@ -898,6 +901,9 @@ | |
15 | /* Define if you have the <dlfcn.h> header file. */ | |
16 | #undef HAVE_DLFCN_H | |
17 | ||
18 | +/* Define if you have the <elf.h> header file. */ | |
19 | +#undef HAVE_ELF_H | |
20 | + | |
21 | /* Define if you have the <grp.h> header file. */ | |
22 | #undef HAVE_GRP_H | |
23 | ||
24 | diff -up bash-4.2-rc2/configure.in.interpreter bash-4.2-rc2/configure.in | |
25 | --- bash-4.2-rc2/configure.in.interpreter 2011-01-16 21:31:12.000000000 +0100 | |
26 | +++ bash-4.2-rc2/configure.ac 2011-02-09 08:02:27.000000000 +0100 | |
27 | @@ -659,7 +659,7 @@ BASH_HEADER_INTTYPES | |
28 | AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \ | |
29 | memory.h locale.h termcap.h termio.h termios.h dlfcn.h \ | |
30 | stdbool.h stddef.h stdint.h netdb.h pwd.h grp.h strings.h \ | |
31 | - regex.h syslog.h ulimit.h) | |
32 | + regex.h syslog.h ulimit.h elf.h) | |
33 | AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h \ | |
34 | sys/resource.h sys/param.h sys/socket.h sys/stat.h \ | |
35 | sys/time.h sys/times.h sys/types.h sys/wait.h) | |
36 | @@ -723,7 +723,7 @@ dnl checks for system calls | |
37 | AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getgroups gethostname \ | |
38 | getpagesize getpeername getrlimit getrusage gettimeofday \ | |
39 | kill killpg lstat readlink sbrk select setdtablesize \ | |
40 | - setitimer tcgetpgrp uname ulimit waitpid) | |
41 | + setitimer tcgetpgrp uname ulimit waitpid pread) | |
42 | AC_REPLACE_FUNCS(rename) | |
43 | ||
44 | dnl checks for c library functions | |
45 | diff -up bash-4.2-rc2/execute_cmd.c.interpreter bash-4.2-rc2/execute_cmd.c | |
46 | --- bash-4.2-rc2/execute_cmd.c.interpreter 2011-01-20 04:24:47.000000000 +0100 | |
47 | +++ bash-4.2-rc2/execute_cmd.c 2011-02-09 07:59:21.000000000 +0100 | |
48 | @@ -41,6 +41,10 @@ | |
49 | # include <unistd.h> | |
50 | #endif | |
51 | ||
52 | +#ifdef HAVE_ELF_H | |
53 | +# include <elf.h> | |
54 | +#endif | |
55 | + | |
56 | #include "posixtime.h" | |
57 | ||
58 | #if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE) | |
59 | @@ -4975,14 +4979,22 @@ shell_execve (command, args, env) | |
60 | { | |
61 | /* The file has the execute bits set, but the kernel refuses to | |
62 | run it for some reason. See why. */ | |
63 | +#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H) | |
64 | + int fd = open (command, O_RDONLY); | |
65 | + | |
66 | + if (fd >= 0) | |
67 | + sample_len = read (fd, sample, sizeof (sample)); | |
68 | + else | |
69 | + sample_len = -1; | |
70 | +#endif | |
71 | #if defined (HAVE_HASH_BANG_EXEC) | |
72 | - READ_SAMPLE_BUF (command, sample, sample_len); | |
73 | sample[sample_len - 1] = '\0'; | |
74 | if (sample_len > 2 && sample[0] == '#' && sample[1] == '!') | |
75 | { | |
76 | char *interp; | |
77 | int ilen; | |
78 | ||
79 | + close (fd); | |
80 | interp = getinterp (sample, sample_len, (int *)NULL); | |
81 | ilen = strlen (interp); | |
82 | errno = i; | |
83 | @@ -4997,6 +5009,136 @@ shell_execve (command, args, env) | |
84 | return (EX_NOEXEC); | |
85 | } | |
86 | #endif | |
87 | +#if defined (HAVE_ELF_H) | |
88 | + if (i == ENOENT | |
89 | + && sample_len > EI_NIDENT | |
90 | + && memcmp (sample, ELFMAG, SELFMAG) == 0) | |
91 | + { | |
92 | + off_t offset = -1; | |
93 | + | |
94 | + /* It is an ELF file. Now determine whether it is dynamically | |
95 | + linked and if yes, get the offset of the interpreter | |
96 | + string. */ | |
97 | + if (sample[EI_CLASS] == ELFCLASS32 | |
98 | + && sample_len > sizeof (Elf32_Ehdr)) | |
99 | + { | |
100 | + Elf32_Ehdr ehdr; | |
101 | + Elf32_Phdr *phdr; | |
102 | + int nphdr; | |
103 | + | |
104 | + /* We have to copy the data since the sample buffer | |
105 | + might not be aligned correctly to be accessed as | |
106 | + an Elf32_Ehdr struct. */ | |
107 | + memcpy (&ehdr, sample, sizeof (Elf32_Ehdr)); | |
108 | + | |
109 | + nphdr = ehdr.e_phnum; | |
110 | + phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize); | |
111 | + if (phdr != NULL) | |
112 | + { | |
113 | +#ifdef HAVE_PREAD | |
114 | + sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize, | |
115 | + ehdr.e_phoff); | |
116 | +#else | |
117 | + if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1) | |
118 | + sample_len = read (fd, phdr, | |
119 | + nphdr * ehdr.e_phentsize); | |
120 | + else | |
121 | + sample_len = -1; | |
122 | +#endif | |
123 | + if (sample_len == nphdr * ehdr.e_phentsize) | |
124 | + while (nphdr-- > 0) | |
125 | + if (phdr[nphdr].p_type == PT_INTERP) | |
126 | + { | |
127 | + offset = phdr[nphdr].p_offset; | |
128 | + break; | |
129 | + } | |
130 | + free (phdr); | |
131 | + } | |
132 | + } | |
133 | + else if (sample[EI_CLASS] == ELFCLASS64 | |
134 | + && sample_len > sizeof (Elf64_Ehdr)) | |
135 | + { | |
136 | + Elf64_Ehdr ehdr; | |
137 | + Elf64_Phdr *phdr; | |
138 | + int nphdr; | |
139 | + | |
140 | + /* We have to copy the data since the sample buffer | |
141 | + might not be aligned correctly to be accessed as | |
142 | + an Elf64_Ehdr struct. */ | |
143 | + memcpy (&ehdr, sample, sizeof (Elf64_Ehdr)); | |
144 | + | |
145 | + nphdr = ehdr.e_phnum; | |
146 | + phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize); | |
147 | + if (phdr != NULL) | |
148 | + { | |
149 | +#ifdef HAVE_PREAD | |
150 | + sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize, | |
151 | + ehdr.e_phoff); | |
152 | +#else | |
153 | + if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1) | |
154 | + sample_len = read (fd, phdr, | |
155 | + nphdr * ehdr.e_phentsize); | |
156 | + else | |
157 | + sample_len = -1; | |
158 | +#endif | |
159 | + if (sample_len == nphdr * ehdr.e_phentsize) | |
160 | + while (nphdr-- > 0) | |
161 | + if (phdr[nphdr].p_type == PT_INTERP) | |
162 | + { | |
163 | + offset = phdr[nphdr].p_offset; | |
164 | + break; | |
165 | + } | |
166 | + free (phdr); | |
167 | + } | |
168 | + } | |
169 | + | |
170 | + if (offset != -1) | |
171 | + { | |
172 | + size_t maxlen = 0; | |
173 | + size_t actlen = 0; | |
174 | + char *interp = NULL; | |
175 | + | |
176 | + do | |
177 | + { | |
178 | + if (actlen == maxlen) | |
179 | + { | |
180 | + char *newinterp = realloc (interp, maxlen += 200); | |
181 | + if (newinterp == NULL) | |
182 | + { | |
183 | + actlen = 0; | |
184 | + break; | |
185 | + } | |
186 | + interp = newinterp; | |
187 | + | |
188 | +#ifdef HAVE_PREAD | |
189 | + actlen = pread (fd, interp, maxlen, offset); | |
190 | +#else | |
191 | + if (lseek (fd, offset, SEEK_SET) != -1) | |
192 | + actlen = read (fd, interp, maxlen); | |
193 | + else | |
194 | + actlen = -1; | |
195 | +#endif | |
196 | + } | |
197 | + } | |
198 | + while (actlen > 0 && memchr (interp, '\0', actlen) == NULL); | |
199 | + | |
200 | + if (actlen > 0) | |
201 | + { | |
202 | + close (fd); | |
203 | + errno = i; | |
204 | + sys_error ("%s: %s: bad ELF interpreter", command, | |
205 | + interp); | |
206 | + free (interp); | |
207 | + return (EX_NOEXEC); | |
208 | + } | |
209 | + | |
210 | + free (interp); | |
211 | + } | |
212 | + } | |
213 | +#endif | |
214 | +#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H) | |
215 | + close (fd); | |
216 | +#endif | |
217 | errno = i; | |
218 | file_error (command); | |
219 | } |