|
Message-Id: <20170901153558.29715-2-christian.brauner@ubuntu.com> Date: Fri, 1 Sep 2017 17:35:58 +0200 From: Christian Brauner <christian.brauner@...ntu.com> To: musl@...ts.openwall.com Cc: Christian Brauner <christian.brauner@...ntu.com> Subject: [PATCH 1/1] openpty: use TIOCGPTPEER to open slave side fd 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 <christian.brauner@...ntu.com> --- src/misc/openpty.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/misc/openpty.c b/src/misc/openpty.c index c1074060..9eab7a37 100644 --- a/src/misc/openpty.c +++ b/src/misc/openpty.c @@ -3,13 +3,14 @@ #include <unistd.h> #include <pty.h> #include <stdio.h> +#include <string.h> #include <pthread.h> /* Nonstandard, but vastly superior to the standard functions */ int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws) { - int m, s, n=0, cs; + int m, s = -1, cs; char buf[20]; m = open("/dev/ptmx", O_RDWR|O_NOCTTY); @@ -17,13 +18,38 @@ int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struc pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + if (!name) name = buf; + +#ifdef TIOCGPTPEER + int ret; + + /* Try to allocate slave fd solely based on the master fd in case the + * kernel supports it. + */ + s = ioctl(m, TIOCGPTPEER, O_RDWR|O_NOCTTY); + if (s < 0) + goto fail; + + /* Check the contents of the symlink in case devpts has been mounted in + * a non-standard location. + */ + ret = ttyname_r(s, name, sizeof buf); + if (ret) + goto fail; + + if (strncmp(name, "/dev/pts/", 9)) + goto fail; +#else + int n = 0; + if (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n)) goto fail; - if (!name) name = buf; snprintf(name, sizeof buf, "/dev/pts/%d", n); - if ((s = open(name, O_RDWR|O_NOCTTY)) < 0) + s = open(name, O_RDWR|O_NOCTTY); + if (s < 0) goto fail; +#endif if (tio) tcsetattr(s, TCSANOW, tio); if (ws) ioctl(s, TIOCSWINSZ, ws); @@ -35,6 +61,8 @@ int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struc return 0; fail: close(m); + if (s >= 0) + close(s); pthread_setcancelstate(cs, 0); return -1; } -- 2.14.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.