mirror of
https://github.com/samba-team/samba.git
synced 2025-01-27 14:04:05 +03:00
s3:messages: make the loop in msg_dgm_ref_recv() more robust against stale pointers
The interaction between msg_dgm_ref_recv() and msg_dgm_ref_destructor() doesn't allow two references from messaging_dgm_ref() to be free'd during the loop in msg_dgm_ref_recv(). In addition to the global 'refs' list, we also need to have a global 'next_ref' pointer, which can be adjusted in msg_dgm_ref_destructor(). As AD DC we hit this when using irpc in auth_winbind, which uses imessaging_client_init(). In addition to the main messaging_dgm_ref() in smbd, source3/auth/auth_samba4.c: prepare_gensec() and make_auth4_context_s4() also generate a temporary imessaging_context for auth_context->msg_ctx from within auth_generic_prepare(). Bug: https://bugzilla.samba.org/show_bug.cgi?id=13514 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
0503bbab95
commit
1a9d6ce589
@ -1 +0,0 @@
|
|||||||
^samba4.local.messaging.multi_ctx
|
|
@ -35,6 +35,7 @@ struct msg_dgm_ref {
|
|||||||
|
|
||||||
static pid_t dgm_pid = 0;
|
static pid_t dgm_pid = 0;
|
||||||
static struct msg_dgm_ref *refs = NULL;
|
static struct msg_dgm_ref *refs = NULL;
|
||||||
|
static struct msg_dgm_ref *next_ref = NULL;
|
||||||
|
|
||||||
static int msg_dgm_ref_destructor(struct msg_dgm_ref *r);
|
static int msg_dgm_ref_destructor(struct msg_dgm_ref *r);
|
||||||
static void msg_dgm_ref_recv(struct tevent_context *ev,
|
static void msg_dgm_ref_recv(struct tevent_context *ev,
|
||||||
@ -121,16 +122,16 @@ static void msg_dgm_ref_recv(struct tevent_context *ev,
|
|||||||
const uint8_t *msg, size_t msg_len,
|
const uint8_t *msg, size_t msg_len,
|
||||||
int *fds, size_t num_fds, void *private_data)
|
int *fds, size_t num_fds, void *private_data)
|
||||||
{
|
{
|
||||||
struct msg_dgm_ref *r, *next;
|
struct msg_dgm_ref *r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to broadcast incoming messages to all refs. The first ref
|
* We have to broadcast incoming messages to all refs. The first ref
|
||||||
* that grabs the fd's will get them.
|
* that grabs the fd's will get them.
|
||||||
*/
|
*/
|
||||||
for (r = refs; r != NULL; r = next) {
|
for (r = refs; r != NULL; r = next_ref) {
|
||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
next = r->next;
|
next_ref = r->next;
|
||||||
|
|
||||||
active = messaging_dgm_fde_active(r->fde);
|
active = messaging_dgm_fde_active(r->fde);
|
||||||
if (!active) {
|
if (!active) {
|
||||||
@ -150,6 +151,11 @@ static int msg_dgm_ref_destructor(struct msg_dgm_ref *r)
|
|||||||
if (refs == NULL) {
|
if (refs == NULL) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r == next_ref) {
|
||||||
|
next_ref = r->next;
|
||||||
|
}
|
||||||
|
|
||||||
DLIST_REMOVE(refs, r);
|
DLIST_REMOVE(refs, r);
|
||||||
|
|
||||||
TALLOC_FREE(r->fde);
|
TALLOC_FREE(r->fde);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user