Subject: lib/12863: "screen -T foo" results in coredump in libc/gen/getcap.c
To: None <gnats-bugs@gnats.netbsd.org>
From: Hubert Feyrer <feyrer@smaug.fh-regensburg.de>
List: netbsd-bugs
Date: 05/08/2001 02:55:10
>Number: 12863
>Category: lib
>Synopsis: "screen -T foo" results in coredump in libc/gen/getcap.c
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: hubertf
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon May 07 17:55:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Hubert Feyrer
>Release: 1.5.1_BETA as or 20010508
>Organization:
Hubert Feyrer <hubertf@channel.regensburg.org>
>Environment:
System: NetBSD miyu 1.5.1_BETA NetBSD 1.5.1_BETA (MIYU) #4: Mon May 7 01:39:40 MEST 2001 feyrer@miyu:/usr/cvs/src-1.5/sys/arch/i386/compile/MIYU i386
>Description:
"screen -T foo" dumps core when executed by a normal user and
screen is setuid.
>How-To-Repeat:
install screen from pkgsrc, run it: screen -T foo
See it dump core.
>Fix:
I'm not sure if this a problem on libc/libcurses/libtermcap,
or in screen.
The codepath in screen here is:
do {
...
if (e_tgetent(buf, p) == 1) {
break;
strcpy(p, "vt100");
}
while (0); /* Goto free programming... */
/* check for compatibility problems, displays == 0 after fork */
{
char xbuf[TERMCAP_BUFSIZE], *xbp = xbuf;
if (tgetstr("im", &xbp) && tgetstr("ic", &xbp) && displays)
...
With -T foo, 'p' is set to "foo" for the e_tgetent() call, which is
just a wrapper for tgetent(). As we don't know term type "foo",
e_tgetent() fails, and it will strcpy "vt100" into the terminal
type 'p', but then exits ("while(0)") instead of trying vt100.
Leaving aside that this is probably a bug in screen, it continues
after the failed (e_)tgetent(), and calls tgetstr() next.
As some internal buffer (fbuf, in termlib/termcap.c) is not properly
initialized due to the error, a null pointer is passed in info->info
to t_getstr(), and as we don't have DIAGASSERT() defined by default,
this is not detected and it finally blows up in _cgetcap().
Can someone confirm that the behaviour of dumping core in this
situation is wanted, when a program decides to ignore a return code?
In that case I'd like to point the screen maintainers to the data
collected in the PR here.
A diff against screen 3.9.8 that fixes the problem is:
--- termcap.c.orig Tue May 8 02:43:24 2001
+++ termcap.c
@@ -773,6 +773,13 @@
if (e_tgetent(buf, p) == 1)
break;
strcpy(p, "vt100");
+#if 1
+ if (e_tgetent(buf, p) == 1) {
+ break;
+ } else {
+ abort(); /* no vt100 ...! */
+ }
+#endif
}
while (0); /* Goto free programming... */
Final comment:
This problem was not detected by me but by syke@newhackcity.net.
I just did the debugging of what's wrong.
The full call tree of the crash in screen is:
Core was generated by `screen'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/libexec/ld.elf_so...done.
Reading symbols from /usr/lib/libcurses.so.3...done.
Reading symbols from /usr/lib/libutil.so.5...done.
Reading symbols from /usr/lib/libcrypt.so.0...done.
Reading symbols from /usr/lib/libc.so.12...done.
#0 0x480f4e03 in _cgetcap (buf=0x0, cap=0xbfbfb51c "im", type=61)
at /usr/cvs/src-1.5/lib/libc/gen/getcap.c:172
172 if (*bp == '\0')
(gdb) bt
#0 0x480f4e03 in _cgetcap (buf=0x0, cap=0xbfbfb51c "im", type=61)
at /usr/cvs/src-1.5/lib/libc/gen/getcap.c:172
#1 0x480f5f2a in _cgetstr (buf=0x0, cap=0xbfbfb51c "im", str=0xbfbfb4fc)
at /usr/cvs/src-1.5/lib/libc/gen/getcap.c:906
#2 0x480a58d1 in t_getstr (info=0x808cb20, id=0xbfbfb51c "im",
area=0xbfbfb568, limit=0x0)
at /usr/cvs/src-1.5/lib/libcurses/../libterm/termcap.c:364
#3 0x480a59a6 in tgetstr (id=0x8076ce2 "im", area=0xbfbfb568)
at /usr/cvs/src-1.5/lib/libcurses/../libterm/termcap.c:426
#4 0x8060a04 in MakeTermcap (aflag=0) at termcap.c:782
#5 0x8060091 in InitTermcap (wi=0, he=0) at termcap.c:472
#6 0x804baf2 in main (ac=0, av=0xbfbfd4f8) at screen.c:1164
#7 0x8049fb5 in ___start ()
>Release-Note:
>Audit-Trail:
>Unformatted: