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: