summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-07-07 06:51:05 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-11-16 19:34:52 -0800
commit515616d259089315f440ce5d80f201da4819ee1d (patch)
tree9adcb3aca2493b36d568dd2c063c94324a2d35eb
parentd7256ca37afb78f351d3c2a944b4ed2f3a3b4cdf (diff)
downloadcygnal-515616d259089315f440ce5d80f201da4819ee1d.tar.gz
cygnal-515616d259089315f440ce5d80f201da4819ee1d.tar.bz2
cygnal-515616d259089315f440ce5d80f201da4819ee1d.zip
Use COMSPEC env var, not hard-coded CMD.EXE path.
It is with some reluctance I make this change, due to the security implications of relying on environment variables. But we can't have a hard-coded path. * winsup/cygwin/include/paths.h (_PATH_CMDEXE): Macro removed. * winsup/cygwin/spawn.cc (av::setup): Use COMSPEC environment variable instead of hard-coded path. If missing, bail with errno set to EOPNOTSUPP. * winsup/cygwin/syscalls.cc (system): Use COMSPEC environment variable. If missing, return -1. (getusershell): Eliminate static array of shell names. If shell_index is zero, return value of COMSPEC env var, if it exists, and increment shell_index to 1. (popen): Use COMSPEC and if that is missing, set errno to EOPNOTSUPP and return NULL.
-rw-r--r--winsup/cygwin/include/paths.h1
-rw-r--r--winsup/cygwin/spawn.cc5
-rw-r--r--winsup/cygwin/syscalls.cc38
3 files changed, 25 insertions, 19 deletions
diff --git a/winsup/cygwin/include/paths.h b/winsup/cygwin/include/paths.h
index cf25056d8..8dc9594fc 100644
--- a/winsup/cygwin/include/paths.h
+++ b/winsup/cygwin/include/paths.h
@@ -29,5 +29,4 @@ details. */
#define _PATH_VARTMP "/var/tmp/"
#define _PATH_VI "/bin/vi"
#define _PATH_WTMP "/var/log/wtmp"
-#define _PATH_CMDEXE "C:/Windows/System32/cmd.exe"
#endif /* _PATHS_H_ */
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 758447e9d..7ea2fca1c 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -1166,7 +1166,10 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext,
}
if (ascii_strcasematch (ext, ".com"))
break;
- pgm = (char *) _PATH_CMDEXE;
+ if ((pgm = getenv("COMSPEC")) == NULL) {
+ set_errno (EOPNOTSUPP);
+ return -1;
+ }
arg1 = NULL;
}
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index db5411fff..53b3714b4 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2617,15 +2617,19 @@ system (const char *cmdstring)
int res = -1;
const char* command[4];
+ const char *cmdexe = getenv("COMSPEC");
+
+ if (cmdexe == NULL)
+ return res;
__try
{
- command[0] = _PATH_CMDEXE;
+ command[0] = cmdexe;
command[1] = "/c";
command[2] = cmdstring;
command[3] = (const char *) NULL;
- if ((res = spawnvp (_P_SYSTEM, _PATH_CMDEXE, command)) == -1)
+ if ((res = spawnvp (_P_SYSTEM, cmdexe, command)) == -1)
{
// when exec fails, return value should be as if shell
// executed exit (127)
@@ -4152,19 +4156,13 @@ static int shell_index;
extern "C" char *
getusershell ()
{
- /* List of default shells if no /etc/shells exists, defined as on Linux.
- FIXME: SunOS has a far longer list, containing all shells which
- might be shipped with the OS. Should we do the same for the Cygwin
- distro, adding bash, tcsh, ksh, pdksh and zsh? */
- static const char *def_shells[] = {
- _PATH_CMDEXE,
- NULL
- };
-
- static char buf[PATH_MAX];
-
- if (def_shells[shell_index])
- return strcpy (buf, def_shells[shell_index++]);
+ if (shell_index == 0) {
+ char *cmdexe = getenv("COMSPEC");
+ if (cmdexe != NULL) {
+ shell_index = 1;
+ return cmdexe;
+ }
+ }
return NULL;
}
@@ -4204,10 +4202,16 @@ popen (const char *command, const char *in_type)
const char *type = in_type;
char fdopen_flags[3] = "\0\0";
int pipe_flags = 0;
+ const char *cmdexe = getenv("COMSPEC");
#define rw fdopen_flags[0]
#define bintext fdopen_flags[1]
+ if (cmdexe == NULL) {
+ set_errno (EOPNOTSUPP);
+ return NULL;
+ }
+
/* Sanity check. GLibc allows any order and any number of repetition,
as long as the string doesn't contradict itself. We do the same here. */
while (*type)
@@ -4275,7 +4279,7 @@ popen (const char *command, const char *in_type)
const char *argv[4] =
{
- _PATH_CMDEXE,
+ cmdexe,
"/c",
command,
NULL
@@ -4296,7 +4300,7 @@ popen (const char *command, const char *in_type)
fcntl64 (stdchild, F_SETFD, stdchild_state | FD_CLOEXEC);
/* Start a shell process to run the given command without forking. */
- pid_t pid = ch_spawn.worker (_PATH_CMDEXE, argv, cur_environ (),
+ pid_t pid = ch_spawn.worker (cmdexe, argv, cur_environ (),
_P_NOWAIT, __std[0], __std[1]);
/* Reinstate the close-on-exec state */