mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 02:40:08 +00:00
Prevent unintended file desriptor leak in grantpt.
The pt_chown program is completely transparently called. It might not be able to live with the various file descriptors the program has open at the time of the call (e.g., under SELinux). Close all but the needed descriptor and connect stdin, stdout, and stderr with /dev/null. pt_chown shouldn't print anything when called to do real work.
This commit is contained in:
parent
fa214705b9
commit
139ee080b6
@ -1,5 +1,11 @@
|
||||
2009-11-24 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/grantpt.c (grantpt): Use CLOSE_ALL_FDS is available
|
||||
before the exec.
|
||||
* sysdeps/unix/sysv/linux/grantpt.c: New file.
|
||||
* login/programs/pt_chown.c (main): Don't print message on errors
|
||||
when doing real work.
|
||||
|
||||
* sysdeps/unix/grantpt.c (grantpt): Only get tty group information
|
||||
once.
|
||||
|
||||
|
@ -154,8 +154,7 @@ main (int argc, char *argv[])
|
||||
# define ncap_list (sizeof (cap_list) / sizeof (cap_list[0]))
|
||||
cap_t caps = cap_init ();
|
||||
if (caps == NULL)
|
||||
error (FAIL_ENOMEM, errno,
|
||||
_("Failed to initialize drop of capabilities"));
|
||||
return FAIL_ENOMEM;
|
||||
|
||||
/* There is no reason why these should not work. */
|
||||
cap_set_flag (caps, CAP_PERMITTED, ncap_list, cap_list, CAP_SET);
|
||||
@ -166,7 +165,7 @@ main (int argc, char *argv[])
|
||||
cap_free (caps);
|
||||
|
||||
if (__builtin_expect (res != 0, 0))
|
||||
error (FAIL_EXEC, errno, _("cap_set_proc failed"));
|
||||
return FAIL_EXEC;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -194,6 +194,10 @@ grantpt (int fd)
|
||||
if (__dup2 (fd, PTY_FILENO) < 0)
|
||||
_exit (FAIL_EBADF);
|
||||
|
||||
#ifdef CLOSE_ALL_FDS
|
||||
CLOSE_ALL_FDS ();
|
||||
#endif
|
||||
|
||||
execle (_PATH_PT_CHOWN, basename (_PATH_PT_CHOWN), NULL, NULL);
|
||||
_exit (FAIL_EXEC);
|
||||
}
|
||||
|
42
sysdeps/unix/sysv/linux/grantpt.c
Normal file
42
sysdeps/unix/sysv/linux/grantpt.c
Normal file
@ -0,0 +1,42 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "not-cancel.h"
|
||||
#include "pty-private.h"
|
||||
|
||||
|
||||
/* Close all file descriptors except the one specified. */
|
||||
static void
|
||||
close_all_fds (void)
|
||||
{
|
||||
DIR *dir = opendir ("/proc/self/fd");
|
||||
if (dir != NULL)
|
||||
{
|
||||
struct dirent64 *d;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (isdigit (d->d_name[0]))
|
||||
{
|
||||
char *endp;
|
||||
long int fd = strtol (d->d_name, &endp, 10);
|
||||
if (*endp == '\0' && fd != PTY_FILENO && fd != dirfd (dir))
|
||||
close_not_cancel_no_status (fd);
|
||||
}
|
||||
|
||||
closedir (dir);
|
||||
|
||||
int nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_RDONLY);
|
||||
assert (nullfd == STDIN_FILENO);
|
||||
nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_WRONLY);
|
||||
assert (nullfd == STDOUT_FILENO);
|
||||
__dup2 (STDOUT_FILENO, STDERR_FILENO);
|
||||
}
|
||||
}
|
||||
#define CLOSE_ALL_FDS() close_all_fds()
|
||||
|
||||
#include <sysdeps/unix/grantpt.c>
|
Loading…
Reference in New Issue
Block a user