diff --git a/docs/libssh2_session_banner_set.md b/docs/libssh2_session_banner_set.md index abff8efd..102eea3f 100644 --- a/docs/libssh2_session_banner_set.md +++ b/docs/libssh2_session_banner_set.md @@ -42,6 +42,8 @@ number, it is not really a failure per se. # ERRORS *LIBSSH2_ERROR_ALLOC* - An internal memory allocation call failed. +*LIBSSH2_ERROR_BAD_USE* - If `session` is NULL. +*LIBSSH2_ERROR_OUT_OF_BOUNDARY* - If banner is oversized (\> 4 MiB). # AVAILABILITY diff --git a/docs/libssh2_session_callback_set.md b/docs/libssh2_session_callback_set.md index 5381692a..590da2aa 100644 --- a/docs/libssh2_session_callback_set.md +++ b/docs/libssh2_session_callback_set.md @@ -37,4 +37,4 @@ which is expecting and returning a function pointer. # RETURN VALUE Pointer to previous callback handler. Returns NULL if no prior callback -handler was set or the callback type was unknown. +handler was set, the callback type was unknown, or `session` is NULL. diff --git a/docs/libssh2_session_callback_set2.md b/docs/libssh2_session_callback_set2.md index eb1991e8..58e01a92 100644 --- a/docs/libssh2_session_callback_set2.md +++ b/docs/libssh2_session_callback_set2.md @@ -168,4 +168,4 @@ can call libssh2_agent_sign(3) to perform signing. # RETURN VALUE Pointer to previous callback handler. Returns NULL if no prior callback -handler was set or the callback type was unknown. +handler was set, the callback type was unknown, or `session` is NULL. diff --git a/docs/libssh2_session_handshake.md b/docs/libssh2_session_handshake.md index f94dfe8c..981aa90e 100644 --- a/docs/libssh2_session_handshake.md +++ b/docs/libssh2_session_handshake.md @@ -38,6 +38,8 @@ Returns 0 on success, negative on failure. # ERRORS +*LIBSSH2_ERROR_BAD_USE* - If `session` is NULL. + *LIBSSH2_ERROR_SOCKET_NONE* - The socket is invalid. *LIBSSH2_ERROR_BANNER_SEND* - Unable to send banner to remote host. diff --git a/docs/libssh2_session_method_pref.md b/docs/libssh2_session_method_pref.md index 3384b2d4..1c83dadd 100644 --- a/docs/libssh2_session_method_pref.md +++ b/docs/libssh2_session_method_pref.md @@ -45,6 +45,8 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. # ERRORS +*LIBSSH2_ERROR_BAD_USE* - If `session` or `prefs` are NULL. + *LIBSSH2_ERROR_INVAL* - The requested method type was invalid. *LIBSSH2_ERROR_ALLOC* - An internal memory allocation call failed. diff --git a/src/kex.c b/src/kex.c index 012ca33e..4590709f 100644 --- a/src/kex.c +++ b/src/kex.c @@ -3773,9 +3773,14 @@ int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, { char **prefvar, *s, *newprefs; char *tmpprefs = NULL; - size_t prefs_len = strlen(prefs); + size_t prefs_len; const struct common_method **mlist; + if(!session || !prefs) + return LIBSSH2_ERROR_BAD_USE; + + prefs_len = strlen(prefs); + switch(method_type) { case LIBSSH2_METHOD_KEX: prefvar = &session->kex_prefs; diff --git a/src/session.c b/src/session.c index 72c17966..5620c9bb 100644 --- a/src/session.c +++ b/src/session.c @@ -335,12 +335,20 @@ static int session_get_socket_nonblocking(libssh2_socket_t sockfd) */ int libssh2_session_banner_set(LIBSSH2_SESSION *session, const char *banner) { - size_t banner_len = banner ? strlen(banner) : 0; + size_t banner_len; + + if(!session) + return LIBSSH2_ERROR_BAD_USE; + + banner_len = banner ? strlen(banner) : 0; + + if(banner_len > (4 * 1024 * 1024)) + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; if(session->local.banner) SSH2_SAFEFREE(session, session->local.banner); - if(!banner_len) + if(!banner || !banner_len) return 0; session->local.banner = SSH2_ALLOC(session, banner_len + 3); @@ -433,6 +441,9 @@ libssh2_cb_generic *libssh2_session_callback_set2(LIBSSH2_SESSION *session, { libssh2_cb_generic *oldcb; + if(!session) + return NULL; + switch(cbtype) { case LIBSSH2_CALLBACK_IGNORE: oldcb = (libssh2_cb_generic *)session->ssh_msg_ignore; @@ -792,6 +803,9 @@ int libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock) { int rc; + if(!session) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, session, session_startup(session, sock)); return rc; @@ -1032,6 +1046,9 @@ int libssh2_session_free(LIBSSH2_SESSION *session) { int rc; + if(!session) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, session, session_free(session)); return rc; @@ -1093,6 +1110,10 @@ int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang) { int rc; + + if(!session) + return LIBSSH2_ERROR_BAD_USE; + session->state &= ~SSH2_STATE_INITIAL_KEX; session->state &= ~SSH2_STATE_EXCHANGING_KEYS; BLOCK_ADJUST(rc, session, @@ -1112,6 +1133,9 @@ const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type) /* All methods have char *name as their first element */ const struct kex_method *method = NULL; + if(!session) + return NULL; + switch(method_type) { case LIBSSH2_METHOD_KEX: method = session->kex; @@ -1170,6 +1194,9 @@ const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type) */ void **libssh2_session_abstract(LIBSSH2_SESSION *session) { + if(!session) + return NULL; + return &session->abstract; } @@ -1183,6 +1210,9 @@ int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, { size_t msglen = 0; + if(!session) + return LIBSSH2_ERROR_BAD_USE; + /* No error to report */ if(!session->err_code) { if(errmsg) { @@ -1227,6 +1257,9 @@ int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, */ int libssh2_session_last_errno(LIBSSH2_SESSION *session) { + if(!session) + return LIBSSH2_ERROR_BAD_USE; + return session->err_code; } @@ -1250,6 +1283,9 @@ int libssh2_session_set_last_error(LIBSSH2_SESSION *session, */ int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value) { + if(!session) + return LIBSSH2_ERROR_BAD_USE; + switch(flag) { case LIBSSH2_FLAG_SIGPIPE: session->flag.sigpipe = value; @@ -1288,6 +1324,9 @@ int ssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) */ void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) { + if(!session) + return; + (void)ssh2_session_set_blocking(session, blocking); } @@ -1296,6 +1335,9 @@ void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) */ int libssh2_session_get_blocking(LIBSSH2_SESSION *session) { + if(!session) + return 0; + return session->api_block_mode; } @@ -1305,6 +1347,9 @@ int libssh2_session_get_blocking(LIBSSH2_SESSION *session) */ void libssh2_session_set_timeout(LIBSSH2_SESSION *session, long timeout) { + if(!session) + return; + session->api_timeout = timeout; } @@ -1313,6 +1358,9 @@ void libssh2_session_set_timeout(LIBSSH2_SESSION *session, long timeout) */ long libssh2_session_get_timeout(LIBSSH2_SESSION *session) { + if(!session) + return 0; + return session->api_timeout; } @@ -1322,6 +1370,9 @@ long libssh2_session_get_timeout(LIBSSH2_SESSION *session) */ void libssh2_session_set_read_timeout(LIBSSH2_SESSION *session, long timeout) { + if(!session) + return; + if(timeout <= 0) timeout = SSH2_DEFAULT_READ_TIMEOUT; @@ -1333,6 +1384,9 @@ void libssh2_session_set_read_timeout(LIBSSH2_SESSION *session, long timeout) */ long libssh2_session_get_read_timeout(LIBSSH2_SESSION *session) { + if(!session) + return 0; + return session->packet_read_timeout; } @@ -1730,6 +1784,9 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout) */ int libssh2_session_block_directions(LIBSSH2_SESSION *session) { + if(!session) + return 0; + return session->socket_block_directions; } @@ -1738,7 +1795,7 @@ int libssh2_session_block_directions(LIBSSH2_SESSION *session) */ const char *libssh2_session_banner_get(LIBSSH2_SESSION *session) { - if(!session) /* to avoid a coredump when session is NULL */ + if(!session) return NULL; if(!session->remote.banner)