From owner-freebsd-bugs@FreeBSD.ORG Thu Dec 23 15:22:23 2004 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D0CFE16A4CE for ; Thu, 23 Dec 2004 15:22:23 +0000 (GMT) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3860643D45 for ; Thu, 23 Dec 2004 15:22:23 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy1.pacific.net.au (mailproxy1.pacific.net.au [61.8.0.86])iBNFMMA6030950; Fri, 24 Dec 2004 02:22:22 +1100 Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) iBNFMJ3X009558; Fri, 24 Dec 2004 02:22:20 +1100 Date: Fri, 24 Dec 2004 02:22:19 +1100 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: "Oleg V. Nauman" In-Reply-To: <200412191530.iBJFUPXC079591@freefall.freebsd.org> Message-ID: <20041224014730.R73904@delplex.bde.org> References: <200412191530.iBJFUPXC079591@freefall.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-bugs@FreeBSD.org Subject: Re: bin/75258: [patch] dd(1) has not async signal safe interrupt handlers X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Dec 2004 15:22:23 -0000 On Sun, 19 Dec 2004, Oleg V. Nauman wrote: > On Sun, Dec 19, 2004 at 06:11:06PM +0300, Maxim Konovalov wrote: > > [...] > > > >Description: > > > dd(1) uses not safe interrupt handlers, they may leads to > > > strange problems with dd > >=20 > > Are you sure? Do you have a testcase? > > No, sorry. However, the patch in the PR would cause strange problems like breaking termination of dd when the input is from certain slow devices, e.g., terminals. Input is normally restarted after a signal, so just setting a flag in the signal handler normally doesn't work. Most "fixes" for unsafe signal handling get this wrong. To get this right, something like the following must be done: - use sigaction() without SA_RESTART instead of signal(), or use siginterrupt() to turn off SA_RESTART. I've only seen this done right for fixing unsafe signal handling in ping(8) I've seen it done wrong in top(1) (try hitting ^C in command mode in top). - handle the resulting EINTR errors from all syscalls that may now fail with this error instead of being restarted. This is difficult or impossible in large programs. If the signal is checked for and acted on after every EINTR, then you have the same problem as acting on it directly in signal handlers (the syscall might be in a context that doesn't or shouldn't know if it is safe to act), plus maintainence problems for checking and acting all over. If the acton is delayed, then the program must somehow be structured to ensure that control is passed up to a level that can safely act; in particular, no more syscalls that might block can be made. I suppose the latter could be implemented simply but laboriously by wrapping all syscalls with { if (signalflag) { errno = EINTR; return (-1); } else { normalcall(); }. > >=20 > > > >How-To-Repeat: > > > > > > man 2 sigaction > >=20 > > Well, stdio(3) is not signal-safe in general but it seems for me > > summary() does not manipulate with the internal state of any file > > descriptors (it uses write(2)) and should be safe. > > But s*printf() family uses malloc(3) for his internal purposes, > and there is no any reasons for things like memory allocations in > the signal handler, I think. s*printf() needs to be signal-safe in practice. It is careful to use only local storage for this reason. Only asprintf() uses malloc(). summary() is obviously attempting to be signal-safe (even in rev.1.1). It avoids using printf() but depends on snprintf() being signal safe since the formatting would be too hard otherwise. Bruce