From patchwork Mon Aug 28 12:11:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 22376 Received: (qmail 121215 invoked by alias); 28 Aug 2017 12:11:21 -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 120951 invoked by uid 89); 28 Aug 2017 12:11:19 -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=10416, Hx-languages-length:3219, handed 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 Cc: Christian Brauner Subject: [PATCH 2/2 v2] openpty: use TIOCGPTPEER to open slave side fd Date: Mon, 28 Aug 2017 14:11:06 +0200 Message-Id: <20170828121106.2629-1-christian.brauner@ubuntu.com> In-Reply-To: <3496d984-a55e-d56b-2c25-a23200327dca@redhat.com> References: <3496d984-a55e-d56b-2c25-a23200327dca@redhat.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 | 5 +++++ login/openpty.c | 36 +++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 11 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..43b34d7a9c 100644 --- a/login/openpty.c +++ b/login/openpty.c @@ -87,9 +87,9 @@ openpty (int *amaster, int *aslave, char *name, const struct termios *termp, const struct winsize *winp) { #ifdef PATH_MAX - char _buf[PATH_MAX]; + char _buf[PATH_MAX] = {0}; #else - char _buf[512]; + char _buf[512] = {0}; #endif char *buf = _buf; int master, slave = -1; @@ -104,16 +104,24 @@ 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); + /* Try to allocate slave fd solely based on master fd first. */ + slave = ioctl (master, TIOCGPTPEER, O_RDWR | O_NOCTTY); 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 +135,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);