libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 314917828af997bcd4abe0b748a254d562f6023a
parent a4036e668134d1ad9637534bac1e0cb55d0a2b36
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sat, 23 Apr 2022 19:18:47 +0300

MHD_get_connection_info(): Fixed possible unaligned access

Also:
* Reduced number of 'MHD_Connection' members.
* Fixed wrong value of returned timeout on some platforms, if timeout
is too large.

Diffstat:
Msrc/include/microhttpd.h | 2++
Msrc/microhttpd/connection.c | 56++++++++++++++++++++++++++++++++++++++------------------
Msrc/microhttpd/internal.h | 23++++-------------------
3 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -4429,6 +4429,8 @@ MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, /** * Obtain information about the given connection. + * The returned pointer is invalidated with the next call of this function or + * when the connection is closed. * * @param connection what connection to get information about * @param info_type what information is desired? diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -4995,6 +4995,8 @@ MHD_set_http_callbacks_ (struct MHD_Connection *connection) /** * Obtain information about the given connection. + * The returned pointer is invalidated with the next call of this function or + * when the connection is closed. * * @param connection what connection to get information about * @param info_type what information is desired? @@ -5014,44 +5016,62 @@ MHD_get_connection_info (struct MHD_Connection *connection, case MHD_CONNECTION_INFO_CIPHER_ALGO: if (NULL == connection->tls_session) return NULL; - connection->cipher = gnutls_cipher_get (connection->tls_session); - return (const union MHD_ConnectionInfo *) &connection->cipher; + connection->connection_info_dummy.cipher_algorithm = + gnutls_cipher_get (connection->tls_session); + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_PROTOCOL: if (NULL == connection->tls_session) return NULL; - connection->protocol = gnutls_protocol_get_version ( - connection->tls_session); - return (const union MHD_ConnectionInfo *) &connection->protocol; + connection->connection_info_dummy.protocol = + gnutls_protocol_get_version (connection->tls_session); + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_GNUTLS_SESSION: if (NULL == connection->tls_session) return NULL; - return (const union MHD_ConnectionInfo *) &connection->tls_session; + connection->connection_info_dummy.tls_session = connection->tls_session; + return &connection->connection_info_dummy; #endif /* HTTPS_SUPPORT */ case MHD_CONNECTION_INFO_CLIENT_ADDRESS: - return (const union MHD_ConnectionInfo *) &connection->addr; + memset (&connection->connection_info_dummy.client_addr, 0, + sizeof (connection->connection_info_dummy.client_addr)); + memcpy (&connection->connection_info_dummy.client_addr, + &connection->addr, + connection->addr_len); + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_DAEMON: - return (const union MHD_ConnectionInfo *) &connection->daemon; + connection->connection_info_dummy.daemon = connection->daemon; + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_CONNECTION_FD: - return (const union MHD_ConnectionInfo *) &connection->socket_fd; + connection->connection_info_dummy.connect_fd = connection->socket_fd; + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_SOCKET_CONTEXT: - return (const union MHD_ConnectionInfo *) &connection->socket_context; + connection->connection_info_dummy.socket_context = + connection->socket_context; + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_CONNECTION_SUSPENDED: - connection->suspended_dummy = connection->suspended ? MHD_YES : MHD_NO; - return (const union MHD_ConnectionInfo *) &connection->suspended_dummy; + connection->connection_info_dummy.suspended = + connection->suspended ? MHD_YES : MHD_NO; + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_CONNECTION_TIMEOUT: - connection->connection_timeout_dummy = - (unsigned int) connection->connection_timeout_ms / 1000; - return (const union MHD_ConnectionInfo *) &connection-> - connection_timeout_dummy; +#if SIZEOF_UNSIGNED_INT <= (SIZEOF_UINT64_T - 2) + if (UINT_MAX < connection->connection_timeout_ms / 1000) + connection->connection_info_dummy.connection_timeout = UINT_MAX; + else +#endif /* SIZEOF_UNSIGNED_INT <=(SIZEOF_UINT64_T - 2) */ + connection->connection_info_dummy.connection_timeout = + (unsigned int) (connection->connection_timeout_ms / 1000); + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE: if ( (MHD_CONNECTION_HEADERS_RECEIVED > connection->state) || (MHD_CONNECTION_CLOSED == connection->state) ) return NULL; /* invalid, too early! */ - return (const union MHD_ConnectionInfo *) &connection->header_size; + connection->connection_info_dummy.header_size = connection->header_size; + return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_HTTP_STATUS: if (NULL == connection->response) return NULL; - return (const union MHD_ConnectionInfo *) &connection->responseCode; + connection->connection_info_dummy.http_status = connection->responseCode; + return &connection->connection_info_dummy; default: return NULL; } diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -1171,11 +1171,6 @@ struct MHD_Connection uint64_t connection_timeout_ms; /** - * Special member to be returned by #MHD_get_connection_info() - */ - unsigned int connection_timeout_dummy; - - /** * Did we ever call the "default_handler" on this connection? (this * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED * handler when the connection closes down). @@ -1343,16 +1338,6 @@ struct MHD_Connection gnutls_session_t tls_session; /** - * Memory location to return for protocol session info. - */ - int protocol; - - /** - * Memory location to return for protocol session info. - */ - int cipher; - - /** * State of connection's TLS layer */ enum MHD_TLS_CONN_STATE tls_state; @@ -1370,14 +1355,14 @@ struct MHD_Connection bool suspended; /** - * Special member to be returned by #MHD_get_connection_info() + * Is the connection wanting to resume? */ - int suspended_dummy; + volatile bool resuming; /** - * Is the connection wanting to resume? + * Special member to be returned by #MHD_get_connection_info() */ - volatile bool resuming; + union MHD_ConnectionInfo connection_info_dummy; };