From patchwork Tue Aug 29 13:45:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 22392 Received: (qmail 130625 invoked by alias); 29 Aug 2017 13:46:01 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 125279 invoked by uid 89); 29 Aug 2017 13:45:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=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: mx1.mailbox.org From: Christian Brauner To: libc-alpha@sourceware.org, stgraber@stgraber.org, serge@hallyn.com, fweimer@redhat.com, joseph@codesourcery.com Cc: Christian Brauner Subject: [PATCH 2/2 v4] openpty: use TIOCGPTPEER to open slave side fd Date: Tue, 29 Aug 2017 15:45:15 +0200 Message-Id: <20170829134515.9345-2-christian.brauner@ubuntu.com> In-Reply-To: <20170829134515.9345-1-christian.brauner@ubuntu.com> References: <20170829134515.9345-1-christian.brauner@ubuntu.com> 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 2017-08-29: * Adapt to unified error handling as suggested by Florian. --- ChangeLog | 5 +++++ login/openpty.c | 30 ++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 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 a7b1ab5dde..766aa958ff 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, ret = -1, slave = -1; + *buf = '\0'; + master = getpt (); if (master == -1) return -1; @@ -104,12 +106,22 @@ openpty (int *amaster, int *aslave, char *name, if (unlockpt (master)) goto on_error; - if (pts_name (master, &buf, sizeof (_buf))) - goto on_error; - - 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) - goto on_error; + { + /* Fallback to path-based slave fd allocation in case kernel doesn't + * support TIOCGPTPEER. + */ + if (pts_name (master, &buf, sizeof (_buf))) + goto on_error; + + slave = open (buf, O_RDWR | O_NOCTTY); + if (slave == -1) + goto on_error; + } /* XXX Should we ignore errors here? */ if (termp) @@ -122,7 +134,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 on_error; + + strcpy (name, buf); + } ret = 0;