From 2d367411484fcc96012e7756481e597052f0bcd4 Mon Sep 17 00:00:00 2001 From: "Evgeny Grin (Karlson2k)" Date: Mon, 25 Apr 2022 15:43:26 +0300 Subject: MHD_get_daemon_info(): fixed unaligned memory access --- src/include/microhttpd.h | 5 +++-- src/microhttpd/daemon.c | 21 ++++++++++++++------- src/microhttpd/internal.h | 28 ++++++++++++++++++++++++++++ src/microhttpd/test_upgrade.c | 17 +++++------------ src/microhttpd/test_upgrade_large.c | 17 +++++------------ 5 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index cf8216d0..b4bc85e3 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h @@ -4529,8 +4529,9 @@ union MHD_DaemonInfo /** - * Obtain information about the given daemon - * (not fully implemented!). + * Obtain information about the given daemon. + * The returned pointer is invalidated with the next call of this function or + * when the daemon is stopped. * * @param daemon what daemon to get information about * @param info_type what information is desired? diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 6cbd9ad5..35708b27 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -7813,8 +7813,9 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) /** - * Obtain information about the given daemon - * (not fully implemented!). + * Obtain information about the given daemon. + * The returned pointer is invalidated with the next call of this function or + * when the daemon is stopped. * * @param daemon what daemon to get information about * @param info_type what information is desired? @@ -7837,10 +7838,12 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon, case MHD_DAEMON_INFO_MAC_KEY_SIZE: return NULL; /* no longer supported */ case MHD_DAEMON_INFO_LISTEN_FD: - return (const union MHD_DaemonInfo *) &daemon->listen_fd; + daemon->daemon_info_dummy_listen_fd.listen_fd = daemon->listen_fd; + return &daemon->daemon_info_dummy_listen_fd; #ifdef EPOLL_SUPPORT case MHD_DAEMON_INFO_EPOLL_FD: - return (const union MHD_DaemonInfo *) &daemon->epoll_fd; + daemon->daemon_info_dummy_epoll_fd.epoll_fd = daemon->epoll_fd; + return &daemon->daemon_info_dummy_epoll_fd; #endif case MHD_DAEMON_INFO_CURRENT_CONNECTIONS: if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) @@ -7862,11 +7865,15 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon, } } #endif - return (const union MHD_DaemonInfo *) &daemon->connections; + daemon->daemon_info_dummy_num_connections.num_connections + = daemon->connections; + return &daemon->daemon_info_dummy_num_connections; case MHD_DAEMON_INFO_FLAGS: - return (const union MHD_DaemonInfo *) &daemon->options; + daemon->daemon_info_dummy_flags.flags = daemon->options; + return &daemon->daemon_info_dummy_flags; case MHD_DAEMON_INFO_BIND_PORT: - return (const union MHD_DaemonInfo *) &daemon->port; + daemon->daemon_info_dummy_port.port = daemon->port; + return &daemon->daemon_info_dummy_port; default: return NULL; } diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index 094c26ba..fc8ec0c6 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h @@ -2164,6 +2164,34 @@ struct MHD_Daemon * #MHD_OPTION_ARRAY are counted. */ size_t num_opts; + + /* TODO: replace with a single member */ + /** + * The value to be returned by #MHD_get_daemon_info() + */ + union MHD_DaemonInfo daemon_info_dummy_listen_fd; + +#ifdef EPOLL_SUPPORT + /** + * The value to be returned by #MHD_get_daemon_info() + */ + union MHD_DaemonInfo daemon_info_dummy_epoll_fd; +#endif /* EPOLL_SUPPORT */ + + /** + * The value to be returned by #MHD_get_daemon_info() + */ + union MHD_DaemonInfo daemon_info_dummy_num_connections; + + /** + * The value to be returned by #MHD_get_daemon_info() + */ + union MHD_DaemonInfo daemon_info_dummy_flags; + + /** + * The value to be returned by #MHD_get_daemon_info() + */ + union MHD_DaemonInfo daemon_info_dummy_port; }; diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade.c index acaecf9f..d4b97718 100644 --- a/src/microhttpd/test_upgrade.c +++ b/src/microhttpd/test_upgrade.c @@ -1257,7 +1257,7 @@ test_upgrade (int flags, struct MHD_Daemon *d = NULL; struct wr_socket *sock; struct sockaddr_in sa; - const union MHD_DaemonInfo *real_flags; + enum MHD_FLAG used_flags; const union MHD_DaemonInfo *dinfo; #if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID) pid_t pid = -1; @@ -1296,10 +1296,11 @@ test_upgrade (int flags, #endif /* HTTPS_SUPPORT */ if (NULL == d) mhdErrorExitDesc ("MHD_start_daemon() failed"); - real_flags = MHD_get_daemon_info (d, - MHD_DAEMON_INFO_FLAGS); - if (NULL == real_flags) + dinfo = MHD_get_daemon_info (d, + MHD_DAEMON_INFO_FLAGS); + if (NULL == dinfo) mhdErrorExitDesc ("MHD_get_daemon_info() failed"); + used_flags = dinfo->flags; dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); if ( (NULL == dinfo) || @@ -1347,15 +1348,7 @@ test_upgrade (int flags, sock)) externalErrorExitDesc ("pthread_create() failed"); if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) ) - { - enum MHD_FLAG used_flags; - - /* make address sanitizer happy */ - memcpy (&used_flags, - real_flags /* ->flags */, - sizeof (used_flags)); run_mhd_loop (d, used_flags); - } if (0 != pthread_join (pt_client, NULL)) externalErrorExitDesc ("pthread_join() failed"); diff --git a/src/microhttpd/test_upgrade_large.c b/src/microhttpd/test_upgrade_large.c index e04e7ebf..477a0851 100644 --- a/src/microhttpd/test_upgrade_large.c +++ b/src/microhttpd/test_upgrade_large.c @@ -1445,7 +1445,7 @@ test_upgrade (int flags, struct MHD_Daemon *d = NULL; struct wr_socket *sock; struct sockaddr_in sa; - const union MHD_DaemonInfo *real_flags; + enum MHD_FLAG used_flags; const union MHD_DaemonInfo *dinfo; #if defined(HTTPS_SUPPORT) && defined(HAVE_FORK) && defined(HAVE_WAITPID) pid_t pid = -1; @@ -1486,10 +1486,11 @@ test_upgrade (int flags, #endif /* HTTPS_SUPPORT */ if (NULL == d) mhdErrorExitDesc ("MHD_start_daemon() failed"); - real_flags = MHD_get_daemon_info (d, - MHD_DAEMON_INFO_FLAGS); - if (NULL == real_flags) + dinfo = MHD_get_daemon_info (d, + MHD_DAEMON_INFO_FLAGS); + if (NULL == dinfo) mhdErrorExitDesc ("MHD_get_daemon_info() failed"); + used_flags = dinfo->flags; dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); if ( (NULL == dinfo) || @@ -1543,15 +1544,7 @@ test_upgrade (int flags, sock)) externalErrorExitDesc ("pthread_create() failed"); if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) ) - { - enum MHD_FLAG used_flags; - - /* make address sanitizer happy */ - memcpy (&used_flags, - real_flags /* ->flags */, - sizeof (used_flags)); run_mhd_loop (d, used_flags); - } if (0 != pthread_join (pt_client, NULL)) externalErrorExitDesc ("pthread_join() failed"); -- cgit v1.2.3