From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10557 invoked by alias); 28 Aug 2017 12:51:01 -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 10524 invoked by uid 89); 28 Aug 2017 12:51:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy= X-HELO: mx2.mailbox.org From: Christian Brauner To: libc-alpha@sourceware.org, stgraber@stgraber.org, serge@hallyn.com, fweimer@redhat.com, joseph@codesourcery.com, schwab@suse.de Cc: Christian Brauner Subject: [PATCH 2/2 v3] openpty: use TIOCGPTPEER to open slave side fd Date: Mon, 28 Aug 2017 12:51:00 -0000 Message-Id: <20170828125025.21923-1-christian.brauner@ubuntu.com> In-Reply-To: , References: , X-SW-Source: 2017-08/txt/msg01197.txt.bz2 Newer kernels expose the ioctl TIOCGPTPEER [1] call to userspace which allows to safely allocate a file descriptor for a pty slave based solely on the master file descriptor. This allows us to avoid path-based operations and makes this function a lot safer in the face of devpts mounts in different mount namespaces. [1]: https://patchwork.kernel.org/patch/9760743/ Signed-off-by: Christian Brauner --- Changelog 2017-08-28: * Instead of #ifdefing the TIOCGPTPEER ioctl flag we now try the ioctl() first and if it fails we fallback to path-based allocation of the slave fd. This allows us retain backward compatibility with kernels that do not support this ioctl call. * A note on the following codepath if (name != NULL) { if (*buf == '\0') if (pts_name (master, &buf, sizeof (_buf))) goto fail; strcpy (name, buf); } "buf" is guaranteed to be allocated in this case. If the pts_name() call above failed we would have never reached this code path. If it has been called succesfully it will either have handed us a valid buffer or "buf" will still point to the static char array "_buf" which is initialized to 0. Changelog 2017-08-28: * Preserve #ifdef for TIOCGPTPEER since it needs to work on non-Linux distros too. * Only intialize first byte of "_buf". --- ChangeLog | 5 +++++ login/openpty.c | 36 +++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc5fb8e27f..30829e4c16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-08-26 Christian Brauner + + * login/openpty.c (openpty): If defined, use the TIOCGPTPEER ioctl call + to allocate the slave pty file descriptor. + 2017-08-26 Christian Brauner * login/openpty.c (openpty): Close slave pty file descriptor on error. diff --git a/login/openpty.c b/login/openpty.c index 8fbc66a3ef..33754e18a7 100644 --- a/login/openpty.c +++ b/login/openpty.c @@ -94,6 +94,8 @@ openpty (int *amaster, int *aslave, char *name, char *buf = _buf; int master, slave = -1; + *buf = '\0'; + master = getpt (); if (master == -1) return -1; @@ -104,16 +106,26 @@ openpty (int *amaster, int *aslave, char *name, if (unlockpt (master)) goto fail; - if (pts_name (master, &buf, sizeof (_buf))) - goto fail; - - slave = open (buf, O_RDWR | O_NOCTTY); +#ifdef TIOCGPTPEER + /* Try to allocate slave fd solely based on master fd first. */ + slave = ioctl (master, TIOCGPTPEER, O_RDWR | O_NOCTTY); +#endif if (slave == -1) { - if (buf != _buf) - free (buf); - - goto fail; + /* Fallback to path-based slave fd allocation in case kernel doesn't + * support TIOCGPTPEER. + */ + if (pts_name (master, &buf, sizeof (_buf))) + goto fail; + + slave = open (buf, O_RDWR | O_NOCTTY); + if (slave == -1) + { + if (buf != _buf) + free (buf); + + goto fail; + } } /* XXX Should we ignore errors here? */ @@ -127,7 +139,13 @@ openpty (int *amaster, int *aslave, char *name, *amaster = master; *aslave = slave; if (name != NULL) - strcpy (name, buf); + { + if (*buf == '\0') + if (pts_name (master, &buf, sizeof (_buf))) + goto fail; + + strcpy (name, buf); + } if (buf != _buf) free (buf); -- 2.14.1