Hi, if an nss provider dies during a request the nss responders dies due to a double free error minutes after the request was sent. The responder does not handle the unfinished request and so they stay around and the client has to wait for a response until SSS_CLI_SOCKET_TIMEOUT (5 minutes) is over. During the termination of the request the sss_dp_callback structure is free two times which lead to an abort in the nss responder.
The first patch add a handler which removes all open requests after a reconnect. The second one is only marginally related to the described issue but makes sure that cmdctx, the parent or grand-parent memory context of the sss_dp_callback structure, is always allocate with talloc_zero. The third patch removes the explicit talloc_free of the sss_dp_callback structures, because they are already freed because cmdctx was freed during the callback. bye, Sumit
From d819922fa1906e5c8c3f65fa171fab11fffb8798 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 22 Oct 2010 12:01:23 +0200 Subject: [PATCH 1/3] Remove all nss requests after a reconnect Currently we do not handle the open nss request after a reconnect and wait until they timeout (which is a couple of minutes!). This patch adds a handler that terminates all requests after a reconnect. Then responder will return matching cache entries or nothing. --- src/responder/common/responder.h | 2 ++ src/responder/common/responder_dp.c | 19 +++++++++++++++++++ src/responder/nss/nsssrv.c | 6 +++++- 3 files changed, 26 insertions(+), 1 deletions(-) diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 980e561..783f9e4 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -161,6 +161,8 @@ struct cli_protocol_version *register_cli_protocol_version(void); typedef void (*sss_dp_callback_t)(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); +void handle_requests_after_reconnect(void); + int sss_dp_send_acct_req(struct resp_ctx *rctx, TALLOC_CTX *callback_memctx, sss_dp_callback_t callback, void *callback_ctx, int timeout, const char *domain, diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c index fd7b976..f8c3b6f 100644 --- a/src/responder/common/responder_dp.c +++ b/src/responder/common/responder_dp.c @@ -107,6 +107,25 @@ static int sss_dp_req_destructor(void *ptr) return 0; } +static bool reconnect_handler(hash_entry_t *item, void *user_data) +{ + struct sss_dp_req *sdp_req = talloc_get_type(item->value.ptr, + struct sss_dp_req); + + return (talloc_free(sdp_req) == EOK ? true : false); +} + +void handle_requests_after_reconnect(void) +{ + int ret; + + ret = hash_iterate(dp_requests, reconnect_handler, NULL); + if (ret != HASH_SUCCESS) { + DEBUG(1, ("hash_iterate failed, " + "not all request might be handled after reconnect.\n")); + } +} + static void sdp_req_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c index 4f5aa62..dfb0312 100644 --- a/src/responder/nss/nsssrv.c +++ b/src/responder/nss/nsssrv.c @@ -39,6 +39,7 @@ #include "dbus/dbus.h" #include "sbus/sssd_dbus.h" #include "responder/common/responder_packet.h" +#include "responder/common/responder.h" #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" #include "sbus/sbus_client.h" @@ -143,7 +144,10 @@ static void nss_dp_reconnect_init(struct sbus_connection *conn, DATA_PROVIDER_VERSION, "NSS"); /* all fine */ - if (ret == EOK) return; + if (ret == EOK) { + handle_requests_after_reconnect(); + return; + } } /* Failed to reconnect */ -- 1.7.2.3
From 1878d676bfd219cab8b75f5742946aca4f3b214c Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 22 Oct 2010 13:01:31 +0200 Subject: [PATCH 2/3] Always use talloc_zero() to allocate cmdctx --- src/responder/nss/nsssrv_cmd.c | 4 ++-- src/responder/nss/nsssrv_netgroup.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index e6437a6..65d9c58 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -1301,7 +1301,7 @@ static int nss_cmd_getpwent(struct cli_ctx *cctx) DEBUG(4, ("Requesting info for all accounts\n")); - cmdctx = talloc(cctx, struct nss_cmd_ctx); + cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } @@ -2630,7 +2630,7 @@ static int nss_cmd_getgrent(struct cli_ctx *cctx) DEBUG(4, ("Requesting info for all groups\n")); - cmdctx = talloc(cctx, struct nss_cmd_ctx); + cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c index feda556..1ac2608 100644 --- a/src/responder/nss/nsssrv_netgroup.c +++ b/src/responder/nss/nsssrv_netgroup.c @@ -595,7 +595,7 @@ int nss_cmd_getnetgrent(struct cli_ctx *client) DEBUG(4, ("Requesting netgroup data\n")); - cmdctx = talloc(client, struct nss_cmd_ctx); + cmdctx = talloc_zero(client, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } -- 1.7.2.3
From bb123f42bb81c17f9c20926ad7b38bceb63cb316 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Mon, 25 Oct 2010 11:14:04 +0200 Subject: [PATCH 3/3] Fix double free issue --- src/responder/common/responder_dp.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c index f8c3b6f..b2b5d40 100644 --- a/src/responder/common/responder_dp.c +++ b/src/responder/common/responder_dp.c @@ -95,12 +95,12 @@ static int sss_dp_req_destructor(void *ptr) cb = sdp_req->cb_list; while (cb) { + next = cb->next; + /* It is the responsibility of the callback to free cb */ cb->callback(sdp_req->err_maj, sdp_req->err_min, sdp_req->err_msg, cb->callback_ctx); - next = cb->next; - talloc_free(cb); cb = next; } -- 1.7.2.3
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel