diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-06-02 12:18:22 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2015-06-02 21:02:11 +0200 |
commit | 9d797ffb27bf4be100c900b0373f62b029679de3 (patch) | |
tree | d68a0dc25f78dc9a72cecff10c0cae42644106ca /lib/tevent | |
parent | 60d95bbf775635e80a61c6809126c6748b1fe6cb (diff) | |
download | samba-9d797ffb27bf4be100c900b0373f62b029679de3.tar.gz |
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
Diffstat (limited to 'lib/tevent')
-rw-r--r-- | lib/tevent/tevent_signal.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c index b54da2ede82..924dc05c029 100644 --- a/lib/tevent/tevent_signal.c +++ b/lib/tevent/tevent_signal.c @@ -457,7 +457,7 @@ int tevent_common_check_signal(struct tevent_context *ev) } #ifdef SA_SIGINFO - if (clear_processed_siginfo) { + if (clear_processed_siginfo && sig_state->sig_info[i] != NULL) { uint32_t j; for (j=0;j<count;j++) { uint32_t ofs = (counter.seen + j) |