From 51ab7c2f95d6d459302423a57cc617021ef6126d Mon Sep 17 00:00:00 2001 From: José Bollo Date: Wed, 10 Jul 2019 00:06:36 +0200 Subject: Fix bad memory access at client disconnection The management of structures handling a client connection to a exported --ws-server was accessing freed memory. Tha commit fixes that issue. Bug-AGL: SPEC-2651 Change-Id: I511218afc907308347bc422a8aead32ca00bdae6 Signed-off-by: Jose Bollo --- src/afb-api-ws.c | 6 ++++-- src/afb-proto-ws.c | 14 +++++--------- src/afb-ws.c | 3 ++- src/afs-supervisor.c | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c index 3d2445ac..6b242e15 100644 --- a/src/afb-api-ws.c +++ b/src/afb-api-ws.c @@ -130,7 +130,9 @@ static void api_ws_server_accept(struct api_ws_server *apiws) close(fd); } else { server = afb_stub_ws_create_server(fdev, &apiws->uri[apiws->offapi], apiws->apiset); - if (!server) + if (server) + afb_stub_ws_set_on_hangup(server, afb_stub_ws_unref); + else ERROR("can't serve accepted connection to %s: %m", apiws->uri); } } @@ -144,7 +146,7 @@ static void api_ws_server_listen_callback(void *closure, uint32_t revents, struc if ((revents & EPOLLIN) != 0) api_ws_server_accept(apiws); - if ((revents & EPOLLHUP) != 0) + else if ((revents & EPOLLHUP) != 0) api_ws_server_connect(apiws); } diff --git a/src/afb-proto-ws.c b/src/afb-proto-ws.c index fb8628db..3c262059 100644 --- a/src/afb-proto-ws.c +++ b/src/afb-proto-ws.c @@ -132,9 +132,6 @@ struct afb_proto_ws /* count of references */ int refcount; - /* file descriptor */ - struct fdev *fdev; - /* resource control */ pthread_mutex_t mutex; @@ -985,9 +982,9 @@ static void on_hangup(void *closure) free(cd); } - if (protows->fdev) { - fdev_unref(protows->fdev); - protows->fdev = 0; + if (protows->ws) { + afb_ws_destroy(protows->ws); + protows->ws = 0; if (protows->on_hangup) protows->on_hangup(protows->closure); } @@ -1027,7 +1024,6 @@ static struct afb_proto_ws *afb_proto_ws_create(struct fdev *fdev, const struct fcntl(fdev_fd(fdev), F_SETFL, O_NONBLOCK); protows->ws = afb_ws_create(fdev, itf, protows); if (protows->ws != NULL) { - protows->fdev = fdev; protows->refcount = 1; protows->closure = closure; protows->server_itf = itfs; @@ -1054,7 +1050,6 @@ void afb_proto_ws_unref(struct afb_proto_ws *protows) { if (protows && !__atomic_sub_fetch(&protows->refcount, 1, __ATOMIC_RELAXED)) { afb_proto_ws_hangup(protows); - afb_ws_destroy(protows->ws); pthread_mutex_destroy(&protows->mutex); free(protows); } @@ -1077,7 +1072,8 @@ int afb_proto_ws_is_server(struct afb_proto_ws *protows) void afb_proto_ws_hangup(struct afb_proto_ws *protows) { - afb_ws_hangup(protows->ws); + if (protows->ws) + afb_ws_hangup(protows->ws); } void afb_proto_ws_on_hangup(struct afb_proto_ws *protows, void (*on_hangup)(void *closure)) diff --git a/src/afb-ws.c b/src/afb-ws.c index b2776468..fb31e4fe 100644 --- a/src/afb-ws.c +++ b/src/afb-ws.c @@ -120,6 +120,7 @@ static void aws_disconnect(struct afb_ws *ws, int call_on_hangup) struct websock *wsi = ws->ws; if (wsi != NULL) { ws->ws = NULL; + fdev_set_callback(ws->fdev, NULL, 0); fdev_unref(ws->fdev); websock_destroy(wsi); free(ws->buffer.buffer); @@ -133,7 +134,7 @@ static void fdevcb(void *ws, uint32_t revents, struct fdev *fdev) { if ((revents & EPOLLIN) != 0) aws_on_readable(ws); - if ((revents & EPOLLHUP) != 0) + else if ((revents & EPOLLHUP) != 0) afb_ws_hangup(ws); } diff --git a/src/afs-supervisor.c b/src/afs-supervisor.c index d36a3408..31b8b7c3 100644 --- a/src/afs-supervisor.c +++ b/src/afs-supervisor.c @@ -282,7 +282,7 @@ static void listening(void *closure, uint32_t revents, struct fdev *fdev) { if ((revents & EPOLLIN) != 0) accept_supervision_link((int)(intptr_t)closure); - if ((revents & EPOLLHUP) != 0) { + else if ((revents & EPOLLHUP) != 0) { ERROR("supervision socket closed"); exit(1); } -- cgit 1.2.3-korg