NetBSD Problem Report #50322

From www@NetBSD.org  Fri Oct  9 17:23:49 2015
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id B2324A5858
	for <gnats-bugs@gnats.NetBSD.org>; Fri,  9 Oct 2015 17:23:49 +0000 (UTC)
Message-Id: <20151009172348.6057EA65C8@mollari.NetBSD.org>
Date: Fri,  9 Oct 2015 17:23:48 +0000 (UTC)
From: fstd.lkml@gmail.com
Reply-To: fstd.lkml@gmail.com
To: gnats-bugs@NetBSD.org
Subject: tail -F <file> misbehaves with stdin closed
X-Send-Pr-Version: www-1.0

>Number:         50322
>Category:       bin
>Synopsis:       tail -F <file> misbehaves with stdin closed
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Oct 09 17:25:00 +0000 2015
>Closed-Date:    Sun Jan 24 13:05:30 +0000 2021
>Last-Modified:  Sun Jan 24 13:05:30 +0000 2021
>Originator:     Timo Buhrmester
>Release:        7.0
>Organization:
>Environment:
NetBSD frozen.localdomain 7.0 NetBSD 7.0 (FRZKERN32) #0: Tue Sep 29 04:46:38 CEST 2015  build@frozen.localdomain:/usr/build/obj-frozen32-i386-i386/sys/arch/i386/compile/FRZKERN32 i386
>Description:
The point of tail -F /some/file is to follow the contents in /some/file, even if /some/file is occasionally replaced with a different file, e.g. due to newsyslog(8) running.  In this mode of operation, standard input is ignored, as it should be.

Now, if standard input happens to be closed, for example by running
tail -F /some/file <&-
or by it being used inside a script that has its standard input closed (possibly as a result of daemonizing the script), tail's attempt to fopen(3) /some/file will open the file at fd 0 - the typical fd for stdin.

However, later on, tail effectively uses fd == 0 to determine whether it is reading from stdin or not.  If /some/file was opened at fd 0, tail will hence consider itself to be reading from stdin and omit adding the vnode filters to kqueue/kevent.

The result is that it will not follow the file after newsyslog(8) rotated the file away; it will instead forever be stuck in kevent(2).

I've been hit by this for a long time, only yesterday managed to finally find this (Heisen)bug.

The root cause of the problem is that tail assumes fd 0 is standard input.  It does this in two places by comparing `fileno(fp)` to `STDIN_FILENO`.  (`fp` being a FILE * as returned by fopen(3) or freopen(3)).
It should instead compare `fp` to `stdin`.
>How-To-Repeat:
Terminal 1:
$ touch /tmp/foo
$ tail -F /tmp/foo <&-

Terminal 2:
$ echo foo >>/tmp/foo  # Outputs 'foo' on Terminal 1
$ rm /tmp/foo
$ echo bar >>/tmp/foo  # SHOULD output 'bar' on Terminal 1, but does not.
>Fix:
--- usr.bin/tail/forward.c.orig 2015-10-09 19:17:34.000000000 +0200
+++ usr.bin/tail/forward.c      2015-10-09 19:17:54.000000000 +0200
@@ -198,7 +198,7 @@
                        n = 0;

                        memset(ev, 0, sizeof(ev));
-                       if (fflag == 2 && fileno(fp) != STDIN_FILENO) {
+                       if (fflag == 2 && fp != stdin) {
                                EV_SET(&ev[n], fileno(fp), EVFILT_VNODE,
                                    EV_ADD | EV_ENABLE | EV_CLEAR,
                                    NOTE_DELETE | NOTE_RENAME, 0, 0);
@@ -240,7 +240,7 @@
                         */
                        (void) sleep(1);

-                       if (fflag == 2 && fileno(fp) != STDIN_FILENO &&
+                       if (fflag == 2 && fp != stdin &&
                            stat(fname, &statbuf) != -1) {
                                if (statbuf.st_ino != sbp->st_ino ||
                                    statbuf.st_dev != sbp->st_dev ||

>Release-Note:

>Audit-Trail:
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/50322 CVS commit: src/usr.bin/tail
Date: Fri, 9 Oct 2015 13:51:27 -0400

 Module Name:	src
 Committed By:	christos
 Date:		Fri Oct  9 17:51:27 UTC 2015

 Modified Files:
 	src/usr.bin/tail: forward.c

 Log Message:
 PR/50322: Timo Buhrmester: tail -F <file> misbehaves with stdin closed
 Compare fp with stdin not fileno(fp) with STDIN_FILENO, because if tail
 is called with 0 closed, then we are not going to be setting event filters
 for the file because we'll erroneously think it is stdin.


 To generate a diff of this commit:
 cvs rdiff -u -r1.32 -r1.33 src/usr.bin/tail/forward.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: jdolecek@NetBSD.org
State-Changed-When: Sun, 24 Jan 2021 13:05:30 +0000
State-Changed-Why:
The patch was actually committedd in 2015.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.