Skip to content

[BUG] SocketAddr(u_long, int) performs misaligned sockaddr_in access and truncates out-of-range ports #4307

Description

@thc1006

Description

SocketTools::SocketAddr(u_long addr, int port) in ext/include/opentelemetry/ext/http/server/socket_tools.h has two defects:

1. Alignment / type-access UB. It binds a sockaddr_in & to the sockaddr m_data storage through a reinterpret_cast:

sockaddr_in &inet4 = reinterpret_cast<sockaddr_in &>(m_data);

sockaddr and sockaddr_in do not share alignment on all platforms (on Linux alignof(sockaddr) == 2 but alignof(sockaddr_in) == 4), so accessing the storage through a sockaddr_in glvalue is an alignment / strict-aliasing issue that UBSan reports.

2. Silent port truncation. port is an int cast to uint16_t with no range check:

inet4.sin_port = htons(static_cast<uint16_t>(port));

so out-of-range values wrap silently:

  • -165535
  • 655360
  • 9999934463

Impact

This constructor is on the live server path: it has an addListeningPort caller (unlike the SocketAddr(char const *) overload, which has no in-repo caller). The string-parsing overload was made safe in #4292 (it memcpys a local sockaddr_in in and out of the storage and parses a strict decimal port); this integer constructor still uses the old reinterpret_cast access and the unchecked port cast.

Suggested fix

Mirror #4292's approach: build a local sockaddr_in, memcpy it into m_data, and validate or clamp the port range (or document the caller's contract that the port is already in 0..65535).

Context

Split out of the ext/http correctness audit (#4287). #4292 deliberately scoped this out to keep that PR limited to the string parser.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triage/acceptedIndicates an issue or PR is ready to be actively worked on.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions