Subject: bin/26813: talkd's tty searching is broken
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <dholland@eecs.harvard.edu>
List: netbsd-bugs
Date: 08/31/2004 01:25:11
>Number: 26813
>Category: bin
>Synopsis: talkd's tty searching is broken
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Aug 31 05:26:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator: David A. Holland <dholland@eecs.harvard.edu>
>Release: NetBSD 2.0G (20040827)
>Organization:
Harvard EECS
>Environment:
System: NetBSD alicante 2.0G NetBSD 2.0G (ALICANTE) #9: Fri Aug 27 17:49:09 EDT 2004 dholland@alicante:/usr/src/sys/arch/i386/compile/ALICANTE i386
Architecture: i386
Machine: i386
>Description:
Some time ago I noticed that talkd had lost the ability to
find the least idle tty. Tonight it also spuriously told
someone I was mesg n: time to investigate.
Now, talkd's tty search code stats all the ttys in utmp
looking for the best match. In order to stat, it has to
prepend _PATH_DEV to ut_line from utmp. It does this by first
preinitializing a buffer with _PATH_DEV, then looping over
the utmp entries copying tty names into the tail of the
buffer.
This was originally done with strcpy. A while back itojun
changed it to use a bounded string function, but seems to
have accidentally used strlcat rather than strlcpy. The
result of this is that on the first iteration of the loop, it
gets the first tty properly, but on the second iteration it
tries to stat things like "/dev/ttyp0ttyp1", which of course
don't exist. The upshot is that talkd only ever sees the first
tty listed in utmp for the user.
If the user is only logged in once, this is immaterial; but
otherwise, only the first tty found is ever used. If that tty
is an iconified xterm six weeks idle, the user will probably
never see the talk request; if that tty is mesg n, talkd
will claim that the user is refusing messages entirely, even
if other ttys are mesg y.
>How-To-Repeat:
Go to the console and log in user1 on ttyE0 and then on ttyE1;
set ttyE0 mesg n, and ttyE1 mesg y. Then log in as user2
somewhere else and send a talk request to user1 without
specifying a tty explicitly, like this:
talk user1
Provided utmp is ordered normally, it will incorrectly report
"Your party is refusing messages".
>Fix:
Back out the version 1.9 change to talkd/process.c, or
alternatively apply this patch.
Index: process.c
===================================================================
RCS file: /cvsroot/src/libexec/talkd/process.c,v
retrieving revision 1.10
diff -u -r1.10 process.c
--- process.c 7 Aug 2003 09:46:50 -0000 1.10
+++ process.c 31 Aug 2004 04:56:06 -0000
@@ -197,7 +197,6 @@
(void)getutentries(NULL, &ep);
status = NOT_HERE;
- (void) strlcpy(ftty, _PATH_DEV, sizeof(ftty));
if (*tty == '\0')
anytty = 1;
@@ -207,7 +206,8 @@
continue;
if (anytty) {
/* no particular tty was requested */
- (void)strlcat(ftty, ep->line, sizeof(ftty));
+ (void)snprintf(ftty, sizeof(ftty),
+ "%s%s", _PATH_DEV, ep->line);
if (stat(ftty, &statb) != 0)
continue;
>Release-Note:
>Audit-Trail:
>Unformatted: