2013-06-21 19:56:08 +04:00
/*
2007-01-21 11:23:14 +03:00
Unix SMB / CIFS implementation .
common events code for signal events
Copyright ( C ) Andrew Tridgell 2007
2009-02-16 10:52:06 +03:00
* * NOTE ! The following LGPL license applies to the tevent
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 3 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
2007-01-21 11:23:14 +03:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2009-02-16 10:52:06 +03:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2007-01-21 11:23:14 +03:00
*/
2008-04-25 01:28:30 +04:00
# include "replace.h"
2007-01-21 11:23:14 +03:00
# include "system/filesys.h"
2009-01-02 14:53:05 +03:00
# include "system/wait.h"
2019-01-08 17:25:22 +03:00
# define TEVENT_DEPRECATED 1
2008-12-16 21:57:09 +03:00
# include "tevent.h"
# include "tevent_internal.h"
# include "tevent_util.h"
2007-01-21 11:23:14 +03:00
2009-09-03 18:38:21 +04:00
/* maximum number of SA_SIGINFO signals to hold in the queue.
NB . This * MUST * be a power of 2 , in order for the ring buffer
wrap to work correctly . Thanks to Petr Vandrovec < petr @ vandrovec . name >
for this . */
2013-12-09 13:29:45 +04:00
# define TEVENT_SA_INFO_QUEUE_COUNT 256
2007-01-21 13:32:39 +03:00
2013-12-09 13:32:00 +04:00
size_t tevent_num_signals ( void )
{
return TEVENT_NUM_SIGNALS ;
}
size_t tevent_sa_info_queue_count ( void )
{
return TEVENT_SA_INFO_QUEUE_COUNT ;
}
2009-12-20 15:59:03 +03:00
struct tevent_sigcounter {
2007-01-22 00:02:24 +03:00
uint32_t count ;
uint32_t seen ;
} ;
2014-06-03 21:44:19 +04:00
# if defined(HAVE___SYNC_FETCH_AND_ADD)
# define TEVENT_SIG_INCREMENT(s) __sync_fetch_and_add(&((s).count), 1)
# elif defined(HAVE_ATOMIC_ADD_32)
# define TEVENT_SIG_INCREMENT(s) atomic_add_32(&((s).count), 1)
# else
2009-12-20 15:59:03 +03:00
# define TEVENT_SIG_INCREMENT(s) (s).count++
2014-06-03 21:44:19 +04:00
# endif
2009-12-20 15:59:03 +03:00
# define TEVENT_SIG_SEEN(s, n) (s).seen += (n)
# define TEVENT_SIG_PENDING(s) ((s).seen != (s).count)
2007-01-22 00:02:24 +03:00
2009-01-05 18:55:00 +03:00
struct tevent_common_signal_list {
struct tevent_common_signal_list * prev , * next ;
struct tevent_signal * se ;
} ;
2007-01-22 00:02:24 +03:00
2007-01-21 11:23:14 +03:00
/*
the poor design of signals means that this table must be static global
*/
2009-12-20 15:59:03 +03:00
static struct tevent_sig_state {
struct tevent_common_signal_list * sig_handlers [ TEVENT_NUM_SIGNALS + 1 ] ;
struct sigaction * oldact [ TEVENT_NUM_SIGNALS + 1 ] ;
struct tevent_sigcounter signal_count [ TEVENT_NUM_SIGNALS + 1 ] ;
struct tevent_sigcounter got_signal ;
2007-01-21 13:32:39 +03:00
# ifdef SA_SIGINFO
/* with SA_SIGINFO we get quite a lot of info per signal */
2009-12-20 15:59:03 +03:00
siginfo_t * sig_info [ TEVENT_NUM_SIGNALS + 1 ] ;
struct tevent_sigcounter sig_blocked [ TEVENT_NUM_SIGNALS + 1 ] ;
2007-01-21 13:32:39 +03:00
# endif
2007-01-23 03:06:33 +03:00
} * sig_state ;
2007-01-21 11:23:14 +03:00
2007-01-22 00:02:24 +03:00
/*
return number of sigcounter events not processed yet
*/
2009-12-20 15:59:03 +03:00
static uint32_t tevent_sig_count ( struct tevent_sigcounter s )
2007-01-22 00:02:24 +03:00
{
2009-08-26 12:00:32 +04:00
return s . count - s . seen ;
2007-01-22 00:02:24 +03:00
}
2007-01-21 11:23:14 +03:00
/*
signal handler - redirects to registered signals
*/
2009-01-14 14:07:45 +03:00
static void tevent_common_signal_handler ( int signum )
2007-01-21 11:23:14 +03:00
{
2009-08-28 06:38:47 +04:00
struct tevent_common_signal_list * sl ;
struct tevent_context * ev = NULL ;
2009-09-21 05:16:18 +04:00
int saved_errno = errno ;
2009-08-28 06:38:47 +04:00
2009-12-20 15:59:03 +03:00
TEVENT_SIG_INCREMENT ( sig_state - > signal_count [ signum ] ) ;
TEVENT_SIG_INCREMENT ( sig_state - > got_signal ) ;
2009-08-28 06:38:47 +04:00
/* Write to each unique event context. */
for ( sl = sig_state - > sig_handlers [ signum ] ; sl ; sl = sl - > next ) {
2009-10-02 03:18:33 +04:00
if ( sl - > se - > event_ctx & & sl - > se - > event_ctx ! = ev ) {
2009-09-22 05:02:10 +04:00
ev = sl - > se - > event_ctx ;
2016-07-29 09:53:59 +03:00
tevent_common_wakeup ( ev ) ;
2009-08-28 06:38:47 +04:00
}
}
2009-09-21 05:16:18 +04:00
errno = saved_errno ;
2007-01-21 11:23:14 +03:00
}
2007-01-21 13:32:39 +03:00
# ifdef SA_SIGINFO
/*
signal handler with SA_SIGINFO - redirects to registered signals
*/
2009-01-14 14:07:45 +03:00
static void tevent_common_signal_handler_info ( int signum , siginfo_t * info ,
void * uctx )
2007-01-21 13:32:39 +03:00
{
2009-12-20 15:59:03 +03:00
uint32_t count = tevent_sig_count ( sig_state - > signal_count [ signum ] ) ;
/* sig_state->signal_count[signum].seen % TEVENT_SA_INFO_QUEUE_COUNT
2009-08-22 02:07:25 +04:00
* is the base of the unprocessed signals in the ringbuffer . */
uint32_t ofs = ( sig_state - > signal_count [ signum ] . seen + count ) %
2009-12-20 15:59:03 +03:00
TEVENT_SA_INFO_QUEUE_COUNT ;
2009-08-22 02:07:25 +04:00
sig_state - > sig_info [ signum ] [ ofs ] = * info ;
2007-01-21 13:32:39 +03:00
2009-01-14 14:07:45 +03:00
tevent_common_signal_handler ( signum ) ;
2007-01-21 13:32:39 +03:00
/* handle SA_SIGINFO */
2009-12-20 15:59:03 +03:00
if ( count + 1 = = TEVENT_SA_INFO_QUEUE_COUNT ) {
2007-01-21 13:32:39 +03:00
/* we've filled the info array - block this signal until
these ones are delivered */
2013-01-15 03:22:11 +04:00
# ifdef HAVE_UCONTEXT_T
/*
* This is the only way for this to work .
* By default signum is blocked inside this
* signal handler using a temporary mask ,
* but what we really need to do now is
* block it in the callers mask , so it
* stays blocked when the temporary signal
* handler mask is replaced when we return
* from here . The callers mask can be found
* in the ucontext_t passed in as the
* void * uctx argument .
*/
ucontext_t * ucp = ( ucontext_t * ) uctx ;
sigaddset ( & ucp - > uc_sigmask , signum ) ;
# else
/*
* WARNING ! ! ! WARNING ! ! ! !
*
* This code doesn ' t work .
* By default signum is blocked inside this
* signal handler , but calling sigprocmask
* modifies the temporary signal mask being
* used * inside * this handler , which will be
* replaced by the callers signal mask once
* we return from here . See Samba
* bug # 9550 for details .
*/
2007-01-21 13:32:39 +03:00
sigset_t set ;
sigemptyset ( & set ) ;
sigaddset ( & set , signum ) ;
sigprocmask ( SIG_BLOCK , & set , NULL ) ;
2013-01-15 03:22:11 +04:00
# endif
2009-12-20 15:59:03 +03:00
TEVENT_SIG_INCREMENT ( sig_state - > sig_blocked [ signum ] ) ;
2007-01-21 13:32:39 +03:00
}
}
# endif
2007-01-21 11:23:14 +03:00
2009-01-05 18:55:00 +03:00
static int tevent_common_signal_list_destructor ( struct tevent_common_signal_list * sl )
{
2010-02-09 12:02:20 +03:00
if ( sig_state - > sig_handlers [ sl - > se - > signum ] ) {
DLIST_REMOVE ( sig_state - > sig_handlers [ sl - > se - > signum ] , sl ) ;
}
2009-01-05 18:55:00 +03:00
return 0 ;
}
2007-01-21 11:23:14 +03:00
/*
destroy a signal event
*/
2009-01-02 15:26:32 +03:00
static int tevent_signal_destructor ( struct tevent_signal * se )
2007-01-21 11:23:14 +03:00
{
2014-07-22 15:01:01 +04:00
if ( se - > destroyed ) {
tevent_common_check_double_free ( se , " tevent_signal double free " ) ;
goto done ;
}
se - > destroyed = true ;
2018-04-17 17:43:54 +03:00
TALLOC_FREE ( se - > additional_data ) ;
2009-01-05 18:55:00 +03:00
2018-04-17 17:43:54 +03:00
if ( se - > event_ctx ! = NULL ) {
2021-06-01 15:10:05 +03:00
tevent_trace_signal_callback ( se - > event_ctx , se , TEVENT_EVENT_TRACE_DETACH ) ;
2018-04-17 17:43:54 +03:00
DLIST_REMOVE ( se - > event_ctx - > signal_events , se ) ;
2009-01-05 18:55:00 +03:00
}
2007-01-23 03:06:33 +03:00
if ( sig_state - > sig_handlers [ se - > signum ] = = NULL ) {
2007-01-21 13:32:39 +03:00
/* restore old handler, if any */
2010-02-09 12:02:20 +03:00
if ( sig_state - > oldact [ se - > signum ] ) {
sigaction ( se - > signum , sig_state - > oldact [ se - > signum ] , NULL ) ;
2018-04-17 17:43:54 +03:00
TALLOC_FREE ( sig_state - > oldact [ se - > signum ] ) ;
2010-02-09 12:02:20 +03:00
}
2007-01-22 01:12:19 +03:00
# ifdef SA_SIGINFO
if ( se - > sa_flags & SA_SIGINFO ) {
2010-02-09 12:02:20 +03:00
if ( sig_state - > sig_info [ se - > signum ] ) {
2018-04-17 17:43:54 +03:00
TALLOC_FREE ( sig_state - > sig_info [ se - > signum ] ) ;
2010-02-09 12:02:20 +03:00
}
2007-01-22 01:12:19 +03:00
}
# endif
2007-01-21 11:23:14 +03:00
}
2009-01-05 18:55:00 +03:00
2014-07-22 15:01:01 +04:00
se - > event_ctx = NULL ;
done :
if ( se - > busy ) {
return - 1 ;
}
2014-07-22 18:51:38 +04:00
se - > wrapper = NULL ;
2014-07-22 15:01:01 +04:00
2007-01-21 11:23:14 +03:00
return 0 ;
}
/*
add a signal event
return NULL on failure ( memory allocation error )
*/
2009-01-02 15:26:32 +03:00
struct tevent_signal * tevent_common_add_signal ( struct tevent_context * ev ,
TALLOC_CTX * mem_ctx ,
int signum ,
int sa_flags ,
tevent_signal_handler_t handler ,
void * private_data ,
const char * handler_name ,
const char * location )
2007-01-21 11:23:14 +03:00
{
2009-01-02 15:26:32 +03:00
struct tevent_signal * se ;
2009-01-05 18:55:00 +03:00
struct tevent_common_signal_list * sl ;
2009-08-28 06:38:47 +04:00
sigset_t set , oldset ;
2016-07-29 09:53:59 +03:00
int ret ;
ret = tevent_common_wakeup_init ( ev ) ;
if ( ret ! = 0 ) {
errno = ret ;
return NULL ;
}
2007-01-21 11:23:14 +03:00
2009-12-20 15:59:03 +03:00
if ( signum > = TEVENT_NUM_SIGNALS ) {
2009-01-05 18:55:00 +03:00
errno = EINVAL ;
2007-01-21 11:23:14 +03:00
return NULL ;
}
2007-01-23 03:06:33 +03:00
/* the sig_state needs to be on a global context as it can last across
multiple event contexts */
if ( sig_state = = NULL ) {
2010-09-24 21:13:05 +04:00
sig_state = talloc_zero ( NULL , struct tevent_sig_state ) ;
2007-01-23 03:06:33 +03:00
if ( sig_state = = NULL ) {
return NULL ;
}
}
2018-03-27 15:30:20 +03:00
se = talloc_zero ( mem_ctx ? mem_ctx : ev , struct tevent_signal ) ;
2007-01-21 11:23:14 +03:00
if ( se = = NULL ) return NULL ;
2018-03-27 15:30:20 +03:00
sl = talloc_zero ( se , struct tevent_common_signal_list ) ;
2009-01-05 18:55:00 +03:00
if ( ! sl ) {
talloc_free ( se ) ;
return NULL ;
}
sl - > se = se ;
2014-10-23 09:15:14 +04:00
* se = ( struct tevent_signal ) {
. event_ctx = ev ,
. signum = signum ,
. sa_flags = sa_flags ,
. handler = handler ,
. private_data = private_data ,
. handler_name = handler_name ,
. location = location ,
. additional_data = sl ,
} ;
2009-01-05 18:55:00 +03:00
2007-01-24 01:28:21 +03:00
/* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */
if ( ! talloc_reference ( se , sig_state ) ) {
2009-01-05 18:55:00 +03:00
talloc_free ( se ) ;
2007-01-24 01:28:21 +03:00
return NULL ;
}
2007-01-21 11:23:14 +03:00
2007-01-21 13:32:39 +03:00
/* only install a signal handler if not already installed */
2007-01-23 03:06:33 +03:00
if ( sig_state - > sig_handlers [ signum ] = = NULL ) {
2007-01-21 13:32:39 +03:00
struct sigaction act ;
ZERO_STRUCT ( act ) ;
2009-01-14 14:07:45 +03:00
act . sa_handler = tevent_common_signal_handler ;
2007-01-21 13:32:39 +03:00
act . sa_flags = sa_flags ;
# ifdef SA_SIGINFO
if ( sa_flags & SA_SIGINFO ) {
act . sa_handler = NULL ;
2009-01-14 14:07:45 +03:00
act . sa_sigaction = tevent_common_signal_handler_info ;
2007-01-23 03:06:33 +03:00
if ( sig_state - > sig_info [ signum ] = = NULL ) {
2009-12-20 15:59:03 +03:00
sig_state - > sig_info [ signum ] =
talloc_zero_array ( sig_state , siginfo_t ,
TEVENT_SA_INFO_QUEUE_COUNT ) ;
2007-01-23 03:06:33 +03:00
if ( sig_state - > sig_info [ signum ] = = NULL ) {
2007-01-22 01:12:19 +03:00
talloc_free ( se ) ;
return NULL ;
}
}
2007-01-21 13:32:39 +03:00
}
# endif
2018-03-27 15:30:20 +03:00
sig_state - > oldact [ signum ] = talloc_zero ( sig_state , struct sigaction ) ;
2007-01-23 03:06:33 +03:00
if ( sig_state - > oldact [ signum ] = = NULL ) {
2007-01-22 01:12:19 +03:00
talloc_free ( se ) ;
2013-06-21 19:56:08 +04:00
return NULL ;
2007-01-22 01:12:19 +03:00
}
2007-01-23 03:06:33 +03:00
if ( sigaction ( signum , & act , sig_state - > oldact [ signum ] ) = = - 1 ) {
2016-02-17 01:23:53 +03:00
talloc_free ( sig_state - > oldact [ signum ] ) ;
sig_state - > oldact [ signum ] = NULL ;
2007-01-21 13:32:39 +03:00
talloc_free ( se ) ;
return NULL ;
}
2007-01-21 11:23:14 +03:00
}
2009-01-05 18:55:00 +03:00
DLIST_ADD ( se - > event_ctx - > signal_events , se ) ;
2009-08-28 06:38:47 +04:00
/* Make sure the signal doesn't come in while we're mangling list. */
sigemptyset ( & set ) ;
sigaddset ( & set , signum ) ;
sigprocmask ( SIG_BLOCK , & set , & oldset ) ;
2021-06-01 15:10:05 +03:00
tevent_trace_signal_callback ( se - > event_ctx , se , TEVENT_EVENT_TRACE_ATTACH ) ;
2009-01-05 18:55:00 +03:00
DLIST_ADD ( sig_state - > sig_handlers [ signum ] , sl ) ;
2009-08-28 06:38:47 +04:00
sigprocmask ( SIG_SETMASK , & oldset , NULL ) ;
2007-01-21 11:23:14 +03:00
2009-01-02 15:26:32 +03:00
talloc_set_destructor ( se , tevent_signal_destructor ) ;
2009-01-05 18:55:00 +03:00
talloc_set_destructor ( sl , tevent_common_signal_list_destructor ) ;
2007-01-21 11:23:14 +03:00
return se ;
}
2014-07-22 15:01:01 +04:00
int tevent_common_invoke_signal_handler ( struct tevent_signal * se ,
int signum , int count , void * siginfo ,
bool * removed )
2012-01-29 01:18:00 +04:00
{
2014-07-22 18:51:38 +04:00
struct tevent_context * handler_ev = se - > event_ctx ;
2014-07-22 15:01:01 +04:00
bool remove = false ;
if ( removed ! = NULL ) {
* removed = false ;
}
if ( se - > event_ctx = = NULL ) {
return 0 ;
}
se - > busy = true ;
2014-07-22 18:51:38 +04:00
if ( se - > wrapper ! = NULL ) {
handler_ev = se - > wrapper - > wrap_ev ;
tevent_wrapper_push_use_internal ( handler_ev , se - > wrapper ) ;
se - > wrapper - > ops - > before_signal_handler (
se - > wrapper - > wrap_ev ,
se - > wrapper - > private_state ,
se - > wrapper - > main_ev ,
se ,
signum ,
count ,
siginfo ,
se - > handler_name ,
se - > location ) ;
}
2021-06-01 15:10:05 +03:00
tevent_trace_signal_callback ( se - > event_ctx , se , TEVENT_EVENT_TRACE_BEFORE_HANDLER ) ;
2014-07-22 18:51:38 +04:00
se - > handler ( handler_ev , se , signum , count , siginfo , se - > private_data ) ;
if ( se - > wrapper ! = NULL ) {
se - > wrapper - > ops - > after_signal_handler (
se - > wrapper - > wrap_ev ,
se - > wrapper - > private_state ,
se - > wrapper - > main_ev ,
se ,
signum ,
count ,
siginfo ,
se - > handler_name ,
se - > location ) ;
tevent_wrapper_pop_use_internal ( handler_ev , se - > wrapper ) ;
}
2014-07-22 15:01:01 +04:00
se - > busy = false ;
# ifdef SA_RESETHAND
if ( se - > sa_flags & SA_RESETHAND ) {
remove = true ;
}
# endif
if ( se - > destroyed ) {
talloc_set_destructor ( se , NULL ) ;
remove = true ;
}
if ( remove ) {
TALLOC_FREE ( se ) ;
if ( removed ! = NULL ) {
* removed = true ;
}
}
2012-01-29 01:18:00 +04:00
return 0 ;
}
2007-01-21 11:23:14 +03:00
/*
check if a signal is pending
return ! = 0 if a signal was pending
*/
2009-01-02 15:26:32 +03:00
int tevent_common_check_signal ( struct tevent_context * ev )
2007-01-21 11:23:14 +03:00
{
int i ;
2007-01-23 03:06:33 +03:00
2009-12-20 15:59:03 +03:00
if ( ! sig_state | | ! TEVENT_SIG_PENDING ( sig_state - > got_signal ) ) {
2007-01-21 11:23:14 +03:00
return 0 ;
}
2013-06-21 19:56:08 +04:00
2009-12-20 15:59:03 +03:00
for ( i = 0 ; i < TEVENT_NUM_SIGNALS + 1 ; i + + ) {
2009-01-05 18:55:00 +03:00
struct tevent_common_signal_list * sl , * next ;
2009-12-20 15:59:03 +03:00
struct tevent_sigcounter counter = sig_state - > signal_count [ i ] ;
uint32_t count = tevent_sig_count ( counter ) ;
2014-07-22 15:01:01 +04:00
int ret ;
2009-08-22 02:07:25 +04:00
# ifdef SA_SIGINFO
/* Ensure we null out any stored siginfo_t entries
* after processing for debugging purposes . */
bool clear_processed_siginfo = false ;
# endif
2007-01-21 20:58:56 +03:00
if ( count = = 0 ) {
continue ;
}
2009-01-05 18:55:00 +03:00
for ( sl = sig_state - > sig_handlers [ i ] ; sl ; sl = next ) {
struct tevent_signal * se = sl - > se ;
2012-01-29 01:18:00 +04:00
2012-02-15 19:17:34 +04:00
next = sl - > next ;
2007-01-21 13:32:39 +03:00
# ifdef SA_SIGINFO
2007-01-21 20:58:56 +03:00
if ( se - > sa_flags & SA_SIGINFO ) {
2009-08-22 02:07:25 +04:00
uint32_t j ;
clear_processed_siginfo = true ;
2007-01-21 20:58:56 +03:00
for ( j = 0 ; j < count ; j + + ) {
2009-08-22 02:07:25 +04:00
/* sig_state->signal_count[i].seen
2009-12-20 15:59:03 +03:00
* % TEVENT_SA_INFO_QUEUE_COUNT is
2009-08-22 02:07:25 +04:00
* the base position of the unprocessed
* signals in the ringbuffer . */
uint32_t ofs = ( counter . seen + j )
2009-12-20 15:59:03 +03:00
% TEVENT_SA_INFO_QUEUE_COUNT ;
2014-07-22 15:01:01 +04:00
bool removed = false ;
ret = tevent_common_invoke_signal_handler (
se , i , 1 ,
( void * ) & sig_state - > sig_info [ i ] [ ofs ] ,
& removed ) ;
if ( ret ! = 0 ) {
tevent_abort ( ev , " tevent_common_invoke_signal_handler() failed " ) ;
}
if ( removed ) {
2012-01-29 01:18:00 +04:00
break ;
}
2007-01-21 13:32:39 +03:00
}
2007-01-21 20:58:56 +03:00
continue ;
}
# endif
2014-07-22 15:01:01 +04:00
ret = tevent_common_invoke_signal_handler ( se , i , count ,
NULL , NULL ) ;
if ( ret ! = 0 ) {
tevent_abort ( ev , " tevent_common_invoke_signal_handler() failed " ) ;
2007-01-21 11:23:14 +03:00
}
}
2009-08-22 02:07:25 +04:00
# ifdef SA_SIGINFO
tevent: fix access after free in tevent_common_check_signal()
This was reported by Pavel Březina <pbrezina@redhat.com>:
We found a crash in SSSD when a tevent signal is freed in its handler, tevent
than crashes when it access siginfo.
sig_info is freed in signal destructor:
> #ifdef SA_SIGINFO
> if (se->sa_flags & SA_SIGINFO) {
> if (sig_state->sig_info[se->signum]) {
> talloc_free(sig_state->sig_info[se->signum]);
> sig_state->sig_info[se->signum] = NULL;
> }
> }
> #endif
(gdb) bt
#0 0x00007f5d4d86cc74 in tevent_signal_destructor (se=0x7f5d5370f920) at
../tevent_signal.c:213
#1 0x00007f5d4d65f233 in _talloc_free_internal () from /lib64/libtalloc.so.2
#2 0x00007f5d4d6593a3 in _talloc_free () from /lib64/libtalloc.so.2
#3 0x00007f5d4342f3d4 in proxy_child_init_done (subreq=0x7f5d5370f600) at
src/providers/proxy/proxy_auth.c:436
#4 0x00007f5d4d86b0c2 in _tevent_req_error (req=req@entry=0x7f5d5370f600,
error=error@entry=5, location=location@entry=0x7f5d43433010
"src/providers/proxy/proxy_auth.c:356")
at ../tevent_req.c:167
#5 0x00007f5d4342ef5e in pc_init_sig_handler (ev=<optimized out>,
sige=<optimized out>, signum=<optimized out>, count=<optimized out>,
__siginfo=<optimized out>, pvt=<optimized out>)
at src/providers/proxy/proxy_auth.c:356
#6 0x00007f5d4d86d48c in tevent_common_check_signal (ev=0x7f5d536de670) at
../tevent_signal.c:428
#7 0x00007f5d4d86f28c in epoll_event_loop (tvalp=0x7fff7b568490,
epoll_ev=0x7f5d536de8b0) at ../tevent_epoll.c:647
#8 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at
../tevent_epoll.c:926
#9 0x00007f5d4d86d7d7 in std_event_loop_once (ev=0x7f5d536de670,
location=0x7f5d50faedc3 "src/util/server.c:668") at ../tevent_standard.c:114
#10 0x00007f5d4d869fbd in _tevent_loop_once (ev=ev@entry=0x7f5d536de670,
location=location@entry=0x7f5d50faedc3 "src/util/server.c:668") at
../tevent.c:530
#11 0x00007f5d4d86a15b in tevent_common_loop_wait (ev=0x7f5d536de670,
location=0x7f5d50faedc3 "src/util/server.c:668") at ../tevent.c:634
#12 0x00007f5d4d86d777 in std_event_loop_wait (ev=0x7f5d536de670,
location=0x7f5d50faedc3 "src/util/server.c:668") at ../tevent_standard.c:140
#13 0x00007f5d50f96863 in server_loop (main_ctx=0x7f5d536dfac0) at
src/util/server.c:668
#14 0x00007f5d5180aa42 in main (argc=8, argv=<optimized out>) at
src/providers/data_provider_be.c:2909
But then it is accessed again in tevent_common_check_signal:
> #ifdef SA_SIGINFO
> if (clear_processed_siginfo) {
> uint32_t j;
> for (j=0;j<count;j++) {
> uint32_t ofs = (counter.seen + j)
> % TEVENT_SA_INFO_QUEUE_COUNT;
> memset((void*)&sig_state->sig_info[i][ofs],
> '\0',
> sizeof(siginfo_t));
> }
> }
> #endif
(gdb) bt
#0 0x00007fd7ba400505 in memset (__len=<optimized out>, __ch=<optimized out>,
__dest=<optimized out>) at /usr/include/bits/string3.h:84
#1 tevent_common_check_signal (ev=0x7fd7bfddf670) at ../tevent_signal.c:459
#2 0x00007fd7ba40228c in epoll_event_loop (tvalp=0x7fff85536430,
epoll_ev=0x7fd7bfddf8b0) at ../tevent_epoll.c:647
#3 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at
../tevent_epoll.c:926
#4 0x00007fd7ba4007d7 in std_event_loop_once (ev=0x7fd7bfddf670,
location=0x7fd7bdb417c3 "src/util/server.c:668") at ../tevent_standard.c:114
#5 0x00007fd7ba3fcfbd in _tevent_loop_once (ev=ev@entry=0x7fd7bfddf670,
location=location@entry=0x7fd7bdb417c3 "src/util/server.c:668") at
../tevent.c:530
#6 0x00007fd7ba3fd15b in tevent_common_loop_wait (ev=0x7fd7bfddf670,
location=0x7fd7bdb417c3 "src/util/server.c:668") at ../tevent.c:634
#7 0x00007fd7ba400777 in std_event_loop_wait (ev=0x7fd7bfddf670,
location=0x7fd7bdb417c3 "src/util/server.c:668") at ../tevent_standard.c:140
#8 0x00007fd7bdb29343 in server_loop (main_ctx=0x7fd7bfde0ac0) at
src/util/server.c:668
#9 0x00007fd7be39ca42 in main (argc=8, argv=<optimized out>) at
src/providers/data_provider_be.c:2909
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11308
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Jun 2 21:02:11 CEST 2015 on sn-devel-104
2015-06-02 13:18:22 +03:00
if ( clear_processed_siginfo & & sig_state - > sig_info [ i ] ! = NULL ) {
2009-08-22 02:07:25 +04:00
uint32_t j ;
for ( j = 0 ; j < count ; j + + ) {
uint32_t ofs = ( counter . seen + j )
2009-12-20 15:59:03 +03:00
% TEVENT_SA_INFO_QUEUE_COUNT ;
2009-08-22 02:07:25 +04:00
memset ( ( void * ) & sig_state - > sig_info [ i ] [ ofs ] ,
' \0 ' ,
sizeof ( siginfo_t ) ) ;
}
}
# endif
2009-12-20 15:59:03 +03:00
TEVENT_SIG_SEEN ( sig_state - > signal_count [ i ] , count ) ;
TEVENT_SIG_SEEN ( sig_state - > got_signal , count ) ;
2009-08-22 02:07:25 +04:00
# ifdef SA_SIGINFO
2009-12-20 15:59:03 +03:00
if ( TEVENT_SIG_PENDING ( sig_state - > sig_blocked [ i ] ) ) {
2009-08-22 02:07:25 +04:00
/* We'd filled the queue, unblock the
signal now the queue is empty again .
Note we MUST do this after the
2009-12-20 15:59:03 +03:00
TEVENT_SIG_SEEN ( sig_state - > signal_count [ i ] , count )
2009-08-22 02:07:25 +04:00
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 ) ;
2009-12-20 15:59:03 +03:00
TEVENT_SIG_SEEN ( sig_state - > sig_blocked [ i ] ,
tevent_sig_count ( sig_state - > sig_blocked [ i ] ) ) ;
2009-08-22 02:07:25 +04:00
sigprocmask ( SIG_UNBLOCK , & set , NULL ) ;
}
# endif
2007-01-21 11:23:14 +03:00
}
return 1 ;
}
2010-02-09 12:02:20 +03:00
void tevent_cleanup_pending_signal_handlers ( struct tevent_signal * se )
{
2014-07-22 14:02:45 +04:00
tevent_signal_destructor ( se ) ;
talloc_set_destructor ( se , NULL ) ;
2010-02-09 12:02:20 +03:00
return ;
}
2021-06-01 14:57:45 +03:00
void tevent_signal_set_tag ( struct tevent_signal * se , uint64_t tag )
{
if ( se = = NULL ) {
return ;
}
se - > tag = tag ;
}
uint64_t tevent_signal_get_tag ( const struct tevent_signal * se )
{
if ( se = = NULL ) {
return 0 ;
}
return se - > tag ;
}