Subject: kern/7572: sigaction() error checking too thorough?
To: None <gnats-bugs@gnats.netbsd.org>
From: John F. Woods <jfw@jfwhome.funhouse.com>
List: netbsd-bugs
Date: 05/12/1999 20:22:07
>Number:         7572
>Category:       kern
>Synopsis:       sigaction() error checking too thorough?
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed May 12 20:20:00 1999
>Last-Modified:
>Originator:     John F. Woods
>Organization:
Misanthropes-R-Us
>Release:        NetBSD 1.4 Release
>Environment:
System: NetBSD jfwhome.funhouse.com 1.4 NetBSD 1.4 (JFW) #1: Mon May 10 21:33:20 EDT 1999 jfw@jfwhome.funhouse.com:/usr/src/sys/arch/i386/compile/JFW i386


>Description:
The netatalk-1.4b2+asun version does not work over TCP/IP due to a possibly
inappropriate error check in sigaction().

A routine in netatalk-1.4b2+asun calls sigaction for SIGALRM with a
struct sigaction which is uninitialized except for the sa_handler.  The
program is certainly wrong to do this, and I'm fixing it and sending a note
to the author; however, reading the manual page, I'm not convinced that
sigaction should be returning the error which it is returning.

Sigaction is returning EINVAL, and reading through the code suggests that
it is failing the following test:

	if (nsa) {
		if (nsa->sa_flags & ~SA_ALLBITS)
			return (EINVAL);

But the manual page certainly does not document this (sensible) error check;
the manual only describes these error conditions:

     [EFAULT]      Either act or oact points to memory that is not a valid
                   part of the process address space.

     [EINVAL]      sig is not a valid signal number.

     [EINVAL]      An attempt is made to ignore or supply a handler for
                   SIGKILL or SIGSTOP.

I don't have a POSIX manual handy, and I don't remember the rules for whether
an implementation may gratuitously add error cases to POSIX routines; if this
added check is allowed by the standard, it should certainly be documented
on the manual page for sigaction.

>How-To-Repeat:
1) Spend a day adjusting patches to turn the pkgsrc version of netatalk into
   netatalk-1.4b2.
2) Run it.
3) Try to connect via TCP/IP, whilst simultaneously being so unlucky as to have
   thoroughly inappropriate junk on the stack in just the wrong place in
   dsi_open_tcp.
4) Read /var/log/messages for the sigaction failure.

>Fix:
In addition to repairing the broken application, either the error check 
should be changed to

	if (nsa) {
		nsa->sa_flags &= SA_ALLBITS;

or the manual page should acquire documentation like

.It Bq Er EINVAL
The
.Em sa_flags
word contains bits other than 
.Dv SA_RESTART ,
.Dv SA_NOCLDWAIT ,
.Dv SA_NOCLDSTOP ,
and
.Dv SA_ONSTACK .

>Audit-Trail:
>Unformatted: