Compare commits

...

7 Commits

Author SHA1 Message Date
Jakub Jelen
118a747acd socket: Free poll handle when resetting socket state
Since 07cb0be12 we are not closing the user provided FDs,
but the above change also resulted in memory leak during
ssh_disconnect that left the poll_handle allocated during
reset.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:13:31 +02:00
Jakub Jelen
5691e0f609 poll: Initialize ssh_poll_handle pointers
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:13:31 +02:00
Jakub Jelen
5a6e2fd02a poll: Fix memory leak on failed realloc()
In cases where this is the initial allocation, the shrinking of the polltrs
buffer would result in 0B realloc, which really does not make sense. Also,
when this second realloc fails, the memory is never freed as the outer code
believes there is nothing allocated on the poll_ctx

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:13:31 +02:00
Jakub Jelen
e8099375fe poll: Check return value of ssh_poll_ctx_add()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:13:27 +02:00
Jakub Jelen
d00f267bc6 Make ssh_socket_set_fd() return errors
and properly check the return value where it is used

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:12:47 +02:00
Jakub Jelen
35d337834b options: Avoid memory leaks on allocation failures
When allocation during tilde expansion fails, libssh could
leak a memory.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:12:47 +02:00
Jakub Jelen
ba1e8303f8 reformat remains of poll.c
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-08-12 12:12:43 +02:00
8 changed files with 177 additions and 132 deletions

View File

@@ -33,7 +33,7 @@ void ssh_socket_cleanup(void);
ssh_socket ssh_socket_new(ssh_session session);
void ssh_socket_reset(ssh_socket s);
void ssh_socket_free(ssh_socket s);
void ssh_socket_set_fd(ssh_socket s, socket_t fd);
int ssh_socket_set_fd(ssh_socket s, socket_t fd);
socket_t ssh_socket_get_fd(ssh_socket s);
void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p);
int ssh_socket_unix(ssh_socket s, const char *path);

View File

@@ -210,8 +210,7 @@ int ssh_set_agent_socket(ssh_session session, socket_t fd)
return SSH_ERROR;
}
ssh_socket_set_fd(session->agent->sock, fd);
return SSH_OK;
return ssh_socket_set_fd(session->agent->sock, fd);
}
/**

View File

@@ -505,7 +505,10 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
ssh_set_error_oom(sshbind);
return SSH_ERROR;
}
ssh_socket_set_fd(session->socket, fd);
rc = ssh_socket_set_fd(session->socket, fd);
if (rc != SSH_OK) {
return rc;
}
handle = ssh_socket_get_poll_handle(session->socket);
if (handle == NULL) {
ssh_set_error_oom(sshbind);

View File

@@ -602,8 +602,7 @@ int ssh_connect(ssh_session session)
if (session->opts.fd != SSH_INVALID_SOCKET) {
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
ssh_socket_set_fd(session->socket, session->opts.fd);
ret = SSH_OK;
ret = ssh_socket_set_fd(session->socket, session->opts.fd);
#ifndef _WIN32
#ifdef HAVE_PTHREAD
} else if (ssh_libssh_proxy_jumps() &&

View File

@@ -1985,10 +1985,10 @@ int ssh_options_apply(ssh_session session)
* it with ssh expansion of ssh escape characters.
*/
tmp = ssh_path_expand_escape(session, id);
free(id);
if (tmp == NULL) {
return -1;
}
free(id);
}
/* use append to keep the order at first call and use prepend
@@ -1999,6 +1999,7 @@ int ssh_options_apply(ssh_session session)
rc = ssh_list_append(session->opts.identity, tmp);
}
if (rc != SSH_OK) {
free(tmp);
return -1;
}
}
@@ -2010,13 +2011,14 @@ int ssh_options_apply(ssh_session session)
char *id = tmp;
tmp = ssh_path_expand_escape(session, id);
free(id);
if (tmp == NULL) {
return -1;
}
free(id);
rc = ssh_list_append(session->opts.certificate, tmp);
if (rc != SSH_OK) {
free(tmp);
return -1;
}
}

View File

@@ -61,24 +61,24 @@
*/
struct ssh_poll_handle_struct {
ssh_poll_ctx ctx;
ssh_session session;
union {
socket_t fd;
size_t idx;
} x;
short events;
uint32_t lock_cnt;
ssh_poll_callback cb;
void *cb_data;
ssh_poll_ctx ctx;
ssh_session session;
union {
socket_t fd;
size_t idx;
} x;
short events;
uint32_t lock_cnt;
ssh_poll_callback cb;
void *cb_data;
};
struct ssh_poll_ctx_struct {
ssh_poll_handle *pollptrs;
ssh_pollfd_t *pollfds;
size_t polls_allocated;
size_t polls_used;
size_t chunk_size;
ssh_poll_handle *pollptrs;
ssh_pollfd_t *pollfds;
size_t polls_allocated;
size_t polls_used;
size_t chunk_size;
};
#ifdef HAVE_POLL
@@ -96,7 +96,7 @@ void ssh_poll_cleanup(void)
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
{
return poll((struct pollfd *) fds, nfds, timeout);
return poll((struct pollfd *)fds, nfds, timeout);
}
#else /* HAVE_POLL */
@@ -249,14 +249,15 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
}
#endif
// we use the readfds to get POLLHUP and POLLERR, which are provided even when not requested
FD_SET (fds[i].fd, &readfds);
// we use the readfds to get POLLHUP and POLLERR, which are provided
// even when not requested
FD_SET(fds[i].fd, &readfds);
if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
FD_SET (fds[i].fd, &writefds);
FD_SET(fds[i].fd, &writefds);
}
if (fds[i].events & (POLLPRI | POLLRDBAND)) {
FD_SET (fds[i].fd, &exceptfds);
FD_SET(fds[i].fd, &exceptfds);
}
if (fds[i].fd > max_fd) {
@@ -297,11 +298,12 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
fds[i].revents = 0;
if (FD_ISSET(fds[i].fd, &readfds)) {
fds[i].revents = bsd_socket_compute_revents(fds[i].fd,
fds[i].events);
fds[i].revents =
bsd_socket_compute_revents(fds[i].fd, fds[i].events);
}
if (FD_ISSET(fds[i].fd, &writefds)) {
fds[i].revents |= fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND);
fds[i].revents |=
fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND);
}
if (FD_ISSET(fds[i].fd, &exceptfds)) {
@@ -319,22 +321,26 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
return rc;
}
void ssh_poll_init(void) {
void ssh_poll_init(void)
{
ssh_poll_emu = bsd_poll;
}
void ssh_poll_cleanup(void) {
void ssh_poll_cleanup(void)
{
ssh_poll_emu = bsd_poll;
}
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
{
return (ssh_poll_emu)(fds, nfds, timeout);
}
#endif /* HAVE_POLL */
/**
* @brief Allocate a new poll object, which could be used within a poll context.
* @brief Allocate a new poll object, which could be used within a poll
* context.
*
* @param[in] fd Socket that will be polled.
* @param[in] events Poll events that will be monitored for the socket.
@@ -354,7 +360,7 @@ int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
ssh_poll_handle
ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata)
{
ssh_poll_handle p;
ssh_poll_handle p = NULL;
p = malloc(sizeof(struct ssh_poll_handle_struct));
if (p == NULL) {
@@ -370,7 +376,6 @@ ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata)
return p;
}
/**
* @brief Free a poll object.
*
@@ -433,8 +438,8 @@ void ssh_poll_set_events(ssh_poll_handle p, short events)
}
/**
* @brief Set the file descriptor of a poll object. The FD will also be propagated
* to an associated poll context.
* @brief Set the file descriptor of a poll object. The FD will also be
* propagated to an associated poll context.
*
* @param p Pointer to an already allocated poll object.
* @param fd New file descriptor.
@@ -496,7 +501,9 @@ socket_t ssh_poll_get_fd(ssh_poll_handle p)
* @param userdata Userdata to be passed to the callback function. NULL if
* not needed.
*/
void ssh_poll_set_callback(ssh_poll_handle p, ssh_poll_callback cb, void *userdata)
void ssh_poll_set_callback(ssh_poll_handle p,
ssh_poll_callback cb,
void *userdata)
{
if (cb != NULL) {
p->cb = cb;
@@ -542,7 +549,7 @@ ssh_poll_ctx ssh_poll_ctx_new(size_t chunk_size)
void ssh_poll_ctx_free(ssh_poll_ctx ctx)
{
if (ctx->polls_allocated > 0) {
while (ctx->polls_used > 0){
while (ctx->polls_used > 0) {
ssh_poll_handle p = ctx->pollptrs[0];
/*
* The free function calls ssh_poll_ctx_remove() and decrements
@@ -565,25 +572,33 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size)
pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * new_size);
if (pollptrs == NULL) {
return -1;
/* Fail, but keep the old value to be freed later */
return SSH_ERROR;
}
ctx->pollptrs = pollptrs;
pollfds = realloc(ctx->pollfds, sizeof(ssh_pollfd_t) * new_size);
if (pollfds == NULL) {
if (ctx->polls_allocated == 0) {
/* This was initial allocation -- just free what we allocated above
* and fail */
SAFE_FREE(ctx->pollptrs);
return SSH_ERROR;
}
/* Try to realloc the pollptrs back to the original size */
pollptrs = realloc(ctx->pollptrs,
sizeof(ssh_poll_handle) * ctx->polls_allocated);
if (pollptrs == NULL) {
return -1;
return SSH_ERROR;
}
ctx->pollptrs = pollptrs;
return -1;
return SSH_ERROR;
}
ctx->pollfds = pollfds;
ctx->polls_allocated = new_size;
return 0;
return SSH_OK;
}
/**
@@ -596,27 +611,27 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size)
*/
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p)
{
socket_t fd;
socket_t fd;
if (p->ctx != NULL) {
/* already attached to a context */
return -1;
}
if (p->ctx != NULL) {
/* already attached to a context */
return -1;
}
if (ctx->polls_used == ctx->polls_allocated &&
ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) {
return -1;
}
if (ctx->polls_used == ctx->polls_allocated &&
ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) {
return -1;
}
fd = p->x.fd;
p->x.idx = ctx->polls_used++;
ctx->pollptrs[p->x.idx] = p;
ctx->pollfds[p->x.idx].fd = fd;
ctx->pollfds[p->x.idx].events = p->events;
ctx->pollfds[p->x.idx].revents = 0;
p->ctx = ctx;
fd = p->x.fd;
p->x.idx = ctx->polls_used++;
ctx->pollptrs[p->x.idx] = p;
ctx->pollfds[p->x.idx].fd = fd;
ctx->pollfds[p->x.idx].events = p->events;
ctx->pollfds[p->x.idx].revents = 0;
p->ctx = ctx;
return 0;
return 0;
}
/**
@@ -627,20 +642,17 @@ int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p)
*
* @return 0 on success, < 0 on error
*/
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s)
int ssh_poll_ctx_add_socket(ssh_poll_ctx ctx, ssh_socket s)
{
ssh_poll_handle p = NULL;
int ret;
p = ssh_socket_get_poll_handle(s);
if (p == NULL) {
return -1;
}
ret = ssh_poll_ctx_add(ctx,p);
return ret;
return ssh_poll_ctx_add(ctx, p);
}
/**
* @brief Remove a poll object from a poll context.
*
@@ -649,25 +661,25 @@ int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s)
*/
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p)
{
size_t i;
size_t i;
i = p->x.idx;
p->x.fd = ctx->pollfds[i].fd;
p->ctx = NULL;
i = p->x.idx;
p->x.fd = ctx->pollfds[i].fd;
p->ctx = NULL;
ctx->polls_used--;
ctx->polls_used--;
/* fill the empty poll slot with the last one */
if (ctx->polls_used > 0 && ctx->polls_used != i) {
ctx->pollfds[i] = ctx->pollfds[ctx->polls_used];
ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used];
ctx->pollptrs[i]->x.idx = i;
}
/* fill the empty poll slot with the last one */
if (ctx->polls_used > 0 && ctx->polls_used != i) {
ctx->pollfds[i] = ctx->pollfds[ctx->polls_used];
ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used];
ctx->pollptrs[i]->x.idx = i;
}
/* this will always leave at least chunk_size polls allocated */
if (ctx->polls_allocated - ctx->polls_used > ctx->chunk_size) {
ssh_poll_ctx_resize(ctx, ctx->polls_allocated - ctx->chunk_size);
}
/* this will always leave at least chunk_size polls allocated */
if (ctx->polls_allocated - ctx->polls_used > ctx->chunk_size) {
ssh_poll_ctx_resize(ctx, ctx->polls_allocated - ctx->chunk_size);
}
}
/**
@@ -690,7 +702,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
{
int rc;
size_t i, used;
ssh_poll_handle p;
ssh_poll_handle p = NULL;
socket_t fd;
int revents;
struct ssh_timestamp ts;
@@ -745,7 +757,8 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
if (ret == -2) {
return -1;
}
/* the poll was removed, reload the used counter and start again */
/* the poll was removed, reload the used counter and start again
*/
used = ctx->polls_used;
i = 0;
} else {
@@ -771,8 +784,9 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
*/
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session)
{
if(session->default_poll_ctx != NULL)
if (session->default_poll_ctx != NULL) {
return session->default_poll_ctx;
}
/* 2 is enough for the default one */
session->default_poll_ctx = ssh_poll_ctx_new(2);
return session->default_poll_ctx;
@@ -782,7 +796,7 @@ ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session)
struct ssh_event_fd_wrapper {
ssh_event_callback cb;
void * userdata;
void *userdata;
};
struct ssh_event_struct {
@@ -811,14 +825,14 @@ ssh_event ssh_event_new(void)
ZERO_STRUCTP(event);
event->ctx = ssh_poll_ctx_new(2);
if(event->ctx == NULL) {
if (event->ctx == NULL) {
free(event);
return NULL;
}
#ifdef WITH_SERVER
event->sessions = ssh_list_new();
if(event->sessions == NULL) {
if (event->sessions == NULL) {
ssh_poll_ctx_free(event->ctx);
free(event);
return NULL;
@@ -828,9 +842,10 @@ ssh_event ssh_event_new(void)
return event;
}
static int
ssh_event_fd_wrapper_callback(ssh_poll_handle p, socket_t fd, int revents,
void *userdata)
static int ssh_event_fd_wrapper_callback(ssh_poll_handle p,
socket_t fd,
int revents,
void *userdata)
{
struct ssh_event_fd_wrapper *pw = (struct ssh_event_fd_wrapper *)userdata;
@@ -858,19 +873,22 @@ ssh_event_fd_wrapper_callback(ssh_poll_handle p, socket_t fd, int revents,
* @returns SSH_OK on success
* SSH_ERROR on failure
*/
int
ssh_event_add_fd(ssh_event event, socket_t fd, short events,
ssh_event_callback cb, void *userdata)
int ssh_event_add_fd(ssh_event event,
socket_t fd,
short events,
ssh_event_callback cb,
void *userdata)
{
ssh_poll_handle p;
ssh_poll_handle p = NULL;
struct ssh_event_fd_wrapper *pw = NULL;
int rc;
if(event == NULL || event->ctx == NULL || cb == NULL
|| fd == SSH_INVALID_SOCKET) {
if (event == NULL || event->ctx == NULL || cb == NULL ||
fd == SSH_INVALID_SOCKET) {
return SSH_ERROR;
}
pw = malloc(sizeof(struct ssh_event_fd_wrapper));
if(pw == NULL) {
if (pw == NULL) {
return SSH_ERROR;
}
@@ -879,12 +897,13 @@ ssh_event_add_fd(ssh_event event, socket_t fd, short events,
/* pw is freed by ssh_event_remove_fd */
p = ssh_poll_new(fd, events, ssh_event_fd_wrapper_callback, pw);
if(p == NULL) {
if (p == NULL) {
free(pw);
return SSH_ERROR;
}
if(ssh_poll_ctx_add(event->ctx, p) < 0) {
rc = ssh_poll_ctx_add(event->ctx, p);
if (rc < 0) {
free(pw);
ssh_poll_free(p);
return SSH_ERROR;
@@ -916,7 +935,7 @@ int ssh_event_add_poll(ssh_event event, ssh_poll_handle p)
*/
void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p)
{
ssh_poll_ctx_remove(event->ctx,p);
ssh_poll_ctx_remove(event->ctx, p);
}
/**
@@ -931,15 +950,16 @@ void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p)
*/
int ssh_event_add_session(ssh_event event, ssh_session session)
{
ssh_poll_handle p;
ssh_poll_handle p = NULL;
#ifdef WITH_SERVER
struct ssh_iterator *iterator = NULL;
#endif
int rc;
if(event == NULL || event->ctx == NULL || session == NULL) {
if (event == NULL || event->ctx == NULL || session == NULL) {
return SSH_ERROR;
}
if(session->default_poll_ctx == NULL) {
if (session->default_poll_ctx == NULL) {
return SSH_ERROR;
}
while (session->default_poll_ctx->polls_used > 0) {
@@ -949,7 +969,10 @@ int ssh_event_add_session(ssh_event event, ssh_session session)
* session->default_poll_ctx->polls_used
*/
ssh_poll_ctx_remove(session->default_poll_ctx, p);
ssh_poll_ctx_add(event->ctx, p);
rc = ssh_poll_ctx_add(event->ctx, p);
if (rc != SSH_OK) {
return rc;
}
/* associate the pollhandler with a session so we can put it back
* at ssh_event_free()
*/
@@ -957,14 +980,14 @@ int ssh_event_add_session(ssh_event event, ssh_session session)
}
#ifdef WITH_SERVER
iterator = ssh_list_get_iterator(event->sessions);
while(iterator != NULL) {
if((ssh_session)iterator->data == session) {
while (iterator != NULL) {
if ((ssh_session)iterator->data == session) {
/* allow only one instance of this session */
return SSH_OK;
}
iterator = iterator->next;
}
if(ssh_list_append(event->sessions, session) == SSH_ERROR) {
if (ssh_list_append(event->sessions, session) == SSH_ERROR) {
return SSH_ERROR;
}
#endif
@@ -1032,17 +1055,17 @@ int ssh_event_remove_fd(ssh_event event, socket_t fd)
register size_t i, used;
int rc = SSH_ERROR;
if(event == NULL || event->ctx == NULL) {
if (event == NULL || event->ctx == NULL) {
return SSH_ERROR;
}
used = event->ctx->polls_used;
for (i = 0; i < used; i++) {
if(fd == event->ctx->pollfds[i].fd) {
if (fd == event->ctx->pollfds[i].fd) {
ssh_poll_handle p = event->ctx->pollptrs[i];
if (p->session != NULL){
/* we cannot free that handle, it's owned by its session */
continue;
if (p->session != NULL) {
/* we cannot free that handle, it's owned by its session */
continue;
}
if (p->cb == ssh_event_fd_wrapper_callback) {
struct ssh_event_fd_wrapper *pw = p->cb_data;
@@ -1076,7 +1099,7 @@ int ssh_event_remove_fd(ssh_event event, socket_t fd)
*/
int ssh_event_remove_session(ssh_event event, ssh_session session)
{
ssh_poll_handle p;
ssh_poll_handle p = NULL;
register size_t i, used;
int rc = SSH_ERROR;
#ifdef WITH_SERVER
@@ -1097,7 +1120,10 @@ int ssh_event_remove_session(ssh_event event, ssh_session session)
*/
ssh_poll_ctx_remove(event->ctx, p);
p->session = NULL;
ssh_poll_ctx_add(session->default_poll_ctx, p);
rc = ssh_poll_ctx_add(session->default_poll_ctx, p);
if (rc != SSH_OK) {
return rc;
}
rc = SSH_OK;
/*
* Restart the loop!
@@ -1105,7 +1131,6 @@ int ssh_event_remove_session(ssh_event event, ssh_session session)
*/
used = event->ctx->polls_used;
i = 0;
}
}
#ifdef WITH_SERVER
@@ -1146,7 +1171,7 @@ int ssh_event_remove_connector(ssh_event event, ssh_connector connector)
void ssh_event_free(ssh_event event)
{
size_t used, i;
ssh_poll_handle p;
ssh_poll_handle p = NULL;
if (event == NULL) {
return;

View File

@@ -744,7 +744,10 @@ int ssh_handle_packets(ssh_session session, int timeout)
ssh_set_error_oom(session);
return SSH_ERROR;
}
ssh_poll_ctx_add(ctx, spoll);
rc = ssh_poll_ctx_add(ctx, spoll);
if (rc != SSH_OK) {
return SSH_ERROR;
}
}
if (timeout == SSH_TIMEOUT_USER) {

View File

@@ -202,7 +202,10 @@ void ssh_socket_reset(ssh_socket s)
s->read_wontblock = 0;
s->write_wontblock = 0;
s->data_except = 0;
s->poll_handle = NULL;
if (s->poll_handle != NULL) {
ssh_poll_free(s->poll_handle);
s->poll_handle = NULL;
}
s->state=SSH_SOCKET_NONE;
#ifndef _WIN32
s->proxy_pid = 0;
@@ -440,7 +443,7 @@ int ssh_socket_unix(ssh_socket s, const char *path)
ssh_set_error(s->session, SSH_FATAL,
"Error from socket(AF_UNIX, SOCK_STREAM, 0): %s",
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
return -1;
return SSH_ERROR;
}
#ifndef _WIN32
@@ -449,7 +452,7 @@ int ssh_socket_unix(ssh_socket s, const char *path)
"Error from fcntl(fd, F_SETFD, 1): %s",
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
CLOSE_SOCKET(fd);
return -1;
return SSH_ERROR;
}
#endif
@@ -458,10 +461,9 @@ int ssh_socket_unix(ssh_socket s, const char *path)
path,
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
CLOSE_SOCKET(fd);
return -1;
return SSH_ERROR;
}
ssh_socket_set_fd(s,fd);
return 0;
return ssh_socket_set_fd(s, fd);
}
/** \internal
@@ -519,7 +521,7 @@ void ssh_socket_close(ssh_socket s)
* @warning this function updates both the input and output
* file descriptors
*/
void ssh_socket_set_fd(ssh_socket s, socket_t fd)
int ssh_socket_set_fd(ssh_socket s, socket_t fd)
{
ssh_poll_handle h = NULL;
@@ -531,7 +533,7 @@ void ssh_socket_set_fd(ssh_socket s, socket_t fd)
s->state = SSH_SOCKET_CONNECTING;
h = ssh_socket_get_poll_handle(s);
if (h == NULL) {
return;
return SSH_ERROR;
}
/* POLLOUT is the event to wait for in a nonblocking connect */
@@ -540,6 +542,7 @@ void ssh_socket_set_fd(ssh_socket s, socket_t fd)
ssh_poll_add_events(h, POLLWRNORM);
#endif
}
return SSH_OK;
}
/** \internal
@@ -889,9 +892,7 @@ int ssh_socket_connect(ssh_socket s,
if (fd == SSH_INVALID_SOCKET) {
return SSH_ERROR;
}
ssh_socket_set_fd(s,fd);
return SSH_OK;
return ssh_socket_set_fd(s, fd);
}
#ifdef WITH_EXEC
@@ -985,8 +986,16 @@ ssh_socket_connect_proxycommand(ssh_socket s, const char *command)
}
s->proxy_pid = pid;
close(pair[0]);
SSH_LOG(SSH_LOG_DEBUG, "ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]);
ssh_socket_set_fd(s, pair[1]);
SSH_LOG(SSH_LOG_DEBUG,
"ProxyCommand connection pipe: [%d,%d]",
pair[0],
pair[1]);
rc = ssh_socket_set_fd(s, pair[1]);
if (rc != SSH_OK) {
return rc;
}
s->fd_is_socket = 0;
h = ssh_socket_get_poll_handle(s);
if (h == NULL) {
@@ -1276,7 +1285,12 @@ ssh_socket_connect_proxyjump(ssh_socket s)
"ProxyJump connection pipe: [%d,%d]",
pair[0],
pair[1]);
ssh_socket_set_fd(s, pair[1]);
rc = ssh_socket_set_fd(s, pair[1]);
if (rc != SSH_OK) {
return rc;
}
s->fd_is_socket = 1;
h = ssh_socket_get_poll_handle(s);
if (h == NULL) {