1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-09 15:41:10 +03:00

socket: do not free poll object if it is locked

As it may a cause a use after free if `send` fails when
ssh_poll_ctx_dopoll does its callback
ssh_poll_ctx_dopoll still wants to use the poll object later

Signed-off-by: Philippe Antoine <p.antoine@catenacyber.fr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Philippe Antoine
2025-07-23 14:37:45 +02:00
committed by Jakub Jelen
parent 53ac23ded4
commit c99261437f
3 changed files with 16 additions and 1 deletions

View File

@@ -157,6 +157,7 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx);
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p);
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s);
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p);
bool ssh_poll_is_locked(ssh_poll_handle p);
int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout);
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session);
int ssh_event_add_poll(ssh_event event, ssh_poll_handle p);

View File

@@ -682,6 +682,20 @@ void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p)
}
}
/**
* @brief Returns if a poll object is locked.
*
* @param p Pointer to an already allocated poll object.
* @returns true if the poll object is locked; false otherwise.
*/
bool ssh_poll_is_locked(ssh_poll_handle p)
{
if (p == NULL) {
return false;
}
return p->lock_cnt > 0;
}
/**
* @brief Poll all the sockets associated through a poll object with a
* poll context. If any of the events are set after the poll, the

View File

@@ -481,7 +481,7 @@ void ssh_socket_close(ssh_socket s)
#endif
}
if (s->poll_handle != NULL) {
if (s->poll_handle != NULL && !ssh_poll_is_locked(s->poll_handle)) {
ssh_poll_free(s->poll_handle);
s->poll_handle = NULL;
}