summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2019-07-10 00:06:36 +0200
committerJose Bollo <jose.bollo@iot.bzh>2019-07-18 15:42:27 +0200
commitad66a4685f5d50ef05338157c84a572088693ed3 (patch)
treedad3d2aa8d11920735f49d368c9f9f7f3a5972d8
parent037157919df0a7ee90837037748a6456431e6469 (diff)
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 <jose.bollo@iot.bzh>
-rw-r--r--src/afb-api-ws.c6
-rw-r--r--src/afb-proto-ws.c14
-rw-r--r--src/afb-ws.c3
-rw-r--r--src/afs-supervisor.c2
4 files changed, 12 insertions, 13 deletions
diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c
index 65daf025..dc45edbb 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 ea95110a..edf63634 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 ca04c7fe..454ddc1a 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 39f0a568..5bc31ea9 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);
}