All of lore.kernel.org
 help / color / mirror / Atom feed
From: Erik Andersen <andersen@codepoet.org>
To: linux-kernel <linux-kernel@vger.kernel.org>
Cc: Marcelo Tosatti <marcelo.tosatti@cyclades.com>
Subject: [PATCH] fix broken 2.4.x rt_sigprocmask error handling
Date: Wed, 31 Dec 2003 04:45:01 -0700	[thread overview]
Message-ID: <20031231114501.GA14865@codepoet.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 2051 bytes --]

SuSv3 says:

	"The argument 'how' indicates the way in which the set is
	changed, and the application shall ensure it consists of
	one of [SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK] ... If
	sigprocmask() fails, the thread's signal mask shall not
	be changed."

The sigprocmask(2) syscall implements this correctly, however the
rt_sigprocmask(2) syscall in 2.4.x does not comply with SuSv3.
When this syscall is provided with a valid 'set' value, and a
bogus value for 'how', the process signal mask is still changed.

The attached test application demonstrates the problem.  This
patch below fixes it.  Please apply!


--- linux/kernel/signal.c.orig	2003-12-31 04:01:59.000000000 -0700
+++ linux/kernel/signal.c	2003-12-31 04:38:06.000000000 -0700
@@ -879,16 +879,16 @@
 			error = -EINVAL;
 			break;
 		case SIG_BLOCK:
-			sigorsets(&new_set, &old_set, &new_set);
+			sigorsets(&current->blocked, &old_set, &new_set);
 			break;
 		case SIG_UNBLOCK:
-			signandsets(&new_set, &old_set, &new_set);
+			signandsets(&current->blocked, &old_set, &new_set);
 			break;
 		case SIG_SETMASK:
+			current->blocked = new_set;
 			break;
 		}
 
-		current->blocked = new_set;
 		recalc_sigpending(current);
 		spin_unlock_irq(&current->sigmask_lock);
 		if (error)
--- linux/CREDITS	2003-12-02 13:04:50.000000000 -0700
+++ linux/CREDITS	2003-12-02 13:04:50.000000000 -0700
@@ -82,13 +82,13 @@
 S: USA
 
 N: Erik Andersen
-E: andersee@debian.org
-W: http://www.xmission.com/~andersen
-P: 1024/FC4CFFED 78 3C 6A 19 FA 5D 92 5A  FB AC 7B A5 A5 E1 FF 8E
+E: andersen@codepoet.org
+W: http://www.codepoet.org/
+P: 1024D/30D39057 1BC4 2742 E885 E4DE 9301  0C82 5F9B 643E 30D3 9057
 D: Maintainer of ide-cd and Uniform CD-ROM driver, 
 D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update.
-S: 4538 South Carnegie Tech Street
-S: Salt Lake City, Utah 84120
+S: 352 North 525 East
+S: Springville, Utah 84663
 S: USA
 
 N: Michael Ang

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

[-- Attachment #2: test-setprocmask.c --]
[-- Type: text/x-csrc, Size: 1996 bytes --]

#define _GNU_SOURCE
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/syscall.h>


#if 0

/* The sigprocmask syscall works correctly */
_syscall3(int, sigprocmask, int, how, const sigset_t *, set,
	sigset_t *, oldset);

#else

/* The rt_sigprocmask syscall currently fails */
_syscall4(int, rt_sigprocmask, int, how, const sigset_t *, set,
	sigset_t *, oldset, size_t, size);
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
{
	return rt_sigprocmask(how, set, oldset, _NSIG/8);
}

#endif

int main(void)
{
	sigset_t set;
	sigset_t oset;
	int r;

	sigemptyset(&set);
	sigemptyset(&oset);

	/* Block no signals since set is empty.
	 * oset will be set to the app default. */
	errno = 0;
	r = sigprocmask(SIG_SETMASK, &set, &oset);
	if (r != 0) {
		printf("r=%d : %m\n", r);
	}

	/* Block no signals since set is empty.
	 * oset will now also be empty. */
	errno = 0;
	r = sigprocmask(SIG_SETMASK, &set, &oset);
	if (r != 0) {
		printf("r=%d : %m\n", r);
	}

	/* * SuSv3 says:
	 *	"The * argument how indicates the way in which the set is
	 *	changed, and the application shall ensure it consists of one
	 *	of [SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK] ... If sigprocmask()
	 *	fails, the thread's signal mask shall not be changed."
	 *
	 * Attempt to block SIGHUP with a bogus 'how'.  This should fail,
	 * and return EINVAL, and oset should should still be empty. */
	errno = 0;
	r = sigaddset(&set, SIGHUP);
	if (r != 0) {
		printf("r=%d : %m\n", r);
	}
	errno = 0;
	r = sigprocmask(0xdeadbeef, &set, &oset);
	if (r != 0) {
		printf("Expected failure: %m\n");
	}

	/* Query the value of oset.  It should still be empty */
	errno = 0;
	r = sigprocmask(SIG_SETMASK, (sigset_t *)0, &oset);
	if (r != 0) {
		printf("r=%d : %m\n", r);
	}

	/* But oset is not empty!  This is contrary to SuSv3! */
	if (sigismember(&oset, SIGHUP)==1) {
		printf("FAIL -- oset was changed when we supplied an invalid 'how'\n");
		return 1;
	} else {
		printf("PASS\n");
	}

	return 0;
}

             reply	other threads:[~2003-12-31 11:45 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-31 11:45 Erik Andersen [this message]
2004-01-05 13:23 ` [PATCH] fix broken 2.4.x rt_sigprocmask error handling Marcelo Tosatti
2004-01-05 13:56   ` Erik Andersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20031231114501.GA14865@codepoet.org \
    --to=andersen@codepoet.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo.tosatti@cyclades.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.