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);
}
-