The Samba-Bugzilla – Attachment 4586 Details for
Bug 6651
smbd SIGSEGV when breaking oplocks
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Git formatted patch for 3.4.1.
0001-Fix-for-bug-6651-smbd-SIGSEGV-when-breaking-oplock.patch (text/plain), 4.34 KB, created by
Jeremy Allison
on 2009-08-21 17:20:42 UTC
(
hide
)
Description:
Git formatted patch for 3.4.1.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2009-08-21 17:20:42 UTC
Size:
4.34 KB
patch
obsolete
>From f0bd4b860b51df4973a80036aece1ecd56fbabb3 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 21 Aug 2009 15:07:25 -0700 >Subject: [PATCH] Fix for bug 6651 - smbd SIGSEGV when breaking oplocks. > Based on a patch submitted by Petr Vandrovec <petr@vandrovec.name>. > Multiple pending signals with siginfo_t's weren't being handled correctly > leading to smbd abort with kernel oplock signals. > Jeremy > >--- > lib/tevent/tevent_signal.c | 71 +++++++++++++++++++++++++++++++++---------- > 1 files changed, 54 insertions(+), 17 deletions(-) > >diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c >index 4a58a8b..27e8624 100644 >--- a/lib/tevent/tevent_signal.c >+++ b/lib/tevent/tevent_signal.c >@@ -97,7 +97,11 @@ static void tevent_common_signal_handler_info(int signum, siginfo_t *info, > void *uctx) > { > uint32_t count = sig_count(sig_state->signal_count[signum]); >- sig_state->sig_info[signum][count] = *info; >+ /* sig_state->signal_count[signum].seen % SA_INFO_QUEUE_COUNT >+ * is the base of the unprocessed signals in the ringbuffer. */ >+ uint32_t ofs = (sig_state->signal_count[signum].seen + count) % >+ SA_INFO_QUEUE_COUNT; >+ sig_state->sig_info[signum][ofs] = *info; > > tevent_common_signal_handler(signum); > >@@ -229,7 +233,7 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, > act.sa_handler = NULL; > act.sa_sigaction = tevent_common_signal_handler_info; > if (sig_state->sig_info[signum] == NULL) { >- sig_state->sig_info[signum] = talloc_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT); >+ sig_state->sig_info[signum] = talloc_zero_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT); > if (sig_state->sig_info[signum] == NULL) { > talloc_free(se); > return NULL; >@@ -294,6 +298,11 @@ int tevent_common_check_signal(struct tevent_context *ev) > struct tevent_common_signal_list *sl, *next; > struct sigcounter counter = sig_state->signal_count[i]; > uint32_t count = sig_count(counter); >+#ifdef SA_SIGINFO >+ /* Ensure we null out any stored siginfo_t entries >+ * after processing for debugging purposes. */ >+ bool clear_processed_siginfo = false; >+#endif > > if (count == 0) { > continue; >@@ -303,25 +312,21 @@ int tevent_common_check_signal(struct tevent_context *ev) > next = sl->next; > #ifdef SA_SIGINFO > if (se->sa_flags & SA_SIGINFO) { >- int j; >+ uint32_t j; >+ >+ clear_processed_siginfo = true; >+ > for (j=0;j<count;j++) { >- /* note the use of the sig_info array as a >- ring buffer */ >- int ofs = ((count-1) + j) % SA_INFO_QUEUE_COUNT; >- se->handler(ev, se, i, 1, >+ /* sig_state->signal_count[i].seen >+ * % SA_INFO_QUEUE_COUNT is >+ * the base position of the unprocessed >+ * signals in the ringbuffer. */ >+ uint32_t ofs = (counter.seen + j) >+ % SA_INFO_QUEUE_COUNT; >+ se->handler(ev, se, i, 1, > (void*)&sig_state->sig_info[i][ofs], > se->private_data); > } >- if (SIG_PENDING(sig_state->sig_blocked[i])) { >- /* we'd filled the queue, unblock the >- signal now */ >- sigset_t set; >- sigemptyset(&set); >- sigaddset(&set, i); >- SIG_SEEN(sig_state->sig_blocked[i], >- sig_count(sig_state->sig_blocked[i])); >- sigprocmask(SIG_UNBLOCK, &set, NULL); >- } > if (se->sa_flags & SA_RESETHAND) { > talloc_free(se); > } >@@ -333,8 +338,40 @@ int tevent_common_check_signal(struct tevent_context *ev) > talloc_free(se); > } > } >+ >+#ifdef SA_SIGINFO >+ if (clear_processed_siginfo) { >+ uint32_t j; >+ for (j=0;j<count;j++) { >+ uint32_t ofs = (counter.seen + j) >+ % SA_INFO_QUEUE_COUNT; >+ memset((void*)&sig_state->sig_info[i][ofs], >+ '\0', >+ sizeof(siginfo_t)); >+ } >+ } >+#endif >+ > SIG_SEEN(sig_state->signal_count[i], count); > SIG_SEEN(sig_state->got_signal, count); >+ >+#ifdef SA_SIGINFO >+ if (SIG_PENDING(sig_state->sig_blocked[i])) { >+ /* We'd filled the queue, unblock the >+ signal now the queue is empty again. >+ Note we MUST do this after the >+ SIG_SEEN(sig_state->signal_count[i], count) >+ call to prevent a new signal running >+ out of room in the sig_state->sig_info[i][] >+ ring buffer. */ >+ sigset_t set; >+ sigemptyset(&set); >+ sigaddset(&set, i); >+ SIG_SEEN(sig_state->sig_blocked[i], >+ sig_count(sig_state->sig_blocked[i])); >+ sigprocmask(SIG_UNBLOCK, &set, NULL); >+ } >+#endif > } > > return 1; >-- >1.5.4.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6651
:
4580
|
4585
|
4586
|
4595
|
4639
|
4640
|
4647