Skip to content

Commit

Permalink
Fix potential segmentation fault (SIGSEGV) error
Browse files Browse the repository at this point in the history
The server->clients variable may still holds reference to user data which is already freed after websocket connection closed.
  • Loading branch information
tsl0922 committed Mar 10, 2017
1 parent 4d31e53 commit 08ac6dc
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions src/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 *
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}
Expand All @@ -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) {
Expand Down

0 comments on commit 08ac6dc

Please sign in to comment.