From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org, Florian Weimer <fweimer@redhat.com>
Subject: Re: [PATCH 3/3] Linux: Require properly configured /dev/pts for PTYs
Date: Thu, 13 Aug 2020 15:53:02 -0300 [thread overview]
Message-ID: <7a9a5134-e00f-0e31-fa9b-863069559a73@linaro.org> (raw)
In-Reply-To: <19aaa58053302c7ed010e61b7b2b53b993e3ed5a.1596611597.git.fweimer@redhat.com>
On 05/08/2020 04:14, Florian Weimer via Libc-alpha wrote:
> Current systems do not have BSD terminals, so the fallback code in
> posix_openpt/getpt does not do anything. Also remove the file system
> check for /dev/pts. Current systems always have a devpts file system
> mounted there if /dev/ptmx exists.
>
> grantpt is now essentially a no-op. It only verifies that the
> argument is a ptmx-descriptor. Therefore, this change indirectly
> addresses bug 24941.
I think it should also adjust the documentation on INSTALL and
manual/install.texi to state pt_chown is now not used on Linux anymore
(thus configuring glibc with --enable-pt_chown will still install the
binary, but glibc won't use it directly).
Besides it, the patch looks ok with just a nit on __posix_openpt
internal definition.
Maybe we can now move the pt_chown to be Hurd-only and thus removing
--enable-pt_chown option.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> NEWS | 12 +++-
> sysdeps/unix/sysv/linux/getpt.c | 67 +---------------------
> sysdeps/unix/sysv/linux/grantpt.c | 73 ++++++++++++------------
> sysdeps/unix/sysv/linux/ptsname.c | 95 ++-----------------------------
> 4 files changed, 54 insertions(+), 193 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index 2937adc3f3..7bdfe211c9 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -17,7 +17,17 @@ Deprecated and removed features, and other changes affecting compatibility:
>
> Changes to build and runtime requirements:
>
> - [Add changes to build and runtime requirements here]
> +* On Linux, the system administrator needs to configure /dev/pts with
> + the intended access modes for pseudo-terminals. glibc no longer
> + attemps to adjust permissions of terminal devices. The previous glibc
> + defaults ("tty" group, user read/write and group write) already
> + corresponded to what most systems used, so that grantpt did not
> + perform any adjustments.
> +
> +* On Linux, the posix_openpt and getpt functions no longer attempt to
> + use legacy (BSD) pseudo-terminals and assume that if /dev/ptmx exists
> + (and pseudo-terminals are supported), a devpts file system is mounted
> + on /dev/pts. Current systems already meet these requirements.
>
> Security related changes:
>
> diff --git a/sysdeps/unix/sysv/linux/getpt.c b/sysdeps/unix/sysv/linux/getpt.c
> index 1803b232c9..3cc745e11a 100644
> --- a/sysdeps/unix/sysv/linux/getpt.c
> +++ b/sysdeps/unix/sysv/linux/getpt.c
> @@ -16,69 +16,18 @@
> License along with the GNU C Library; if not, see
> <https://www.gnu.org/licenses/>. */
>
> -#include <errno.h>
> #include <fcntl.h>
> -#include <stdlib.h>
> #include <unistd.h>
> #include <paths.h>
> -#include <sys/statfs.h>
> -
> -#include "linux_fsinfo.h"
>
> /* Path to the master pseudo terminal cloning device. */
> #define _PATH_DEVPTMX _PATH_DEV "ptmx"
> -/* Directory containing the UNIX98 pseudo terminals. */
> -#define _PATH_DEVPTS _PATH_DEV "pts"
> -
> -/* Prototype for function that opens BSD-style master pseudo-terminals. */
> -extern int __bsd_getpt (void) attribute_hidden;
>
> /* Open a master pseudo terminal and return its file descriptor. */
> int
> __posix_openpt (int oflag)
> {
> - static int have_no_dev_ptmx;
> - int fd;
> -
> - if (!have_no_dev_ptmx)
> - {
> - fd = __open (_PATH_DEVPTMX, oflag);
> - if (fd != -1)
> - {
> - struct statfs fsbuf;
> - static int devpts_mounted;
> -
> - /* Check that the /dev/pts filesystem is mounted
> - or if /dev is a devfs filesystem (this implies /dev/pts). */
> - if (devpts_mounted
> - || (__statfs (_PATH_DEVPTS, &fsbuf) == 0
> - && fsbuf.f_type == DEVPTS_SUPER_MAGIC)
> - || (__statfs (_PATH_DEV, &fsbuf) == 0
> - && fsbuf.f_type == DEVFS_SUPER_MAGIC))
> - {
> - /* Everything is ok. */
> - devpts_mounted = 1;
> - return fd;
> - }
> -
> - /* If /dev/pts is not mounted then the UNIX98 pseudo terminals
> - are not usable. */
> - __close (fd);
> - have_no_dev_ptmx = 1;
> - __set_errno (ENOENT);
> - }
> - else
> - {
> - if (errno == ENOENT || errno == ENODEV)
> - have_no_dev_ptmx = 1;
> - else
> - return -1;
> - }
> - }
> - else
> - __set_errno (ENOENT);
> -
> - return -1;
> + return __open (_PATH_DEVPTMX, oflag);
> }
> weak_alias (__posix_openpt, posix_openpt)
>
Ok. Not really required, but maybe use open64 so we remove non-LFS usage
internally?
Also, __posix_openpt is defined as attribute_hidden but at same time
exported. Afaiu this is not really supported (although binutils has not
triggered an issue in most cases) so maybe use a proper
hidden_def/hidden_proto here?
> @@ -86,16 +35,6 @@ weak_alias (__posix_openpt, posix_openpt)
> int
> __getpt (void)
> {
> - int fd = __posix_openpt (O_RDWR);
> - if (fd == -1)
> - fd = __bsd_getpt ();
> - return fd;
> + return __posix_openpt (O_RDWR);
> }
> -
> -
> -#define PTYNAME1 "pqrstuvwxyzabcde";
> -#define PTYNAME2 "0123456789abcdef";
> -
> -#define __getpt __bsd_getpt
> -#define HAVE_POSIX_OPENPT
> -#include <sysdeps/unix/bsd/getpt.c>
> +weak_alias (__getpt, getpt)
Ok.
> diff --git a/sysdeps/unix/sysv/linux/grantpt.c b/sysdeps/unix/sysv/linux/grantpt.c
> index 2030e07fa6..43122f9a76 100644
> --- a/sysdeps/unix/sysv/linux/grantpt.c
> +++ b/sysdeps/unix/sysv/linux/grantpt.c
> @@ -1,44 +1,41 @@
> -#include <assert.h>
> -#include <ctype.h>
> -#include <dirent.h>
> -#include <errno.h>
> -#include <fcntl.h>
> -#include <paths.h>
> -#include <stdlib.h>
> -#include <unistd.h>
> +/* grantpt implementation for Linux.
> + Copyright (C) 1998-2020 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> + Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
>
> -#include <not-cancel.h>
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
>
> -#include "pty-private.h"
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
>
> -#if HAVE_PT_CHOWN
> -/* 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_nocancel_nostatus (fd);
> - }
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/ioctl.h>
> +#include <termios.h>
>
> - __closedir (dir);
> +int
> +grantpt (int fd)
> +{
> + /* Without pt_chown on Linux, we have delegated the creation of the
> + pty node with the right group and permission mode to the kernel, and
> + non-root users are unlikely to be able to change it. Therefore let's
> + consider that POSIX enforcement is the responsibility of the whole
> + system and not only the GNU libc. */
>
> - int nullfd = __open_nocancel (_PATH_DEVNULL, O_RDONLY);
> - assert (nullfd == STDIN_FILENO);
> - nullfd = __open_nocancel (_PATH_DEVNULL, O_WRONLY);
> - assert (nullfd == STDOUT_FILENO);
> - __dup2 (STDOUT_FILENO, STDERR_FILENO);
> - }
> + /* Verify that fd refers to a ptmx descriptor. */
> + unsigned int ptyno;
> + int ret = __ioctl (fd, TIOCGPTN, &ptyno);
> + if (ret != 0 && errno == ENOTTY)
> + /* POSIX requires EINVAL instead of ENOTTY provided by the kernel. */
> + __set_errno (EINVAL);
> + return ret;
> }
> -# define CLOSE_ALL_FDS() close_all_fds()
> -#endif
> -
> -#include <sysdeps/unix/grantpt.c>
Ok.
> diff --git a/sysdeps/unix/sysv/linux/ptsname.c b/sysdeps/unix/sysv/linux/ptsname.c
> index 81d9d26f1e..3e9be3f0d4 100644
> --- a/sysdeps/unix/sysv/linux/ptsname.c
> +++ b/sysdeps/unix/sysv/linux/ptsname.c
> @@ -21,39 +21,14 @@
> #include <stdlib.h>
> #include <string.h>
> #include <sys/ioctl.h>
> -#include <sys/stat.h>
> -#include <sys/sysmacros.h>
> #include <termios.h>
> #include <unistd.h>
>
> #include <_itoa.h>
>
> -/* Check if DEV corresponds to a master pseudo terminal device. */
> -#define MASTER_P(Dev) \
> - (__gnu_dev_major ((Dev)) == 2 \
> - || (__gnu_dev_major ((Dev)) == 4 \
> - && __gnu_dev_minor ((Dev)) >= 128 && __gnu_dev_minor ((Dev)) < 192) \
> - || (__gnu_dev_major ((Dev)) >= 128 && __gnu_dev_major ((Dev)) < 136))
> -
> -/* Check if DEV corresponds to a slave pseudo terminal device. */
> -#define SLAVE_P(Dev) \
> - (__gnu_dev_major ((Dev)) == 3 \
> - || (__gnu_dev_major ((Dev)) == 4 \
> - && __gnu_dev_minor ((Dev)) >= 192 && __gnu_dev_minor ((Dev)) < 256) \
> - || (__gnu_dev_major ((Dev)) >= 136 && __gnu_dev_major ((Dev)) < 144))
> -
> -/* Note that major number 4 corresponds to the old BSD style pseudo
> - terminal devices. As of Linux 2.1.115 these are no longer
> - supported. They have been replaced by major numbers 2 (masters)
> - and 3 (slaves). */
> -
> /* Directory where we can find the slave pty nodes. */
> #define _PATH_DEVPTS "/dev/pts/"
>
> -/* The are declared in getpt.c. */
> -extern const char __libc_ptyname1[] attribute_hidden;
> -extern const char __libc_ptyname2[] attribute_hidden;
> -
> /* Static buffer for `ptsname'. */
> static char buffer[sizeof (_PATH_DEVPTS) + 20];
>
> @@ -68,19 +43,15 @@ ptsname (int fd)
> }
>
>
> +/* Store at most BUFLEN characters of the pathname of the slave pseudo
> + terminal associated with the master FD is open on in BUF.
> + Return 0 on success, otherwise an error number. */
> int
> -__ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp)
> +__ptsname_r (int fd, char *buf, size_t buflen)
> {
> int save_errno = errno;
> unsigned int ptyno;
>
> - if (!__isatty (fd))
> - {
> - __set_errno (ENOTTY);
> - return ENOTTY;
> - }
> -
> -#ifdef TIOCGPTN
> if (__ioctl (fd, TIOCGPTN, &ptyno) == 0)
> {
> /* Buffer we use to print the number in. For a maximum size for
> @@ -101,67 +72,11 @@ __ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp)
>
> memcpy (__stpcpy (buf, devpts), p, &numbuf[sizeof (numbuf)] - p);
> }
> - else if (errno != EINVAL)
> - return errno;
> else
> -#endif
> - {
> - char *p;
> -
> - if (buflen < strlen (_PATH_TTY) + 3)
> - {
> - __set_errno (ERANGE);
> - return ERANGE;
> - }
> -
> - if (__fxstat64 (_STAT_VER, fd, stp) < 0)
> - return errno;
> -
> - /* Check if FD really is a master pseudo terminal. */
> - if (! MASTER_P (stp->st_rdev))
> - {
> - __set_errno (ENOTTY);
> - return ENOTTY;
> - }
> -
> - ptyno = __gnu_dev_minor (stp->st_rdev);
> -
> - if (ptyno / 16 >= strlen (__libc_ptyname1))
> - {
> - __set_errno (ENOTTY);
> - return ENOTTY;
> - }
> -
> - p = __stpcpy (buf, _PATH_TTY);
> - p[0] = __libc_ptyname1[ptyno / 16];
> - p[1] = __libc_ptyname2[ptyno % 16];
> - p[2] = '\0';
> - }
> -
> - if (__xstat64 (_STAT_VER, buf, stp) < 0)
> + /* Bad file descriptor, or not a ptmx descriptor. */
> return errno;
>
Ok.
> - /* Check if the name we're about to return really corresponds to a
> - slave pseudo terminal. */
> - if (! S_ISCHR (stp->st_mode) || ! SLAVE_P (stp->st_rdev))
> - {
> - /* This really is a configuration problem. */
> - __set_errno (ENOTTY);
> - return ENOTTY;
> - }
> -
> __set_errno (save_errno);
> return 0;
> }
> -
> -
> -/* Store at most BUFLEN characters of the pathname of the slave pseudo
> - terminal associated with the master FD is open on in BUF.
> - Return 0 on success, otherwise an error number. */
> -int
> -__ptsname_r (int fd, char *buf, size_t buflen)
> -{
> - struct stat64 st;
> - return __ptsname_internal (fd, buf, buflen, &st);
> -}
> weak_alias (__ptsname_r, ptsname_r)
>
Ok.
next prev parent reply other threads:[~2020-08-13 18:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-05 7:14 [PATCH 1/3] login/tst-grantpt: Convert to support framework, more error checking Florian Weimer
2020-08-05 7:14 ` [PATCH 2/3] Linux: unlockpt needs to fail with EINVAL, not ENOTTY (bug 26053) Florian Weimer
2020-08-13 18:30 ` Adhemerval Zanella
2020-08-05 7:14 ` [PATCH 3/3] Linux: Require properly configured /dev/pts for PTYs Florian Weimer
2020-08-13 18:53 ` Adhemerval Zanella [this message]
2020-08-13 18:21 ` [PATCH 1/3] login/tst-grantpt: Convert to support framework, more error checking Adhemerval Zanella
2020-08-13 18:31 ` Florian Weimer
2020-08-13 18:58 ` Adhemerval Zanella
-- strict thread matches above, loose matches on Subject: below --
2020-05-27 10:14 [PATCH 0/3] Linux: Rework Linux PTY support Florian Weimer
2020-05-27 10:14 ` [PATCH 3/3] Linux: Require properly configured /dev/pts for PTYs Florian Weimer
2020-05-27 10:31 ` Christian Brauner
2020-10-02 17:20 ` Adhemerval Zanella
2020-10-02 17:26 ` Florian Weimer
2020-10-07 9:31 ` Florian Weimer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7a9a5134-e00f-0e31-fa9b-863069559a73@linaro.org \
--to=adhemerval.zanella@linaro.org \
--cc=fweimer@redhat.com \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).