From 87d3f0455ddbf08c1a81864a8f0b8e0febefb88e Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Fri, 25 Feb 2022 02:14:11 +0200 Subject: [PATCH] kpty: assume grantpt() and unlockpt() are available Signed-off-by: Ivailo Monev --- ConfigureChecks.cmake | 2 - config-pty.h.cmake | 2 - kpty/CMakeLists.txt | 6 -- kpty/kgrantpty.c | 180 ------------------------------------------ kpty/kpty.cpp | 92 ++------------------- kpty/kpty_p.h | 3 - 6 files changed, 5 insertions(+), 280 deletions(-) delete mode 100644 kpty/kgrantpty.c diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index f3483fec..61e6e091 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -119,8 +119,6 @@ if (UNIX) set(HAVE_OPENPTY 0) check_function_exists(revoke HAVE_REVOKE) - check_function_exists(grantpt HAVE_GRANTPT) - check_function_exists(unlockpt HAVE_UNLOCKPT) endif (openpty_in_libc OR openpty_in_libutil) check_function_exists(ptsname_r HAVE_PTSNAME_R) diff --git a/config-pty.h.cmake b/config-pty.h.cmake index 76b10385..c49ff7d4 100644 --- a/config-pty.h.cmake +++ b/config-pty.h.cmake @@ -2,11 +2,9 @@ #cmakedefine PTM_DEVICE "${PTM_DEVICE}" #cmakedefine HAVE_LIBUTIL_H 1 -#cmakedefine HAVE_GRANTPT 1 #cmakedefine HAVE_OPENPTY 1 #cmakedefine HAVE_PTSNAME_R 1 #cmakedefine HAVE_REVOKE 1 -#cmakedefine HAVE_UNLOCKPT 1 #cmakedefine HAVE_PTY_H 1 #cmakedefine HAVE_TERMIO_H 1 diff --git a/kpty/CMakeLists.txt b/kpty/CMakeLists.txt index 8bbcd287..98dad615 100644 --- a/kpty/CMakeLists.txt +++ b/kpty/CMakeLists.txt @@ -42,12 +42,6 @@ install( ########### next target ############### -if(NOT HAVE_OPENPTY) - add_executable(kgrantpty kgrantpty.c) - target_link_libraries(kgrantpty) - install(TARGETS kgrantpty DESTINATION ${KDE4_LIBEXEC_INSTALL_DIR}) -endif() - if(ENABLE_TESTING) add_subdirectory(tests) endif() diff --git a/kpty/kgrantpty.c b/kpty/kgrantpty.c deleted file mode 100644 index 5cacaea1..00000000 --- a/kpty/kgrantpty.c +++ /dev/null @@ -1,180 +0,0 @@ -/* kgrantpty - helper program for KPty. */ - -/* This program is based on the glibc2.1 pt_chmod. - * It was pulled out from there since both Linux - * distributors and other OSes are not able to make - * use of the glibc for different reasons. - * - * THIS IS A ROOT SUID PROGRAM - * - * Things work as following: - * - * In konsole we open a master pty. This can be opened - * done by at most one process. Prior to opening the - * master pty, the slave pty cannot be opened. Then, in - * grantpty, we fork to this program. The trick is, that - * the parameter is passes as a file handle, which cannot - * be faked, so that we get a secure setuid root chmod/chown - * with this program. - * - * We have to chown/chmod the slave pty to prevent eavesdroping. - * - * Contributed by Zack Weinberg , 1998. - * Copyright (c) 1999 by Lars Doelle . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_PTY_H -# include -#endif - - -#define TTY_GROUP "tty" - -int main (int argc, char *argv[]) -{ - struct stat st; - gid_t gid; - uid_t uid; - mode_t mod; - char* tty = 0; - int fd; -#if defined(HAVE_PTSNAME_R) - char ttyb[32]; -#endif - - /* check preconditions **************************************************/ - if (argc != 3 || (strcmp(argv[1],"--grant") && strcmp(argv[1],"--revoke"))) - { - printf("usage: %s (--grant|--revoke) \n" - "%s is a helper for the KDE core libraries.\n" - "It is not intended to be called from the command line.\n" - "It needs to be installed setuid root to function.\n", - argv[0], argv[0]); - return 1; /* FAIL */ - } - - if (geteuid () != 0) - { - fprintf(stderr, "%s not installed setuid root\n", argv[0]); - return 1; /* FAIL */ - } - - fd = atoi(argv[2]); - - /* get slave pty name from master pty file handle *********/ -#if defined(HAVE_PTSNAME_R) - memset(ttyb, '\0', sizeof(ttyb) * sizeof(char)); - if (ptsname_r(fd, ttyb, sizeof(ttyb)) == 0) { - tty = ttyb; - if (!tty) -#else - tty = ptsname(fd); - if (!tty) -#endif - { - /* Check that fd is a valid master pseudo terminal. */ -#if defined(HAVE_TTYNAME_R) - char pty[32]; - memset(pty, '\0', sizeof(pty) * sizeof(char)); - if (ttyname_r(fd, pty, sizeof(pty)) != 0) -#else - char *pty = ttyname(fd); - if (pty == NULL) -#endif - { - fprintf(stderr,"%s: cannot determine pty name.\n",argv[0]); - return 1; /* FAIL */ - } - - /* matches /dev/pty?? */ - if (memcmp(pty,"/dev/pty",8)) - { - fprintf(stderr,"%s: determined a strange pty name '%s'.\n",argv[0],pty); -#if !defined(HAVE_TTYNAME_R) - free(pty); -#endif - return 1; /* FAIL */ - } - - tty = malloc(strlen(pty) + 1); - strcpy(tty,"/dev/tty"); - strcat(tty,pty+8); -#if !defined(HAVE_TTYNAME_R) - free(pty); -#endif - } - - /* Check that the returned slave pseudo terminal is a character device. */ - if (stat(tty, &st) < 0 || !S_ISCHR(st.st_mode)) - { - fprintf(stderr,"%s: found '%s' not to be a character device.\n",argv[0],tty); - free(tty); - return 1; /* FAIL */ - } - - /* setup parameters for the operation ***********************************/ - - if (!strcmp(argv[1],"--grant")) - { - uid = getuid(); - struct group* p = getgrnam(TTY_GROUP); - if (!p) - p = getgrnam("wheel"); - gid = p ? p->gr_gid : getgid (); - mod = S_IRUSR | S_IWUSR | S_IWGRP; - } - else - { - uid = 0; - gid = st.st_gid == getgid () ? 0 : -1; - mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - } - - /* Perform the actual chown/chmod ************************************/ - - if (chown(tty, uid, gid) < 0) - { - fprintf(stderr,"%s: cannot chown %s: %s\n",argv[0],tty,strerror(errno)); - free(tty); - return 1; /* FAIL */ - } - - if (chmod(tty, mod) < 0) - { - fprintf(stderr,"%s: cannot chmod %s: %s\n",argv[0],tty,strerror(errno)); - free(tty); - return 1; /* FAIL */ - } - - free(tty); - return 0; /* OK */ -} diff --git a/kpty/kpty.cpp b/kpty/kpty.cpp index 2527975a..06d20b44 100644 --- a/kpty/kpty.cpp +++ b/kpty/kpty.cpp @@ -80,13 +80,8 @@ extern "C" { #endif #include -#include // findExe #include -#include - -#define TTY_GROUP "tty" - #ifndef PATH_MAX # define PATH_MAX _POSIX_PATH_MAX #endif @@ -108,14 +103,6 @@ KPtyPrivate::~KPtyPrivate() { } -#ifndef HAVE_OPENPTY -bool KPtyPrivate::chownpty(bool grant) -{ - return !QProcess::execute(KStandardDirs::findExe("kgrantpty"), - QStringList() << (grant?"--grant":"--revoke") << QString::number(masterFd)); -} -#endif - ///////////////////////////// // public member functions // ///////////////////////////// @@ -176,97 +163,29 @@ bool KPty::open() #ifdef HAVE_PTSNAME_R char ptsn[32]; ::memset(ptsn, '\0', sizeof(ptsn) * sizeof(char)); - if (ptsname_r(d->masterFd, ptsn, sizeof(ptsn)) == 0) { + if (::ptsname_r(d->masterFd, ptsn, sizeof(ptsn)) == 0) { d->ttyName = ptsn; #else // HAVE_PTSNAME_R - char *ptsn = ptsname(d->masterFd); + char *ptsn = ::ptsname(d->masterFd); if (ptsn) { d->ttyName = ptsn; #endif // HAVE_PTSNAME_R -#ifdef HAVE_GRANTPT - if (!grantpt(d->masterFd)) + if (::grantpt(d->masterFd) == 0) goto grantedpt; -#else // HAVE_GRANTPT - goto gotpty; -#endif // HAVE_GRANTPT } ::close(d->masterFd); d->masterFd = -1; } - // Linux device names, FIXME: Trouble on other systems? - for (const char* s3 = "pqrstuvwxyzabcde"; *s3; s3++) - { - for (const char* s4 = "0123456789abcdef"; *s4; s4++) - { - ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toLatin1(); - d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toLatin1(); - - d->masterFd = KDE_open(ptyName.data(), O_RDWR); - if (d->masterFd >= 0) - { -#ifdef Q_OS_SOLARIS - /* Need to check the process group of the pty. - * If it exists, then the slave pty is in use, - * and we need to get another one. - */ - int pgrp_rtn; - if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) { - ::close(d->masterFd); - d->masterFd = -1; - continue; - } -#endif /// Q_OS_SOLARIS - if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits - { - if (!geteuid()) - { - struct group* p = getgrnam(TTY_GROUP); - if (!p) - p = getgrnam("wheel"); - gid_t gid = p ? p->gr_gid : getgid (); - - chown(d->ttyName.data(), getuid(), gid); - chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP); - } - goto gotpty; - } - ::close(d->masterFd); - d->masterFd = -1; - } - } - } - kWarning(175) << "Can't open a pseudo teletype"; return false; - gotpty: - KDE_struct_stat st; - if (KDE_stat(d->ttyName.data(), &st)) - return false; // this just cannot happen ... *cough* Yeah right, I just - // had it happen when pty #349 was allocated. I guess - // there was some sort of leak? I only had a few open. - if (((st.st_uid != getuid()) || - (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) && - !d->chownpty(true)) - { - kWarning(175) - << "chownpty failed for device " << ptyName << "::" << d->ttyName - << "\nThis means the communication can be eavesdropped." << endl; - } - grantedpt: - #ifdef HAVE_REVOKE revoke(d->ttyName.data()); #endif -#ifdef HAVE_UNLOCKPT unlockpt(d->masterFd); -#elif defined(TIOCSPTLCK) - int flag = 0; - ioctl(d->masterFd, TIOCSPTLCK, &flag); -#endif d->slaveFd = KDE_open(d->ttyName.data(), O_RDWR | O_NOCTTY); if (d->slaveFd < 0) @@ -375,15 +294,14 @@ void KPty::close() #ifndef HAVE_OPENPTY // don't bother resetting unix98 pty, it will go away after closing master anyway. if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) { - if (!geteuid()) { + if (geteuid() == 0) { KDE_struct_stat st; - if (!KDE_stat(d->ttyName.data(), &st)) { + if (KDE_stat(d->ttyName.data(), &st) == 0) { chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1); chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); } } else { fcntl(d->masterFd, F_SETFD, 0); - d->chownpty(false); } } #endif diff --git a/kpty/kpty_p.h b/kpty/kpty_p.h index ef13ee88..678faf93 100644 --- a/kpty/kpty_p.h +++ b/kpty/kpty_p.h @@ -33,9 +33,6 @@ class KPtyPrivate { public: KPtyPrivate(KPty* parent); virtual ~KPtyPrivate(); -#ifndef HAVE_OPENPTY - bool chownpty(bool grant); -#endif int masterFd; int slaveFd;