Skip to content

Commit

Permalink
bootloader: on Windows, avoid using ntohl() from ws2_32 library
Browse files Browse the repository at this point in the history
On Windows, use built-in byte-swap macros instead of ntohl(), which
is available from winsock2 library. Using the latter requires the
bootloader to be linked against the winsock2 library, which may have
other unintended consequences.

On all other platforms, continue using ntohl() for now, but hide it
behind the pyi_be32toh() macro.
  • Loading branch information
rokm committed Jan 28, 2021
1 parent 1d6ab0e commit 7d9cbd4
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 15 deletions.
33 changes: 23 additions & 10 deletions bootloader/src/pyi_archive.c
Expand Up @@ -16,15 +16,28 @@
*/

#ifdef _WIN32
/* TODO verify windows includes */
#include <winsock.h> /* ntohl */
#if BYTE_ORDER == LITTLE_ENDIAN
#if defined(_MSC_VER)
#include <stdlib.h>
#define pyi_be32toh(x) _byteswap_ulong(x)
#elif defined(__GNUC__) || defined(__clang__)
#define pyi_be32toh(x) __builtin_bswap32(x)
#else
#error Unsupported compiler
#endif
#elif BYTE_ORDER == BIG_ENDIAN
#define pyi_be32toh(x) (x)
#else
#error Unsupported byte order
#endif
#else
#ifdef __FreeBSD__
/* freebsd issue #188316 */
#include <arpa/inet.h> /* ntohl */
#else
#include <netinet/in.h> /* ntohl */
#endif
#define pyi_be32toh(x) ntohl(x)
#include <stdlib.h> /* malloc */
#include <string.h> /* strncmp, strcpy, strcat */
#include <sys/stat.h> /* fchmod */
Expand Down Expand Up @@ -266,10 +279,10 @@ pyi_arch_find_cookie(ARCHIVE_STATUS *status, int search_end)
memcpy(&status->cookie, search_ptr, sizeof(COOKIE));

/* Fix endianess of COOKIE fields */
status->cookie.len = ntohl(status->cookie.len);
status->cookie.TOC = ntohl(status->cookie.TOC);
status->cookie.TOClen = ntohl(status->cookie.TOClen);
status->cookie.pyvers = ntohl(status->cookie.pyvers);
status->cookie.len = pyi_be32toh(status->cookie.len);
status->cookie.TOC = pyi_be32toh(status->cookie.TOC);
status->cookie.TOClen = pyi_be32toh(status->cookie.TOClen);
status->cookie.pyvers = pyi_be32toh(status->cookie.pyvers);

/* From the cookie, calculate the archive start */
status->pkgstart = search_start + sizeof(COOKIE) + (search_ptr - buf) - status->cookie.len;
Expand Down Expand Up @@ -389,10 +402,10 @@ _pyi_arch_fix_toc_endianess(ARCHIVE_STATUS *status)
TOC *ptoc = status->tocbuff;
while (ptoc < status->tocend) {
/* Fixup the current entry */
ptoc->structlen = ntohl(ptoc->structlen);
ptoc->pos = ntohl(ptoc->pos);
ptoc->len = ntohl(ptoc->len);
ptoc->ulen = ntohl(ptoc->ulen);
ptoc->structlen = pyi_be32toh(ptoc->structlen);
ptoc->pos = pyi_be32toh(ptoc->pos);
ptoc->len = pyi_be32toh(ptoc->len);
ptoc->ulen = pyi_be32toh(ptoc->ulen);
/* Jump to next entry; with the current entry fixed up, we can
* use pyi_arch_increment_toc_ptr() */
ptoc = pyi_arch_increment_toc_ptr(status, ptoc);
Expand Down
1 change: 1 addition & 0 deletions bootloader/src/pyi_global.h
Expand Up @@ -51,6 +51,7 @@ typedef int bool;

/* Type for dynamic library. */
#ifdef _WIN32
#include <windows.h> /* HINSTANCE */
#define dylib_t HINSTANCE
#else
#define dylib_t void *
Expand Down
3 changes: 1 addition & 2 deletions bootloader/tests/wscript
Expand Up @@ -17,10 +17,9 @@ def build(ctx):

def test_program(name):
if ctx.env.DEST_OS == 'win32':
# WS2_32: ntohl()
# Z: inflate*()
# ADVAPI32: ConvertStringSecurityDescriptorToSecurityDescriptorW()
extra_libs=['ADVAPI32', 'WS2_32', 'Z']
extra_libs=['ADVAPI32', 'Z']
else:
extra_libs=[]
ctx.program(
Expand Down
5 changes: 2 additions & 3 deletions bootloader/wscript
Expand Up @@ -556,14 +556,13 @@ def configure(ctx):

if ctx.env.DEST_OS == 'win32':
if ctx.env.CC_NAME == 'msvc':
ctx.check_libs_msvc('user32 comctl32 kernel32 advapi32 ws2_32',
ctx.check_libs_msvc('user32 comctl32 kernel32 advapi32',
mandatory=True)
else:
ctx.check_cc(lib='user32', mandatory=True)
ctx.check_cc(lib='comctl32', mandatory=True)
ctx.check_cc(lib='kernel32', mandatory=True)
ctx.check_cc(lib='advapi32', mandatory=True)
ctx.check_cc(lib='ws2_32', mandatory=True)
else:
# Mac OS X and FreeBSD do not need libdl.
# https://stackoverflow.com/questions/20169660/where-is-libdl-so-on-mac-os-x
Expand Down Expand Up @@ -750,7 +749,7 @@ def build(ctx):
source=['src/main.c', icon_rc],
target=exe_name,
install_path=install_path,
use='OBJECTS USER32 COMCTL32 KERNEL32 ADVAPI32 WS2_32 Z',
use='OBJECTS USER32 COMCTL32 KERNEL32 ADVAPI32 Z',
includes='src windows zlib',
features=features,
)
Expand Down

0 comments on commit 7d9cbd4

Please sign in to comment.