Fix potential segmentation fault (SIGSEGV) error

The server->clients variable may still holds reference to user data which is already freed after websocket connection closed.
This commit is contained in:
Shuanglei Tao
2017-03-11 02:24:38 +08:00
parent 4d31e534c0
commit 08ac6dc43c

View File

@@ -77,6 +77,14 @@ check_host_origin(struct lws *wsi) {
return false;
}
void
tty_client_remove(struct tty_client *client) {
pthread_mutex_lock(&server->lock);
LIST_REMOVE(client, list);
server->client_count--;
pthread_mutex_unlock(&server->lock);
}
void
tty_client_destroy(struct tty_client *client) {
if (!client->running || client->pid <= 0)
@@ -99,10 +107,7 @@ tty_client_destroy(struct tty_client *client) {
free(client->buffer);
// remove from client list
pthread_mutex_lock(&server->lock);
LIST_REMOVE(client, list);
server->client_count--;
pthread_mutex_unlock(&server->lock);
tty_client_remove(client);
}
void *
@@ -210,8 +215,10 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
case LWS_CALLBACK_SERVER_WRITEABLE:
if (!client->initialized) {
if (send_initial_message(wsi) < 0)
if (send_initial_message(wsi) < 0) {
tty_client_remove(client);
return -1;
}
client->initialized = true;
break;
}
@@ -223,6 +230,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
if (frame->len <= 0) {
STAILQ_REMOVE_HEAD(&client->queue, list);
free(frame);
tty_client_remove(client);
return -1;
}
@@ -284,6 +292,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
return 0;
if (write(client->pty, client->buffer + 1, client->len - 1) < client->len - 1) {
lwsl_err("write INPUT to pty\n");
tty_client_remove(client);
return -1;
}
break;
@@ -292,6 +301,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
unsigned char c = PONG;
if (lws_write(wsi, &c, 1, LWS_WRITE_TEXT) != 1) {
lwsl_err("send PONG\n");
tty_client_remove(client);
return -1;
}
}
@@ -316,8 +326,10 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
else
lwsl_warn("WS authentication failed with token: %s\n", token);
}
if (!client->authenticated)
return 1;
if (!client->authenticated) {
tty_client_remove(client);
return -1;
}
}
int err = pthread_create(&client->thread, NULL, thread_run_command, client);
if (err != 0) {