Subject: 9term buffer overflow

From: [email-masked]
Date: Tue, 27 Jan 1998 16:47:56 -0500

9term "1.6.6 Nov 1995" (the latest?) has a problem in display.c, where
a static buffer can overflow.  (The font improvements for libXg that I
posted a while ago can exercise this; since no one has complained I
guess no one has tried those either (hmmm.))

*** /tmp/T0a004pS	Tue Jan 27 16:43:03 1998
--- display.c	Tue Jan 27 16:33:46 1998
***************
*** 121,126 ****
--- 121,137 ----
  		_killpg(SIGHUP);
  }
  
+ static char *
+ str_ndup(char *p, unsigned int n)
+ {
+ 	char *s = malloc(n+1);
+ 	if (!s)
+ 		error("malloc failure");
+ 	strncpy(s, p, n);
+ 	s[n] = 0;
+ 	return s;
+ }
+ 
  /*
   *	try to extract an X resource under a variety of names
   */
***************
*** 128,134 ****
  get_resource(char *resource, char *class, char *rname, char *cname)
  {
  	char str1[256], str2[256];
- 	static char result[512];
  	XrmValue value;
  	char *str_type;
  
--- 139,144 ----
***************
*** 137,144 ****
  	if (XrmGetResource(
  			XrmGetDatabase(_dpy),
  			str1, str2, &str_type, &value) == True) {
! 		strncpy(result, value.addr, (int)value.size);
! 		return result;
  	}
  	return 0;
  }
--- 147,153 ----
  	if (XrmGetResource(
  			XrmGetDatabase(_dpy),
  			str1, str2, &str_type, &value) == True) {
! 		return str_ndup(value.addr, value.size);
  	}
  	return 0;
  }
***************
*** 155,165 ****
--- 164,176 ----
  
  	s = get_resource(resource, class, "debug", "Debug");
  	if (s && strcasecmp(s, "true")) {
+ 		free(s);
  		XSetErrorHandler(error_handler);
  		XSetIOErrorHandler(io_error_handler);
  	}
  	s = get_resource(resource, class, "login", "Login");
  	if (s && !strcasecmp(s, "true")) {
+ 		free(s);
  		/* Change argv[0] if this is a login shell */
  		new = (char *)malloc(strlen(shargv[0])+2);
  		if (!new)
***************
*** 169,206 ****
  		shargv[0] = new;
  	}
  	s = get_resource(resource, class, "scroll", "Scroll");
! 	if (s && !strcasecmp(s, "true"))
  		scrolling = 1;
  	s = get_resource(resource, class, "utmp", "Utmp");
! 	if (s && !strcasecmp(s, "true"))
  		utmpentry = 1;
  	if (s = get_resource(resource, class, "label", "Label")) {
  		XStoreName(_dpy, XtWindow(_toplevel), s);
  		XSetIconName(_dpy, XtWindow(_toplevel), s);
  		XFlush(_dpy);
  	}
! 	if (s = get_resource(resource, class, "ttyModes", "TtyModes"))
  		parsettymodes(UNIX, s);
! 	if (s = get_resource(resource, class, "p9TtyModes", "P9TTyModes"))
  		parsettymodes(PLAN9, s);
! 	if (s = get_resource(resource, class, "kbdMode", "KbdMode"))
  		if (!strcasecmp(s, "unix"))
  			kbdmode = UNIX;
  		else if (!strcasecmp(s, "plan9"))
  			kbdmode = PLAN9;
! 	if (s = get_resource(resource, class, "p9font", "P9font"))
  		setenv("font", s, 1);
! 	if (s = get_resource(resource, class, "highwater", "Highwater"))
  		highwater = atoi(s);
! 	if (s = get_resource(resource, class, "lowwater", "Lowwater"))
  		lowwater = atoi(s);
! 	if (s = get_resource(resource, class, "9wm", "9Wm"))
  		ninewm = !strcasecmp(s, "true");
  	if (s = get_resource(resource, class, "beep", "Beep")) {
  		if (strstr(s, "unix"))
  			beepmask |= UNIX;
  		if (strstr(s, "plan9"))
  			beepmask |= PLAN9;
  	}
  }
  /*
--- 180,237 ----
  		shargv[0] = new;
  	}
  	s = get_resource(resource, class, "scroll", "Scroll");
! 	if (s && !strcasecmp(s, "true")) {
! 		free(s);
  		scrolling = 1;
+ 	}
  	s = get_resource(resource, class, "utmp", "Utmp");
! 	if (s && !strcasecmp(s, "true")) {
! 		free(s);
  		utmpentry = 1;
+ 	}
  	if (s = get_resource(resource, class, "label", "Label")) {
  		XStoreName(_dpy, XtWindow(_toplevel), s);
  		XSetIconName(_dpy, XtWindow(_toplevel), s);
  		XFlush(_dpy);
+ 		free(s);
  	}
! 	if (s = get_resource(resource, class, "ttyModes", "TtyModes")) {
  		parsettymodes(UNIX, s);
! 		free(s);
! 	}
! 	if (s = get_resource(resource, class, "p9TtyModes", "P9TTyModes")) {
  		parsettymodes(PLAN9, s);
! 		free(s);
! 	}
! 	if (s = get_resource(resource, class, "kbdMode", "KbdMode")) {
  		if (!strcasecmp(s, "unix"))
  			kbdmode = UNIX;
  		else if (!strcasecmp(s, "plan9"))
  			kbdmode = PLAN9;
! 		free(s);
! 	}
! 	if (s = get_resource(resource, class, "p9font", "P9font")) {
  		setenv("font", s, 1);
! 		free(s);
! 	}
! 	if (s = get_resource(resource, class, "highwater", "Highwater")) {
  		highwater = atoi(s);
! 		free(s);
! 	}
! 	if (s = get_resource(resource, class, "lowwater", "Lowwater")) {
  		lowwater = atoi(s);
! 		free(s);
! 	}
! 	if (s = get_resource(resource, class, "9wm", "9Wm")) {
  		ninewm = !strcasecmp(s, "true");
+ 		free(s);
+ 	}
  	if (s = get_resource(resource, class, "beep", "Beep")) {
  		if (strstr(s, "unix"))
  			beepmask |= UNIX;
  		if (strstr(s, "plan9"))
  			beepmask |= PLAN9;
+ 		free(s);
  	}
  }
  /*