NetBSD Problem Report #40109

From mouse@Sparkle.Rodents-Montreal.ORG  Fri Dec  5 00:51:24 2008
Return-Path: <mouse@Sparkle.Rodents-Montreal.ORG>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id 663EC63BAE7
	for <gnats-bugs@gnats.NetBSD.org>; Fri,  5 Dec 2008 00:51:24 +0000 (UTC)
Message-Id: <200812050051.TAA18507@Sparkle.Rodents-Montreal.ORG>
Date: Thu, 4 Dec 2008 19:51:21 -0500 (EST)
From: der Mouse <mouse@Rodents-Montreal.ORG>
Reply-To: mouse@Rodents-Montreal.ORG
To: gnats-bugs@gnats.NetBSD.org
Subject: [dM] PARMRK bugs
X-Send-Pr-Version: 3.95

>Number:         40109
>Category:       kern
>Synopsis:       Buggy PARMRK treatment of \377
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Dec 05 00:55:00 +0000 2008
>Last-Modified:  Mon Jan 12 23:20:02 +0000 2009
>Originator:     der Mouse
>Release:        -current as of tty.c,v 1.228
>Organization:
	Dis-
>Environment:
	Any 1.4T or 4.0 - probably everything in between.
>Description:
	(1) PARMRK's escaping of \377 doesn't work unless INPCK is set
	too.

	termios(4) says, of PARMRK,

		If PARMRK is set, and IGNPAR is not set, [...].  To
		avoid ambiguity in this case, if ISTRIP is not set, a
		valid character of `\377' is given to the application
		as `\377', `\377'.

	However, the code does not actually do this doubling unless
	INPCK is also set:

	} else if (c == 0377 &&
	    ISSET(iflag, ISTRIP|IGNPAR|INPCK|PARMRK) == (INPCK|PARMRK)) {
		/* "Escape" a valid character of '\377'. */
		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
		goto endcase;
	}

	I believe this is a code bug, not a doc bug, because the
	documented behaviour is more useful - an application may want
	to distinguish between a break condition and a 0x00 character
	without turning on input parity checking.  (Indeed, it was just
	such an application that led me to discover this.)

	(2) If PARMRK _does_ escape a \377, there's a good deal of
	other processing that gets bypassed, thanks to "goto endcase".
	For example, ttwakeup() and ttyecho() don't get called, so an
	isolated 0xff will mysteriously fail to wake up an application
	blocking for tty input (my application ran into this too), and
	won't get echoed even if echoing is enabled.

>How-To-Repeat:
	Write code to distinguish between breaks and 0x00, but without
	parity checking, based on the manpage.  Try it and find it's
	not working as documented - 0xff characters don't get doubled.

	Fix that bug and then find your program blocking waiting for an
	input character even when a 0xff gets sent.
>Fix:
	In progress.  Removing INPCK from its two appearances in the
	snippet quoted above fixes the no-quoting bug, but then there's
	the no-wakeup bug too.  I'm working on fixing that, but it's
	more involved - especially since it also affects input that is
	correctly framed but has incorrect parity, something that is
	(slightly) more difficult for me to test.

	I'll append to this PR when I have patches.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse@rodents-montreal.org
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

>Audit-Trail:
From: der Mouse <mouse@Rodents-Montreal.ORG>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/40109: [dM] PARMRK bugs
Date: Mon, 12 Jan 2009 18:15:39 -0500 (EST)

 Here's the patch I've been running with.  The line numbers are probably
 off (this is not the only patch I have to tty.c), and it may well not
 be a fully right fix, but it seems to work for me.

 --- base/sys/kern/tty.c	Sat Feb 19 19:56:26 2000
 +++ live/sys/kern/tty.c	Fri Dec  5 03:30:17 2008
 @@ -358,13 +360,6 @@
  				c = 0;
  		}
  	}
 -	else if (c == 0377 &&
 -	    ISSET(iflag, ISTRIP|IGNPAR|INPCK|PARMRK) == (INPCK|PARMRK)) {
 -		/* "Escape" a valid character of '\377'. */
 -		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
 -		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
 -		goto endcase;
 -	}

  	/*
  	 * In tandem mode, check high water mark.
 @@ -582,6 +577,11 @@
  	 * Put data char in q for user and
  	 * wakeup on seeing a line delimiter.
  	 */
 +	if ((c == 0377) && (ISSET(iflag,ISTRIP|IGNPAR|PARMRK) == PARMRK)) {
 +		/* "Escape" a valid character of '\377'. */
 +		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
 +		c = 0377 | TTY_QUOTE;
 +	}
  	if (putc(c, &tp->t_rawq) >= 0) {
  		if (!ISSET(lflag, ICANON)) {
  			ttwakeup(tp);

 /~\ The ASCII				  Mouse
 \ / Ribbon Campaign
  X  Against HTML		mouse@rodents-montreal.org
 / \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

>Unformatted:
 	(Also present as far back as tty.c,v 1.115, probably farther.)

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.