commit 2d367411484fcc96012e7756481e597052f0bcd4
parent 9c7c06d8b8e8beb7f45107e51ed19c1be816c762
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Mon, 25 Apr 2022 15:43:26 +0300
MHD_get_daemon_info(): fixed unaligned memory access
Diffstat:
5 files changed, 55 insertions(+), 33 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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");