[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: _BRANCH Konsole & FreeBSD
From: Adriaan de Groot <adridg () cs ! kun ! nl>
Date: 2003-08-24 21:56:59
[Download RAW message or body]
Many moons ago, I wrote patches to get konsole to work around many linuxistic
assumptions and actually invoke konsole_grantpty properly; recent changes in
-CURRENT that break konsole wrt. gethostname() reminded me that I still
haven't committed them nor ported them to HEAD. Find attached a patch:
* Makes the FD that konsole_grantpty uses a parameter. To be sure, I can't
tell what the security implications of this change might be. I can imagine
konsole_grantpty --revoke 3> /tmp/bar
actually already as a way to mess with /tmp/bar (well, if it was a tty).
To be on the safe side, konsole_grantpty should still work with FD 3 if no
extra parameter is given. This allows the patched konsole_grantpty to work
with older konsole's. Might be overkill, though.
* gethostname() may also return ENAMETOOLONG.
* ttyname() only works on ttys, not ptys in FreeBSD.
* Use Q_OS_FREEBSD instead of __FreeBSD__.
OK to apply? Look sensible for HEAD as well?
--
pub 1024D/FEA2A3FE 2002-06-18 Adriaan de Groot <groot@kde.org>
Key fingerprint = 934E 31AA 80A7 723F 54F9 50ED 76AC EE01 FEA2 A3FE
["konsole.diff" (text/x-diff)]
Index: TEPty.cpp
===================================================================
RCS file: /home/kde/kdebase/konsole/konsole/TEPty.cpp,v
retrieving revision 1.75
diff -u -3 -p -r1.75 TEPty.cpp
--- TEPty.cpp 22 Nov 2002 13:17:57 -0000 1.75
+++ TEPty.cpp 24 Aug 2003 21:44:00 -0000
@@ -65,6 +65,9 @@
#include <config.h>
#endif
+// Get the Q_OS_* defines
+#include <qglobal.h>
+
#ifdef __sgi
#define __svr4__
#endif
@@ -88,6 +91,10 @@
#include <sys/types.h>
#endif
+#ifdef Q_OS_FREEBSD
+#include <sys/param.h>
+#endif
+
#include <stdlib.h>
#include <stdio.h>
@@ -198,9 +205,30 @@ public:
FILE* syslog_file = NULL; //stdout;
-#define PTY_FILENO 3
+#define DEFAULT_PTY_FILENO 3
+int PTY_FILENO = -1; // None allocated yet.
+
#define BASE_CHOWN "konsole_grantpty"
+void TEPtyInit()
+{
+/*
+** FreeBSD can't dup2(fd,3) because fd 3 is already in use by
+** some weird pipe. So instead, we get a new throwaway fd
+** that's not in use by anyone.
+*/
+#ifdef Q_OS_FREEBSD
+ PTY_FILENO = open("/dev/null",O_RDWR);
+ if (PTY_FILENO == -1) {
+ perror("konsole:open PTY");
+ /* This won't work either, but hey .. */
+ PTY_FILENO = DEFAULT_PTY_FILENO;
+ }
+#else
+ PTY_FILENO = DEFAULT_PTY_FILENO;
+#endif
+}
+
int chownpty(int fd, bool grant)
// param fd: the fd of a master pty.
// param grant: true to grant, false to revoke
@@ -212,6 +240,8 @@ int chownpty(int fd, bool grant)
newsa.sa_flags = 0;
sigaction(SIGCHLD, &newsa, &oldsa);
+ if (PTY_FILENO == -1) TEPtyInit();
+
pid_t pid = fork();
if (pid < 0)
{
@@ -225,7 +255,12 @@ int chownpty(int fd, bool grant)
/* We pass the master pseudo terminal as file descriptor PTY_FILENO. */
if (fd != PTY_FILENO && dup2(fd, PTY_FILENO) < 0) exit(1);
QString path = locate("exe", BASE_CHOWN);
- execle(path.ascii(), BASE_CHOWN, grant?"--grant":"--revoke", NULL, NULL);
+ /*
+ ** Because konsole_grantpty now can't expect the fd
+ ** to be constant, we need an additional parameter.
+ */
+ QString fdnumber = QString::number(PTY_FILENO);
+ execle(path.ascii(), BASE_CHOWN, grant?"--grant":"--revoke", fdnumber.ascii(), \
NULL, NULL); exit(1); // should not be reached
}
@@ -486,6 +521,16 @@ int TEPty::makePty(bool _addutmp)
// open and set all standard files to slave tty
int tt = m_SlaveFd; // Already opened?
+#ifdef Q_OS_FREEBSD
+ /*
+ ** It seems to be possible for SlaveFd to be closed in error
+ ** somewhere along the line. So check it for "liveness".
+ */
+ struct stat sb;
+ if (fstat(tt,&sb)!=0)
+ tt=-1; // Apparently not alive.
+#endif
+
if (tt < 0)
tt = open(ttynam, O_RDWR);
@@ -524,14 +569,57 @@ int TEPty::makePty(bool _addutmp)
}
strncpy(l_struct.ut_name, str_ptr, UT_NAMESIZE);
+#ifdef Q_OS_FREEBSD
+ /* FreeBSD until august 22, 2003 returned ENOMEM for too-long
+ ** hostnames. Then sanity prevailed (?) and the error was changed
+ ** to NAMETOOLONG, but this breaks konsole .. again.
+ **
+ ** Instead of bailing out with long hostnames, put in partial
+ ** hostnames (the first UT_HOSTSIZE characters) instead.
+ */
+ char hostnamebuffer[MAXHOSTNAMELEN+1];
+ memset(hostnamebuffer,0,MAXHOSTNAMELEN+1);
+ if (gethostname(hostnamebuffer, MAXHOSTNAMELEN) == -1)
+ {
+ if ( (errno==ENOMEM) || (errno==ENAMETOOLONG) ) {
+ /* ignore it, but very odd */
+ }
+ else {
+ /* Not much chance of this being visible anywhere ... */
+ perror("konsole:gethostname");
+ abort();
+ }
+ }
+ /* Copy hostname, possibly only partially */
+ memset(l_struct.ut_host,0,UT_HOSTSIZE);
+ strncpy(l_struct.ut_host,hostnamebuffer,UT_HOSTSIZE);
+ l_struct.ut_host[UT_HOSTSIZE]=0;
+#else
+ /* Non-FreeBSD systems */
if (gethostname(l_struct.ut_host, UT_HOSTSIZE) == -1) {
- if (errno != ENOMEM)
+ if (errno != ENOMEM)
abort();
l_struct.ut_host[UT_HOSTSIZE]=0;
}
+#endif
if (! (str_ptr=ttyname(tt)) ) {
+#ifdef Q_OS_FREEBSD
+ /*
+ ** In FreeBSD, the ttyname() call always returns NULL
+ ** for the kinds of devices (ptys) we have opened,
+ ** so don't abort, use a foolish default value instead.
+ ** The call to login() probably won't work _anyway_,
+ ** since normally users can't update the wtmp file.
+ **
+ ** If we were real sticklers for accuracy, we'd copy the
+ ** code from konsole_grantpty that does it's darndest to
+ ** file out the right tty name.
+ */
+ str_ptr = const_cast<char *>("/dev/konsole");
+#else
abort();
+#endif
}
if (strncmp(str_ptr, "/dev/", 5) == 0)
str_ptr += 5;
@@ -607,7 +695,7 @@ void TEPty::startPgm(const char* pgm, QV
// #define CERASE 0177
// #endif
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \
defined (__bsdi__) || defined(__APPLE__) +#if defined (Q_OS_FREEBSD) || defined \
(__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) \
ioctl(0,TIOCGETA,(char *)&ttmode); #else
# if defined (_HPUX_SOURCE) || defined(__Lynx__)
@@ -621,7 +709,7 @@ void TEPty::startPgm(const char* pgm, QV
ttmode.c_cc[VINTR] = CTRL('C');
ttmode.c_cc[VQUIT] = CTRL('\\');
ttmode.c_cc[VERASE] = 0177;
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \
defined (__bsdi__) || defined(__APPLE__) +#if defined (Q_OS_FREEBSD) || defined \
(__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) \
ioctl(0,TIOCSETA,(char *)&ttmode); #else
# ifdef _HPUX_SOURCE
Index: konsole_grantpty.c
===================================================================
RCS file: /home/kde/kdebase/konsole/konsole/Attic/konsole_grantpty.c,v
retrieving revision 1.7
diff -u -3 -p -r1.7 konsole_grantpty.c
--- konsole_grantpty.c 2 Sep 2002 01:09:24 -0000 1.7
+++ konsole_grantpty.c 24 Aug 2003 21:44:01 -0000
@@ -40,7 +40,9 @@
# include <dirent.h>
#endif
-#define PTY_FILENO 3 /* keep in sync with grantpty */
+#define DEFAULT_PTY_FILENO 3 /* keep in sync with TEPty.cpp */
+int PTY_FILENO = DEFAULT_PTY_FILENO;
+
#define TTY_GROUP "tty"
int main (int argc, char *argv[])
@@ -52,11 +54,13 @@ int main (int argc, char *argv[])
uid_t uid;
mode_t mod;
char* tty;
+ int command_fd; /* which fd to use? */
/* check preconditions **************************************************/
- if (argc != 2 || (strcmp(argv[1],"--grant") && strcmp(argv[1],"--revoke")))
+ if (( (argc != 3) && (argc != 2) /* optional third arg */ ) ||
+ (strcmp(argv[1],"--grant") && strcmp(argv[1],"--revoke")))
{
- printf("usage: %s (--grant|--revoke)\n",argv[0]);
+ printf("usage: %s (--grant|--revoke) [fd]\n",argv[0]);
printf("%s is a helper for\n",argv[0]);
printf("konsole and not intented to\n");
printf("be called from the command\n");
@@ -83,6 +87,22 @@ int main (int argc, char *argv[])
uid = 0; /* root */
mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
}
+
+ command_fd = DEFAULT_PTY_FILENO;
+ if (argv[2])
+ {
+ command_fd = atoi(argv[2]);
+ }
+ if (command_fd > 2) /* must be out of stdin,stdout,stderr range */
+ {
+ PTY_FILENO=command_fd;
+ }
+ else
+ {
+ fprintf(stderr,"%s: Bad command fd (seems to be %d)\n",argv[0],command_fd);
+ return 1;
+ }
+
/* Get the group ID of the special `tty' group. */
p = getgrnam(TTY_GROUP); /* posix */
gid = p ? p->gr_gid : getgid (); /* posix */
@@ -117,6 +137,9 @@ int main (int argc, char *argv[])
if (dirp->d_fileno != dsb.st_ino)
continue;
{
+ /* Else this is the right device file .. any possible memory
+ ** leak here because two files match is unimportant?
+ */
int pdlen = strlen(_PATH_DEV), namelen = strlen(dirp->d_name);
pty = malloc(pdlen + namelen + 1);
if (pty) {
Index: main.cpp
===================================================================
RCS file: /home/kde/kdebase/konsole/konsole/main.cpp,v
retrieving revision 1.243.2.3
diff -u -3 -p -r1.243.2.3 main.cpp
--- main.cpp 29 Jun 2003 21:53:11 -0000 1.243.2.3
+++ main.cpp 24 Aug 2003 21:44:02 -0000
@@ -123,6 +123,7 @@ public:
};
+extern void TEPtyInit();
/* --| main |------------------------------------------------------ */
int main(int argc, char* argv[])
@@ -137,6 +138,7 @@ int main(int argc, char* argv[])
bool scrollbaron = true;
QCString wname = PACKAGE;
+ TEPtyInit();
KAboutData aboutData( PACKAGE, I18N_NOOP("Konsole"),
VERSION, description, KAboutData::License_GPL_V2,
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic