mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-22 18:22:11 +01:00
glib-unix: Ensure g_unix_open_pipe never leaves standard io fd range exposed
It's now possible that g_unix_open_pipe will reject an fd because it's STDIN, STDOUT, or STDERR. Having those fds left open to be used by the next thing is causing buggy apps to fail, since they relied on g_unix_open_pipe using the fds. This commit puts a /dev/null placeholder on an standard fds that g_unix_open_pipe rejects. Closes: https://gitlab.gnome.org/GNOME/glib/-/issues/2795
This commit is contained in:
parent
356676bc5e
commit
ee9c928e06
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "glib-unix.h"
|
#include "glib-unix.h"
|
||||||
#include "gmain-internal.h"
|
#include "gmain-internal.h"
|
||||||
|
#include "gstdio.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -70,6 +71,59 @@ g_unix_set_error_from_errno (GError **error,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
move_pipe_fds_away_from_standard_io_range (int *fds,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
gboolean result = TRUE;
|
||||||
|
|
||||||
|
/* For backward compatibilty with buggy apps, still make sure
|
||||||
|
* the standard fd slots get used up with something harmless
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
int open_flags = 0;
|
||||||
|
int ret;
|
||||||
|
g_autofd int dev_null = -1;
|
||||||
|
|
||||||
|
switch (fds[i])
|
||||||
|
{
|
||||||
|
case STDIN_FILENO:
|
||||||
|
open_flags = O_RDONLY;
|
||||||
|
break;
|
||||||
|
case STDOUT_FILENO:
|
||||||
|
case STDERR_FILENO:
|
||||||
|
open_flags = O_WRONLY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_null = g_open ("/dev/null", open_flags, 0);
|
||||||
|
|
||||||
|
if (dev_null < 0)
|
||||||
|
{
|
||||||
|
g_unix_set_error_from_errno (error, errno);
|
||||||
|
result = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
ret = dup2 (g_steal_fd (&dev_null), fds[i]);
|
||||||
|
while (ret < 0 && (errno == EINTR || errno == EBUSY));
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_unix_set_error_from_errno (error, errno);
|
||||||
|
result = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_unix_open_pipe:
|
* g_unix_open_pipe:
|
||||||
* @fds: (array fixed-size=2): Array of two integers
|
* @fds: (array fixed-size=2): Array of two integers
|
||||||
@ -111,10 +165,14 @@ g_unix_open_pipe (int *fds,
|
|||||||
/* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
|
/* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
|
||||||
else if (fds[0] < 3 || fds[1] < 3)
|
else if (fds[0] < 3 || fds[1] < 3)
|
||||||
{
|
{
|
||||||
int old_fds[2] = { fds[0], fds[1] };
|
gboolean result;
|
||||||
gboolean result = g_unix_open_pipe (fds, flags, error);
|
|
||||||
close (old_fds[0]);
|
result = move_pipe_fds_away_from_standard_io_range (fds, error);
|
||||||
close (old_fds[1]);
|
|
||||||
|
if (!result)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
result = g_unix_open_pipe (fds, flags, error);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -129,10 +187,14 @@ g_unix_open_pipe (int *fds,
|
|||||||
/* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
|
/* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
|
||||||
else if (fds[0] < 3 || fds[1] < 3)
|
else if (fds[0] < 3 || fds[1] < 3)
|
||||||
{
|
{
|
||||||
int old_fds[2] = { fds[0], fds[1] };
|
gboolean result;
|
||||||
gboolean result = g_unix_open_pipe (fds, flags, error);
|
|
||||||
close (old_fds[0]);
|
result = move_pipe_fds_away_from_standard_io_range (fds, error);
|
||||||
close (old_fds[1]);
|
|
||||||
|
if (!result)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
result = g_unix_open_pipe (fds, flags, error);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user