File jfbterm-0.3.10-security.patch of Package jfbterm

--- jfbterm-0.3.10/configure.in.security	Sun Jan 23 16:36:43 2000
+++ jfbterm-0.3.10/configure.in	Thu Jan 31 14:11:08 2002
@@ -6,7 +6,7 @@
 dnl Checks for programs.
 AC_PROG_CC
 if test x$CC = xgcc; then
-        CFLAGS="$CFLAGS -Wimplicit -Wreturn-type -Wunused -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align"
+        CFLAGS="$CFLAGS -Wimplicit -Wreturn-type -Wunused -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wcast-qual -Wcast-align"
 fi
 AC_PROG_INSTALL
 
@@ -34,6 +34,9 @@
 AC_TYPE_SIGNAL
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS(select strdup strerror)
+
+AC_CHECK_LIB(util,openpty)
+AC_CHECK_LIB(utempter,addToUtmp)
 
 dnl setup options.
 AC_PATH_PROGS(jfb_gzip_path, gzip, :)
--- jfbterm-0.3.10/fbcommon.c.security	Sun Jan 23 16:07:46 2000
+++ jfbterm-0.3.10/fbcommon.c	Thu Jan 31 14:11:08 2002
@@ -169,8 +169,6 @@
 #define major(dev)	(((dev) >> 8) & 0xff)
 #endif
 
-static char*		fbdn = NULL;
-
 static unsigned short	red[256], green[256], blue[256];
 static struct fb_cmap	ncmap = { 0, 256, red, green, blue, NULL};
 
@@ -391,65 +389,68 @@
 /*---------------------------------------------------------------------------*/
 void tfbm_init(TFrameBufferMemory* p)
 {
-	char *env_fbdn;
+	char		fbdn[16];
+	struct stat	st;
+
+	/* Zap the fd */
 	p->fh = -1;
 
-/*
-	if (!sFBCapabilityList[tvisual].fill) {
-		die("No framebuffer supported.");
-	}
-*/
-	if((fbdn = (char*)malloc(16)) == NULL) {
-		die("malloc: %s\n", strerror(errno));
-	}
+	/* Nixed the use of the FRAMEBUFFER environment
+	 * variable for security reasons. --okir */
 
-	if (NULL != (env_fbdn = getenv("FRAMEBUFFER"))) {
-		strncpy(fbdn, env_fbdn, 16);
-	} else {
+	{
 		int fd;
 		struct fb_con2fbmap c2m;
 		struct vt_stat vstat;
+		char *ttn = ttyname(0);
 
-		if (-1 == (fd = open("/dev/tty0", O_RDWR, 0))) {
-			util_free(fbdn);
-			die("open /dev/tty0: %s\n", strerror(errno));
-		}
-		if (-1 == ioctl(fd, VT_GETSTATE, &vstat)) {
-			util_free(fbdn);
+		if (!ttn)
+			die("ttyname: %s", strerror(errno));
+
+		/* Make sure this is really a VT, and we have
+		 * r/w access to it by reopening it O_RDWR.
+		 *
+		 * Note that if there's a setuid X server installed
+		 * on your system, getting a tty owned by you is
+		 * quite simple.    --okir
+		 */
+		if (strncmp(ttn, "/dev/tty", 8) != 0)
+			die("You do not seem to be logged in at the console");
+		if (-1 == (fd = open(ttn, O_RDWR, 0)))
+			die("open %s: %s\n", ttn, strerror(errno));
+
+		if (-1 == ioctl(fd, VT_GETSTATE, &vstat))
 			die("ioctl VT_GETSTATE");
-		}
 		close(fd);
 		c2m.console = vstat.v_active;
-		if (-1 == (fd = open("/dev/fb0", O_RDWR,0))) {
-			util_free(fbdn);
+		if (-1 == (fd = open("/dev/fb0", O_RDWR,0)))
 			die("open /dev/fb0: %s\n", strerror(errno));
-		}
 		if (-1 == ioctl(fd, FBIOGET_CON2FBMAP, &c2m)) {
 			perror("ioctl FBIOGET_CON2FBMAP");
 			c2m.framebuffer = 0;
 		}
 		close(fd);
-		snprintf(fbdn, 16, "/dev/fb%d", c2m.framebuffer);
+
+		snprintf(fbdn, sizeof(fbdn), "/dev/fb%d", c2m.framebuffer);
 	}
+
+	if ((p->fh = open(fbdn, O_RDWR)) == -1)
+		die("open %s: %s\n", fbdn, strerror(errno));
+
+	if (-1 == fstat(p->fh, &st))
+		die("fstat(%s): %s\n", fbdn, strerror(errno));
+
+	if (!S_ISCHR(st.st_mode) || major(st.st_rdev) != 29 /* FB_MAJOR */)
+		die("%s: not a frame buffer device\n", fbdn);
+
+	if (-1 == fcntl(p->fh, F_SETFL, FD_CLOEXEC))
+		die("fcntl(%s, F_SETFL): %s\n", fbdn, strerror(errno));
 }
 
 void tfbm_open(TFrameBufferMemory* p)
 {
-	struct stat st;
 	struct fb_var_screeninfo fb_var;
 	struct fb_fix_screeninfo fb_fix;
-
-	if ((p->fh = open(fbdn, O_RDWR)) == -1) {
-		die("open %s: %s\n", fbdn, strerror(errno));
-	}
-
-	if (-1 == fstat(p->fh,&st)) {
-		die("fstat(%s): %s\n", fbdn, strerror(errno));
-	}
-	if (!S_ISCHR(st.st_mode) || major(st.st_rdev) != 29 /* FB_MAJOR */) {
-		die("%s: not a frame buffer device\n", fbdn);
-	}
-	free(fbdn);
 
 	tfbm_get_var_screen_info(p->fh, &fb_var);
 	tfbm_get_fix_screen_info(p->fh, &fb_fix);
--- jfbterm-0.3.10/main.c.security	Thu Jan 31 14:11:08 2002
+++ jfbterm-0.3.10/main.c	Thu Jan 31 14:58:16 2002
@@ -42,6 +42,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <getopt.h>
+#include <errno.h>
 
 
 #include <pcf.h>
@@ -63,6 +64,7 @@
 #endif
 
 TFrameBufferMemory gFramebuffer;
+static int	console_fd = -1;
 
 static void tapp_get_options(TApplication* p, int argc, char *argv[])
 {
@@ -102,7 +104,6 @@
 
 void tapp_change_to_original_console(TApplication* p)
 {
-        int cfd;
 	int n = p->gOrigVirtualConsole;
 
 /*
@@ -110,14 +111,9 @@
         signal(SIGUSR2, SIG_DFL);
 */
 
-        cfd = open("/dev/console", O_WRONLY);
-        if (cfd < 0 && (cfd = open("/dev/console", O_RDONLY)) < 0) {
-                print_strerror("/dev/console");
-        }
-        if (ioctl(cfd, VT_ACTIVATE, n) != 0) {
+        if (ioctl(console_fd, VT_ACTIVATE, n) != 0) {
                 fprintf(stderr, "can't activate VC(%d)", n);
         }
-        close(cfd);
 }
 
 void tapp_final(TApplication* p)
@@ -164,7 +160,6 @@
 void tapp_change_to_new_console(TApplication* p)
 {
         struct vt_stat vts;
-        int cfd;
         int vfd;
         int vtNum;
         int child;
@@ -172,22 +167,18 @@
         char vtty[128];
         int mode;
 
-        cfd = open("/dev/console", O_WRONLY);
-        if (cfd < 0 && (cfd = open("/dev/console", O_RDONLY)) < 0) {
-                die("can't open /dev/console");
-        }
 #if 1
-        ioctl(cfd, KDGETMODE, &mode);
+        ioctl(console_fd, KDGETMODE, &mode);
         if (mode == KD_TEXT) {
-                close(cfd);
+                close(console_fd);
                 return;
         }
 #endif
-        ioctl(cfd, VT_GETSTATE, &vts);
+        ioctl(console_fd, VT_GETSTATE, &vts);
 	p->gOrigVirtualConsole	= vts.v_active;
 	p->gOrigVirtualConsoleQ	= TRUE;
 
-        ioctl(cfd, VT_OPENQRY, &vtNum);
+        ioctl(console_fd, VT_OPENQRY, &vtNum);
         if (vtNum < 0) {
                 die("can't get free VC");
         }
@@ -205,13 +196,12 @@
         if ((vfd = open(vtty, O_RDWR)) < 0) {
                 die("can't open %s", vtty);
         }
-        if (ioctl(cfd, VT_ACTIVATE, vtNum) != 0) {
+        if (ioctl(console_fd, VT_ACTIVATE, vtNum) != 0) {
                 die("can't activate VC(%d)", vtNum);
         }
 /*
         atexit(change_to_original_console);
 */
-        close(cfd);
         dup2(vfd, 0);
         dup2(vfd, 1);
         dup2(vfd, 2);
@@ -309,6 +299,25 @@
 		PACKAGE, VERSION
 	);
 
+	/* Open frame buffer device right here, then drop root
+	 * privs because we don't need them anymore --okir */
+	tfbm_init(&gFramebuffer);
+
+	/* Open /dev/console */
+        console_fd = open("/dev/console", O_WRONLY);
+        if (console_fd < 0
+	 && (console_fd = open("/dev/console", O_RDONLY)) < 0) {
+                print_strerror("/dev/console");
+		exit(1);
+        }
+
+	if (setuid(getuid()) < 0)
+		die("unable to drop root privileges: %s\n", strerror(errno));
+
+	/* Everything that follows is safe, at least in a setuid context.
+	 * Running jfbterm as a wrapper around /bin/login is an entirely
+	 * different matter... */
+
 	tapp_init(&gApp);
 
 	tapp_get_options(&gApp, argc, argv);
@@ -318,11 +327,6 @@
 		exit(EXIT_SUCCESS);
 	}
 
-	if (geteuid() != 0) {
-		fprintf(stderr, "permission denied.\n");
-		exit(EXIT_FAILURE);
-	}
-
 	tcaps_read(&(gApp.gCaps), FILE_JFBTERM_CONF);
 	fcap = tcaps_find(&(gApp.gCaps), "fontset"); 
 	if (!fcap || !(fcap->values)) {
@@ -336,8 +340,6 @@
 
 	tapp_change_to_new_console(&gApp);
 
-	tfbm_init(&gFramebuffer);
-	
 	tfont_setup_fontlist(fcap->values);
 
 	tfbm_open(&gFramebuffer);
--- jfbterm-0.3.10/term.c.security	Tue Jan 11 16:28:58 2000
+++ jfbterm-0.3.10/term.c	Thu Jan 31 14:12:35 2002
@@ -41,6 +41,7 @@
 #include <pwd.h>
 #include <utmp.h>
 #include <grp.h>
+#include <utempter.h>
 
 #include <term.h>
 #include <vterm.h>
@@ -50,6 +51,7 @@
 #include <main.h>
 
 
+
 int gChildProcessId = 0;
 
 TTerm gTerm;
@@ -117,27 +119,8 @@
 
 int tterm_get_ptytty(TTerm* p)
 {
-	char buf[256];
-	int i;
-
-	for (i = 0; i < 32; i++) {
-		sprintf(buf, "/dev/pty%c%x", "pqrs"[i/16],i%16);
-		p->ptyfd = open(buf, O_RDWR);
-		if (p->ptyfd >= 0) {
-			break;
-		}
-	}
-	if (p->ptyfd < 0) {
-		print_strerror(buf);
-		return 0;
-	}
-		
-	sprintf(p->name, "/dev/tty%c%x", "pqrs"[i/16],i%16);
-	p->ttyfd = open(p->name, O_RDWR);
-	if (p->ttyfd < 0) {
-		close(p->ptyfd);
-		print_strerror(p->name);
-		p->ptyfd = -1;
+	if (-1 == openpty(&(p->ptyfd),&(p->ttyfd),p->name,NULL,NULL)) {
+		print_strerror("openpty");
 		return 0;
 	}
 	return 1;
@@ -214,6 +197,7 @@
 
 void tterm_wakeup_shell_as_child(TTerm* p, const char* tn)
 {
+	int i;
 	fflush(stdout);
 	gChildProcessId = fork();
 	if (gChildProcessId) {
@@ -240,8 +224,11 @@
 		close(p->ttyfd);
 	}
 	tcsetattr(0, TCSANOW, &(p->ttysave));
-	setgid(getgid());
-	setuid(getuid());
+
+	/* Close all non-essential files */
+	i = getdtablesize();
+	while (--i > 2)
+		close(i);
 
 	execvp(gApp.gExecShell, gApp.gExecShellArgv);
 	exit(1);
@@ -250,55 +237,11 @@
 
 void	tterm_set_utmp(TTerm* p)
 {
-	struct utmp	utmp;
-	struct passwd	*pw;
-	struct group	*ttygrp;
-	char	*tn;
-
-	pw = getpwuid(getuid());
-	tn = rindex(p->name, '/') + 1;
-	memset((char *)&utmp, 0, sizeof(utmp));
-	strncpy(utmp.ut_id, tn + 3, sizeof(utmp.ut_id));
-	utmp.ut_type = DEAD_PROCESS;
-	setutent();
-	getutid(&utmp);
-	utmp.ut_type = USER_PROCESS;
-	utmp.ut_pid = getpid();
-	strncpy(utmp.ut_line, tn, sizeof(utmp.ut_line));
-	strncpy(utmp.ut_user, pw->pw_name, sizeof(utmp.ut_user));
-	time(&(utmp.ut_time));
-	pututline(&utmp);
-	endutent();
-	if ((ttygrp = getgrnam("tty")) != NULL) {
-		p->ttygid = ttygrp->gr_gid;
-		p->ttygidQ = TRUE;
-	} else {
-		p->ttygid = -1;
-	}
-	chmod(p->name, 0720);
-	chown(p->name, getuid(), p->ttygid);
+	addToUtmp(p->name,0,p->ptyfd);
 }
 
 void	tterm_reset_utmp(TTerm* p)
 {
-	struct utmp	utmp, *utp;
-	char	*tn;
-
-	tn = rindex(p->name, '/') + 4;
-	memset((char *)&utmp, 0, sizeof(utmp));
-	strncpy(utmp.ut_id, tn, sizeof(utmp.ut_id));
-	utmp.ut_type = USER_PROCESS;
-	setutent();
-	utp = getutid(&utmp);
-	utp->ut_type = DEAD_PROCESS;
-	memset(utp->ut_user, 0, sizeof(utmp.ut_user));
-	utp->ut_type = DEAD_PROCESS;
-	time(&(utp->ut_time));
-	pututline(utp);
-	endutent();
-	chmod(p->name, 0666);
-	chown(p->name, 0, p->ttygid);
-	p->ttygid = FALSE;
+	removeLineFromUtmp(p->name,p->ptyfd);
 }
-
 
openSUSE Build Service is sponsored by