Race condition in tdb_runtime_check_for_robust_mutexes()
Jeremy Allison
jra at samba.org
Fri Mar 25 18:13:03 UTC 2016
On Fri, Mar 25, 2016 at 06:10:24AM +0100, Ralph Boehme wrote:
> On Thu, Mar 24, 2016 at 11:34:11PM +0200, Uri Simchoni wrote:
> > On 03/24/2016 04:57 PM, Ralph Boehme wrote:
> > > Something like the attached patch. This can probably be enhanced by
> > > using pselect with a timeout and a signal mask to block/unblock
> > > SIGCHLD instead of sleep.
> > >
> > ENOPATCH?
>
> gna, attached.
Not too keen on this one. I really don't like the
playing with the signal handler SA_RESTART flags :-(.
Plus sleep(1) is *way* too long. Use usleep(100) (or
the select()-based alternative already used in tdb).
> --
> SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
> phone: +49-551-370000-0, fax: +49-551-370000-9
> AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
> http://www.sernet.de,mailto:kontakt@sernet.de
> From 091cfad07a7693cb88f76e46f576fd39978bdc6f Mon Sep 17 00:00:00 2001
> From: Ralph Boehme <slow at samba.org>
> Date: Thu, 24 Mar 2016 15:49:13 +0100
> Subject: [PATCH] WIP: only call waitpid() in the signal handler
>
> ---
> lib/tdb/common/mutex.c | 36 ++++++++++--------------------------
> 1 file changed, 10 insertions(+), 26 deletions(-)
>
> diff --git a/lib/tdb/common/mutex.c b/lib/tdb/common/mutex.c
> index fae43d4..9556238 100644
> --- a/lib/tdb/common/mutex.c
> +++ b/lib/tdb/common/mutex.c
> @@ -723,9 +723,6 @@ static bool tdb_robust_mutex_setup_sigchild(void (*handler)(int),
> memset(&act, '\0', sizeof(act));
>
> act.sa_handler = handler;
> -#ifdef SA_RESTART
> - act.sa_flags = SA_RESTART;
> -#endif
> sigemptyset(&act.sa_mask);
> sigaddset(&act.sa_mask, SIGCHLD);
> sigaction(SIGCHLD, &act, &oldact);
> @@ -884,17 +881,11 @@ _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void)
> }
>
> while (tdb_robust_mutex_pid > 0) {
> - pid_t pid;
> -
> - errno = 0;
> - pid = waitpid(tdb_robust_mutex_pid, &status, 0);
> - if (pid == tdb_robust_mutex_pid) {
> - tdb_robust_mutex_pid = -1;
> - break;
> - }
> - if (pid == -1 && errno != EINTR) {
> - goto cleanup_child;
> - }
> + /*
> + * RACE: if the SIGCHLD is delivered now, *before* the
> + * sleep, we will unneededly sleep for one second.
> + */
> + sleep(1);
> }
> tdb_robust_mutex_setup_sigchild(tdb_robust_mutext_old_handler, NULL);
>
> @@ -927,19 +918,12 @@ _PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void)
>
> cleanup_child:
> while (tdb_robust_mutex_pid > 0) {
> - pid_t pid;
> -
> + /*
> + * RACE: if the SIGCHLD is delivered now, *before* the
> + * sleep, we will unneededly sleep for one second.
> + */
> kill(tdb_robust_mutex_pid, SIGKILL);
> -
> - errno = 0;
> - pid = waitpid(tdb_robust_mutex_pid, &status, 0);
> - if (pid == tdb_robust_mutex_pid) {
> - tdb_robust_mutex_pid = -1;
> - break;
> - }
> - if (pid == -1 && errno != EINTR) {
> - break;
> - }
> + sleep();
> }
> cleanup_sig_child:
> tdb_robust_mutex_setup_sigchild(tdb_robust_mutext_old_handler, NULL);
> --
> 2.5.0
>
More information about the samba-technical
mailing list