aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-11-14 11:15:02 +0000
committerRon Yorston <rmy@pobox.com>2023-11-14 11:15:02 +0000
commitf444dc586b16c104a82d201d3a7caca68affe51b (patch)
tree6e39b32ab1385f6a67d5a0ddf98c4b0d33d59148
parent5085fe5d56e63f23f9812bd120a8453bd6589edc (diff)
downloadbusybox-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.h3
-rw-r--r--networking/wget.c2
-rw-r--r--win32/popen.c30
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
138FILE *mingw_popen(const char *cmd, const char *mode); 138FILE *mingw_popen(const char *cmd, const char *mode);
139int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid); 139int mingw_popen_fd(const char *exe, const char *cmd, const char *mode,
140 int fd0, pid_t *pid);
140int mingw_pclose(FILE *fd); 141int mingw_pclose(FILE *fd);
141pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode); 142pid_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 {
11static pipe_data *pipes = NULL; 11static pipe_data *pipes = NULL;
12static int num_pipes = 0; 12static int num_pipes = 0;
13 13
14static int mingw_popen_internal(pipe_data *p, const char *cmd, 14static 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
17static int mingw_pipe(pipe_data *p, int bidi) 17static 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 */
185static int mingw_popen_internal(pipe_data *p, const char *cmd, 185static 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
283int mingw_popen_fd(const char *cmd, const char *mode, int fd0, pid_t *pid) 283int 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
288int mingw_pclose(FILE *fp) 289int 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. */
311pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) 312pid_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}