lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 27 Feb 2008 23:04:38 +0100 (CET)
From:	Jiri Kosina <jkosina@...e.cz>
To:	Roland McGrath <roland@...hat.com>
cc:	Oleg Nesterov <oleg@...sign.ru>,
	Davide Libenzi <davidel@...ilserver.org>,
	Andrew Morton <akpm@...ux-foundation.org>,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH] [RFC] fix missed SIGCONT cases

On Wed, 27 Feb 2008, Roland McGrath wrote:

> Have you observed an actual problem?  I don't think the "race" you seem 
> to be concerned about is a problem at all.
> The comment refers to the necessary atomicity of posting the signal along
> with doing the wakeups.  Those are done together with the siglock held.
> It does not matter that the siglock was dropped and reacquired before
> there.  

What happens here is that the proces that was woken-up is spinning on the 
siglock even before the actual SIGCONT has been queued. When this lock is 
released, the process continues executing, and its SIGCONT handler doesn't 
run, even though it executes _just because_ it was woken up by SIGCONT. 

Let's take this as an example:

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

volatile int sigcont_received = 0;

static void sigcont_handler(int signo)
{
	sigcont_received = 1;
}

int main(int argc, char **argv)
{

	struct sigaction action;

	memset(&action, 0, sizeof(action));
	action.sa_handler = sigcont_handler;
	sigemptyset(&action.sa_mask);

	if (sigaction(SIGCONT, &action, NULL) != 0) {
		fprintf(stderr, "sigaction() failed\n");
		return 1;
	}

	while (1) {
		if (kill(getpid(), SIGSTOP) != 0) {
			printf("could not send SIGSTOP to self\n");
			return 1;
		}

			if (sigcont_received)
				printf("finished (SIGCONT received)\n");
			else
				printf("finished (without SIGCONT)\n");
		sigcont_received = 0;
	}
	return 0;
}

Do you agree that when you run this program, and once it gets stopped 
(sends SIGSTOP to itself), send SIGCONT to it. It should always print

	finished (SIGCONT received)

right? Without my patch, sometimes 

	finished (without SIGCONT)

can be observed (for some reason, it seems to trigger more often on ia64 
machines than on any x86 hardware).

Thanks,

-- 
Jiri Kosina
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ