diff options
author | Ron Yorston <rmy@pobox.com> | 2023-11-14 11:15:02 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-11-14 11:15:02 +0000 |
commit | f444dc586b16c104a82d201d3a7caca68affe51b (patch) | |
tree | 6e39b32ab1385f6a67d5a0ddf98c4b0d33d59148 | |
parent | 5085fe5d56e63f23f9812bd120a8453bd6589edc (diff) | |
download | busybox-w32-f444dc586b16c104a82d201d3a7caca68affe51b.tar.gz busybox-w32-f444dc586b16c104a82d201d3a7caca68affe51b.tar.bz2 busybox-w32-f444dc586b16c104a82d201d3a7caca68affe51b.zip |
win32: only search PATH for compressor
mingw_fork_compressor() uses CreateProcess() to run the compressor
program. This will often be an instance of BusyBox, but since the
xv and lzma applets in BusyBox don't support compression it can be
an external program.
It was intended that the external program should be found using PATH.
However, CreateProcess() looks in various other places before trying
PATH. In particular, it first looks in the directory of the current
executable, then in the current directory of the process. This can
result in the wrong xz.exe or lzma.exe being found.
Perform an explicit PATH search and force CreateProcess() to use the
result.
This change only affects the search for a compressor. The same
problem also affects other uses of our popen(3) emulation. These
may be addressed in future.
Costs 64-80 bytes.
(GitHub issue #376)
-rw-r--r-- | include/mingw.h | 3 | ||||
-rw-r--r-- | networking/wget.c | 2 | ||||
-rw-r--r-- | win32/popen.c | 30 |
3 files changed, 21 insertions, 14 deletions
diff --git a/include/mingw.h b/include/mingw.h index f6f0bf262..eab756184 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -136,7 +136,8 @@ int mingw_rename(const char*, const char*); | |||
136 | #define rename mingw_rename | 136 | #define rename mingw_rename |
137 | 137 | ||
138 | FILE *mingw_popen(const char *cmd, const char *mode); | 138 | FILE *mingw_popen(const char *cmd, const char *mode); |
139 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid); | 139 | int mingw_popen_fd(const char *exe, const char *cmd, const char *mode, |
140 | int fd0, pid_t *pid); | ||
140 | int mingw_pclose(FILE *fd); | 141 | int mingw_pclose(FILE *fd); |
141 | pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode); | 142 | pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode); |
142 | #undef popen | 143 | #undef popen |
diff --git a/networking/wget.c b/networking/wget.c index e0c66edba..f9e463f6c 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -844,7 +844,7 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) | |||
844 | (void *)_get_osfhandle(network_fd), servername, | 844 | (void *)_get_osfhandle(network_fd), servername, |
845 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); | 845 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); |
846 | 846 | ||
847 | if ( (fd1=mingw_popen_fd(cmd, "b", -1, NULL)) == -1 ) { | 847 | if ( (fd1=mingw_popen_fd(NULL, cmd, "b", -1, NULL)) == -1 ) { |
848 | bb_perror_msg_and_die("can't execute ssl_client"); | 848 | bb_perror_msg_and_die("can't execute ssl_client"); |
849 | } | 849 | } |
850 | 850 | ||
diff --git a/win32/popen.c b/win32/popen.c index 2208aa6bb..79433a27b 100644 --- a/win32/popen.c +++ b/win32/popen.c | |||
@@ -11,8 +11,8 @@ typedef struct { | |||
11 | static pipe_data *pipes = NULL; | 11 | static pipe_data *pipes = NULL; |
12 | static int num_pipes = 0; | 12 | static int num_pipes = 0; |
13 | 13 | ||
14 | static int mingw_popen_internal(pipe_data *p, const char *cmd, | 14 | static int mingw_popen_internal(pipe_data *p, const char *exe, |
15 | const char *mode, int fd0, pid_t *pid); | 15 | const char *cmd, const char *mode, int fd0, pid_t *pid); |
16 | 16 | ||
17 | static int mingw_pipe(pipe_data *p, int bidi) | 17 | static int mingw_pipe(pipe_data *p, int bidi) |
18 | { | 18 | { |
@@ -162,7 +162,7 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
162 | *t = '\0'; | 162 | *t = '\0'; |
163 | 163 | ||
164 | /* Create the pipe */ | 164 | /* Create the pipe */ |
165 | if ((fd=mingw_popen_internal(p, cmd_buff, mode, -1, NULL)) != -1) { | 165 | if ((fd=mingw_popen_internal(p, NULL, cmd_buff, mode, -1, NULL)) != -1) { |
166 | fptr = _fdopen(fd, *mode == 'r' ? "rb" : "wb"); | 166 | fptr = _fdopen(fd, *mode == 'r' ? "rb" : "wb"); |
167 | } | 167 | } |
168 | 168 | ||
@@ -182,8 +182,8 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
182 | * - the pid of the command is returned in the variable pid, which | 182 | * - the pid of the command is returned in the variable pid, which |
183 | * can be NULL if the pid is not required. | 183 | * can be NULL if the pid is not required. |
184 | */ | 184 | */ |
185 | static int mingw_popen_internal(pipe_data *p, const char *cmd, | 185 | static int mingw_popen_internal(pipe_data *p, const char *exe, |
186 | const char *mode, int fd0, pid_t *pid) | 186 | const char *cmd, const char *mode, int fd0, pid_t *pid) |
187 | { | 187 | { |
188 | pipe_data pd; | 188 | pipe_data pd; |
189 | STARTUPINFO siStartInfo; | 189 | STARTUPINFO siStartInfo; |
@@ -245,8 +245,8 @@ static int mingw_popen_internal(pipe_data *p, const char *cmd, | |||
245 | siStartInfo.wShowWindow = SW_HIDE; | 245 | siStartInfo.wShowWindow = SW_HIDE; |
246 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; | 246 | siStartInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; |
247 | 247 | ||
248 | success = CreateProcess(NULL, | 248 | success = CreateProcess((LPCSTR)exe, |
249 | (LPTSTR)cmd, /* command line */ | 249 | (LPSTR)cmd, /* command line */ |
250 | NULL, /* process security attributes */ | 250 | NULL, /* process security attributes */ |
251 | NULL, /* primary thread security attributes */ | 251 | NULL, /* primary thread security attributes */ |
252 | TRUE, /* handles are inherited */ | 252 | TRUE, /* handles are inherited */ |
@@ -280,9 +280,10 @@ finito: | |||
280 | return fd; | 280 | return fd; |
281 | } | 281 | } |
282 | 282 | ||
283 | int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid) | 283 | int mingw_popen_fd(const char *exe, const char *cmd, const char *mode, |
284 | int fd0, pid_t *pid) | ||
284 | { | 285 | { |
285 | return mingw_popen_internal(NULL, cmd, mode, fd0, pid); | 286 | return mingw_popen_internal(NULL, exe, cmd, mode, fd0, pid); |
286 | } | 287 | } |
287 | 288 | ||
288 | int mingw_pclose(FILE *fp) | 289 | int mingw_pclose(FILE *fp) |
@@ -310,7 +311,7 @@ int mingw_pclose(FILE *fp) | |||
310 | * file; with mode "r" and a decompressor in open_transformer. */ | 311 | * file; with mode "r" and a decompressor in open_transformer. */ |
311 | pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) | 312 | pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) |
312 | { | 313 | { |
313 | char *cmd; | 314 | char *cmd, *exe = NULL; |
314 | int fd1; | 315 | int fd1; |
315 | pid_t pid; | 316 | pid_t pid; |
316 | 317 | ||
@@ -322,20 +323,25 @@ pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) | |||
322 | && !(mode[0] == 'w' && index_in_strings("lzma\0xz\0", compressor) >= 0) | 323 | && !(mode[0] == 'w' && index_in_strings("lzma\0xz\0", compressor) >= 0) |
323 | # endif | 324 | # endif |
324 | ) { | 325 | ) { |
326 | // shared format string | ||
325 | cmd = xasprintf("%s --busybox %s -cf -", bb_busybox_exec_path, | 327 | cmd = xasprintf("%s --busybox %s -cf -", bb_busybox_exec_path, |
326 | compressor); | 328 | compressor); |
327 | } else { | 329 | } else { |
328 | // share format string | 330 | // Look up compressor on PATH |
331 | exe = find_first_executable(compressor); | ||
332 | if (exe == NULL) | ||
333 | bb_perror_msg_and_die("can't execute '%s'", compressor); | ||
329 | cmd = xasprintf("%s --busybox %s -cf -" + 13, compressor); | 334 | cmd = xasprintf("%s --busybox %s -cf -" + 13, compressor); |
330 | } | 335 | } |
331 | #else | 336 | #else |
332 | cmd = xasprintf("%s -cf -", compressor); | 337 | cmd = xasprintf("%s -cf -", compressor); |
333 | #endif | 338 | #endif |
334 | 339 | ||
335 | if ((fd1 = mingw_popen_fd(cmd, mode, fd, &pid)) == -1) | 340 | if ((fd1 = mingw_popen_fd(exe, cmd, mode, fd, &pid)) == -1) |
336 | bb_perror_msg_and_die("can't execute '%s'", compressor); | 341 | bb_perror_msg_and_die("can't execute '%s'", compressor); |
337 | 342 | ||
338 | free(cmd); | 343 | free(cmd); |
344 | free(exe); | ||
339 | xmove_fd(fd1, fd); | 345 | xmove_fd(fd1, fd); |
340 | return pid; | 346 | return pid; |
341 | } | 347 | } |