bugs in -ltermlib termcap.c
Tony L. Hansen
hansen at pegasus.UUCP
Sat Apr 27 07:08:45 AEST 1985
I've found a few bugs in the termcap library that still exist in
4.2BSD.
1: tgetent() cannot be called more than once in a program (hopcount doesn't
get rezeroed).
2: an entry with ":tc=foo" but no trailing colon will cause coredumps.
3. buffer overflows can still occur, causing coredumps.
4. in tc=foo, foo can only be 16 chars long. this is not checked.
Apply patch at will.
Tony Hansen
pegasus!hansen
*** /tmp/termcap.c Fri Apr 26 16:41:17 1985
--- /tmp/ntermcap.c Fri Apr 26 16:57:40 1985
***************
*** 2,8
static char sccsid[] = "@(#)termcap.c 4.1 (Berkeley) 6/27/83";
#endif
! #define BUFSIZ 1024
#define MAXHOP 32 /* max number of tc= indirections */
#define E_TERMCAP "/etc/termcap"
--- 2,8 -----
static char sccsid[] = "@(#)termcap.c 4.1 (Berkeley) 6/27/83";
#endif
! #define TBUFSIZE 2048
#define MAXHOP 32 /* max number of tc= indirections */
#define E_TERMCAP "/etc/termcap"
***************
*** 36,41
tgetent(bp, name)
char *bp, *name;
{
register char *cp;
register int c;
register int i = 0, cnt = 0;
--- 36,59 -----
tgetent(bp, name)
char *bp, *name;
{
+ /* Tony Hansen */
+ int ret;
+ hopcount = 0;
+ ret = _tgetent(bp, name);
+ /*
+ There is some sort of bug in the check way down below to prevent
+ buffer overflow. I really don't want to track it down, so I
+ upped the standard buffer size and check here to see if the created
+ buffer is larger than the old buffer size.
+ */
+ if (strlen(bp) >= 1024)
+ write(2,"Termcap entry too long\n", 23);
+ return ret;
+ }
+
+ static _tgetent(bp, name)
+ char *bp, *name;
+ {
register char *cp;
register int c;
register int i = 0, cnt = 0;
***************
*** 39,45
register char *cp;
register int c;
register int i = 0, cnt = 0;
! char ibuf[BUFSIZ];
char *cp2;
int tf;
--- 57,63 -----
register char *cp;
register int c;
register int i = 0, cnt = 0;
! char ibuf[TBUFSIZ];
char *cp2;
int tf;
***************
*** 77,83
cp = bp;
for (;;) {
if (i == cnt) {
! cnt = read(tf, ibuf, BUFSIZ);
if (cnt <= 0) {
close(tf);
return (0);
--- 95,101 -----
cp = bp;
for (;;) {
if (i == cnt) {
! cnt = read(tf, ibuf, TBUFSIZE);
if (cnt <= 0) {
close(tf);
return (0);
***************
*** 92,98
}
break;
}
! if (cp >= bp+BUFSIZ) {
write(2,"Termcap entry too long\n", 23);
break;
} else
--- 110,116 -----
}
break;
}
! if (cp >= bp+TBUFSIZE) {
write(2,"Termcap entry too long\n", 23);
break;
} else
***************
*** 120,125
tnchktc()
{
register char *p, *q;
char tcname[16]; /* name of similar terminal */
char tcbuf[BUFSIZ];
char *holdtbuf = tbuf;
--- 138,145 -----
tnchktc()
{
register char *p, *q;
+ #define TERMNAMESIZE 16
+ char tcname[TERMNAMESIZE]; /* name of similar terminal */
char tcname[16]; /* name of similar terminal */
char tcbuf[TBUFSIZE];
char *holdtbuf = tbuf;
***************
*** 121,127
{
register char *p, *q;
char tcname[16]; /* name of similar terminal */
! char tcbuf[BUFSIZ];
char *holdtbuf = tbuf;
int l;
--- 141,147 -----
#define TERMNAMESIZE 16
char tcname[TERMNAMESIZE]; /* name of similar terminal */
char tcname[16]; /* name of similar terminal */
! char tcbuf[TBUFSIZE];
char *holdtbuf = tbuf;
int l;
***************
*** 135,140
/* p now points to beginning of last field */
if (p[0] != 't' || p[1] != 'c')
return(1);
strcpy(tcname,p+3);
q = tcname;
while (q && *q != ':')
--- 155,161 -----
/* p now points to beginning of last field */
if (p[0] != 't' || p[1] != 'c')
return(1);
+ strncpy(tcname,p+3, TERMNAMESIZE); /* TLH */
strcpy(tcname,p+3);
q = tcname;
while (*q && *q != ':')
***************
*** 137,143
return(1);
strcpy(tcname,p+3);
q = tcname;
! while (q && *q != ':')
q++;
*q = 0;
if (++hopcount > MAXHOP) {
--- 158,164 -----
strncpy(tcname,p+3, TERMNAMESIZE); /* TLH */
strcpy(tcname,p+3);
q = tcname;
! while (*q && *q != ':')
q++;
*q = 0;
if (++hopcount > MAXHOP) {
***************
*** 144,150
write(2, "Infinite tc= loop\n", 18);
return (0);
}
! if (tgetent(tcbuf, tcname) != 1)
return(0);
for (q=tcbuf; *q != ':'; q++)
;
--- 165,171 -----
write(2, "Infinite tc= loop\n", 18);
return (0);
}
! if (_tgetent(tcbuf, tcname) != 1)
return(0);
for (q=tcbuf; *q != ':'; q++)
;
***************
*** 149,155
for (q=tcbuf; *q != ':'; q++)
;
l = p - holdtbuf + strlen(q);
! if (l > BUFSIZ) {
write(2, "Termcap entry too long\n", 23);
q[BUFSIZ - (p-tbuf)] = 0;
}
--- 170,176 -----
for (q=tcbuf; *q != ':'; q++)
;
l = p - holdtbuf + strlen(q);
! if (l > TBUFSIZE) {
write(2, "Termcap entry too long\n", 23);
q[TBUFSIZE - (p-tbuf)] = 0;
}
***************
*** 151,157
l = p - holdtbuf + strlen(q);
if (l > BUFSIZ) {
write(2, "Termcap entry too long\n", 23);
! q[BUFSIZ - (p-tbuf)] = 0;
}
strcpy(p, q+1);
tbuf = holdtbuf;
--- 172,178 -----
l = p - holdtbuf + strlen(q);
if (l > TBUFSIZE) {
write(2, "Termcap entry too long\n", 23);
! q[TBUFSIZE - (p-tbuf)] = 0;
}
strcpy(p, q+1);
tbuf = holdtbuf;
More information about the Comp.unix.wizards
mailing list