From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15773 invoked by alias); 10 Nov 2016 18:04:41 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 15751 invoked by uid 89); 10 Nov 2016 18:04:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.5 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=pty, Prepare, HTo:D*canonical.com, H*Ad:U*serge X-HELO: h2.hallyn.com Date: Thu, 10 Nov 2016 18:04:00 -0000 From: "Serge E. Hallyn" To: Christian Brauner Cc: libc-alpha@sourceware.org, serge@hallyn.com Subject: Re: [PATCH] linux ttyname and ttyname_r: do not return wrong results Message-ID: <20161110180436.GA17893@mail.hallyn.com> References: <20161108165638.21674-1-christian.brauner@canonical.com> <20161108165638.21674-2-christian.brauner@canonical.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20161108165638.21674-2-christian.brauner@canonical.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2016-11/txt/msg00412.txt.bz2 Quoting Christian Brauner (christian.brauner@canonical.com): > If a link (say /proc/self/fd/0) pointing to a device, say /dev/pts/2, in a > parent mount namespace is passed to ttyname, and a /dev/pts/2 exists (in a > different devpts) in the current namespace, then it returns /dev/pts/2. But > /dev/pts/2 is NOT the current tty, it is a different file and device. > > Detect this case and return ENODEV. Userspace can choose to take this as a hint > that the fd points to a tty device but to act on the fd rather than the link. > > Signed-off-by: Serge Hallyn > Signed-off-by: Christian Brauner Thanks ! > --- > Changelog: 2016-11-08 > - remove obsolete comment in ttyname_r.c > - move is_pty() to common header file and mark as static inline > --- > sysdeps/unix/sysv/linux/ttyname.c | 17 +++++++++++++---- > sysdeps/unix/sysv/linux/ttyname.h | 35 +++++++++++++++++++++++++++++++++++ > sysdeps/unix/sysv/linux/ttyname_r.c | 18 ++++++++++++++---- > 3 files changed, 62 insertions(+), 8 deletions(-) > create mode 100644 sysdeps/unix/sysv/linux/ttyname.h > > diff --git a/sysdeps/unix/sysv/linux/ttyname.c b/sysdeps/unix/sysv/linux/ttyname.c > index 7a001b4..dabed22 100644 > --- a/sysdeps/unix/sysv/linux/ttyname.c > +++ b/sysdeps/unix/sysv/linux/ttyname.c > @@ -25,9 +25,12 @@ > #include > #include > #include > +#include > > #include <_itoa.h> > > +#include "ttyname.h" > + > #if 0 > /* Is this used anywhere? It is not exported. */ > char *__ttyname; > @@ -170,12 +173,18 @@ ttyname (int fd) > #ifdef _STATBUF_ST_RDEV > && S_ISCHR (st1.st_mode) > && st1.st_rdev == st.st_rdev > -#else > - && st1.st_ino == st.st_ino > - && st1.st_dev == st.st_dev > #endif > - ) > + && st1.st_ino == st.st_ino > + && st1.st_dev == st.st_dev) > return ttyname_buf; > + > + /* If the link doesn't exist, then it points to a device in another > + namespace. */ > + if (is_pty (&st)) > + { > + __set_errno (ENODEV); > + return NULL; > + } > } > > if (__xstat64 (_STAT_VER, "/dev/pts", &st1) == 0 && S_ISDIR (st1.st_mode)) > diff --git a/sysdeps/unix/sysv/linux/ttyname.h b/sysdeps/unix/sysv/linux/ttyname.h > new file mode 100644 > index 0000000..19af6e6 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/ttyname.h > @@ -0,0 +1,35 @@ > +/* Copyright (C) 2004-2016 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + 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. > + > + 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. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; see the file COPYING.LIB. If > + not, see . */ > + > +#include > +#include > +#include > +#include > + > +/* Return true if this is a UNIX98 pty device, as defined in > + linux/Documentation/devices.txt. */ > +static inline int > +is_pty (struct stat64 *sb) > +{ > +#ifdef _STATBUF_ST_RDEV > + int m = major (sb->st_rdev); > + return (136 <= m && m <= 143); > +#else > + return false; > +#endif > +} > + > diff --git a/sysdeps/unix/sysv/linux/ttyname_r.c b/sysdeps/unix/sysv/linux/ttyname_r.c > index d15bc74..542114b 100644 > --- a/sysdeps/unix/sysv/linux/ttyname_r.c > +++ b/sysdeps/unix/sysv/linux/ttyname_r.c > @@ -25,9 +25,12 @@ > #include > #include > #include > +#include > > #include <_itoa.h> > > +#include "ttyname.h" > + > static int getttyname_r (char *buf, size_t buflen, > dev_t mydev, ino64_t myino, int save, > int *dostat) internal_function; > @@ -152,12 +155,19 @@ __ttyname_r (int fd, char *buf, size_t buflen) > #ifdef _STATBUF_ST_RDEV > && S_ISCHR (st1.st_mode) > && st1.st_rdev == st.st_rdev > -#else > - && st1.st_ino == st.st_ino > - && st1.st_dev == st.st_dev > #endif > - ) > + && st1.st_ino == st.st_ino > + && st1.st_dev == st.st_dev) > return 0; > + > + /* If the link doesn't exist, then it points to a device in another > + * namespace. > + */ > + if (is_pty (&st)) > + { > + __set_errno (ENODEV); > + return ENODEV; > + } > } > > /* Prepare the result buffer. */ > -- > 2.9.3