Don't use insecure popen in getroot.

* util/getroot.c (get_mdadm_uuid): Move pipe logic to ...
	(exec_pipe): ... here.
	(find_root_devices_from_poolname): Use exec_pipe.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-02-27 17:37:23 +01:00
parent 53f13848f1
commit 30ac48c452
2 changed files with 111 additions and 68 deletions

View file

@ -1,3 +1,11 @@
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
Don't use insecure popen in getroot.
* util/getroot.c (get_mdadm_uuid): Move pipe logic to ...
(exec_pipe): ... here.
(find_root_devices_from_poolname): Use exec_pipe.
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com> 2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
Remove platform and target_cpu replacement. Remove platform and target_cpu replacement.

View file

@ -208,6 +208,42 @@ xgetcwd (void)
return path; return path;
} }
static pid_t
exec_pipe (char **argv, int *fd)
{
int mdadm_pipe[2];
pid_t mdadm_pid;
*fd = 0;
if (pipe (mdadm_pipe) < 0)
{
grub_util_warn (_("Unable to create pipe: %s"),
strerror (errno));
return 0;
}
mdadm_pid = fork ();
if (mdadm_pid < 0)
grub_util_error (_("Unable to fork: %s"), strerror (errno));
else if (mdadm_pid == 0)
{
/* Child. */
close (mdadm_pipe[0]);
dup2 (mdadm_pipe[1], STDOUT_FILENO);
close (mdadm_pipe[1]);
execvp (argv[0], argv);
exit (127);
}
else
{
close (mdadm_pipe[1]);
*fd = mdadm_pipe[0];
return mdadm_pid;
}
}
static char ** static char **
find_root_devices_from_poolname (char *poolname) find_root_devices_from_poolname (char *poolname)
{ {
@ -277,7 +313,6 @@ find_root_devices_from_poolname (char *poolname)
zpool_close (zpool); zpool_close (zpool);
#else #else
char *cmd;
FILE *fp; FILE *fp;
int ret; int ret;
char *line; char *line;
@ -287,10 +322,28 @@ find_root_devices_from_poolname (char *poolname)
char name[PATH_MAX + 1], state[257], readlen[257], writelen[257]; char name[PATH_MAX + 1], state[257], readlen[257], writelen[257];
char cksum[257], notes[257]; char cksum[257], notes[257];
unsigned int dummy; unsigned int dummy;
char *argv[4];
pid_t pid;
int fd;
cmd = xasprintf ("zpool status %s", poolname); /* execvp has inconvenient types, hence the casts. None of these
fp = popen (cmd, "r"); strings will actually be modified. */
free (cmd); argv[0] = (char *) "zpool";
argv[1] = (char *) "status";
argv[2] = (char *) poolname;
argv[3] = NULL;
pid = exec_pipe (argv, &fd);
if (!pid)
return NULL;
fp = fdopen (fd, "r");
if (!fp)
{
grub_util_warn (_("Unable to open stream from %s: %s"),
"zpool", strerror (errno));
goto out;
}
st = 0; st = 0;
while (1) while (1)
@ -338,7 +391,9 @@ find_root_devices_from_poolname (char *poolname)
free (line); free (line);
} }
pclose (fp); out:
close (fd);
waitpid (pid, NULL, 0);
#endif #endif
if (devices) if (devices)
{ {
@ -1166,28 +1221,13 @@ grub_util_get_dev_abstraction (const char *os_dev)
static char * static char *
get_mdadm_uuid (const char *os_dev) get_mdadm_uuid (const char *os_dev)
{ {
int mdadm_pipe[2];
pid_t mdadm_pid;
char *name = NULL;
if (pipe (mdadm_pipe) < 0)
{
grub_util_warn (_("Unable to create pipe for mdadm: %s"),
strerror (errno));
return NULL;
}
mdadm_pid = fork ();
if (mdadm_pid < 0)
grub_util_warn (_("Unable to fork mdadm: %s"), strerror (errno));
else if (mdadm_pid == 0)
{
/* Child. */
char *argv[5]; char *argv[5];
int fd;
close (mdadm_pipe[0]); pid_t pid;
dup2 (mdadm_pipe[1], STDOUT_FILENO); FILE *mdadm;
close (mdadm_pipe[1]); char *buf = NULL;
size_t len = 0;
char *name = NULL;
/* execvp has inconvenient types, hence the casts. None of these /* execvp has inconvenient types, hence the casts. None of these
strings will actually be modified. */ strings will actually be modified. */
@ -1196,22 +1236,18 @@ get_mdadm_uuid (const char *os_dev)
argv[2] = (char *) "--export"; argv[2] = (char *) "--export";
argv[3] = (char *) os_dev; argv[3] = (char *) os_dev;
argv[4] = NULL; argv[4] = NULL;
execvp ("mdadm", argv);
exit (127);
}
else
{
/* Parent. Read mdadm's output. */
FILE *mdadm;
char *buf = NULL;
size_t len = 0;
close (mdadm_pipe[1]); pid = exec_pipe (argv, &fd);
mdadm = fdopen (mdadm_pipe[0], "r");
if (!pid)
return NULL;
/* Parent. Read mdadm's output. */
mdadm = fdopen (fd, "r");
if (! mdadm) if (! mdadm)
{ {
grub_util_warn (_("Unable to open stream from mdadm: %s"), grub_util_warn (_("Unable to open stream from %s: %s"),
strerror (errno)); "mdadm", strerror (errno));
goto out; goto out;
} }
@ -1235,9 +1271,8 @@ get_mdadm_uuid (const char *os_dev)
} }
out: out:
close (mdadm_pipe[0]); close (fd);
waitpid (mdadm_pid, NULL, 0); waitpid (pid, NULL, 0);
}
return name; return name;
} }