Skip to content

Commit c3e4f7c

Browse files
committed
TCP input - fix stack buffer overflow in acceptor.
1 parent 6380631 commit c3e4f7c

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/plugins/input/tcp/src/Acceptor.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232

3333
namespace tcp_in {
3434

35+
/** Constexpr implementation of std::max for 3 size_t values. */
36+
constexpr size_t max(size_t a, size_t b, size_t c) {
37+
return a > b ? (a > c ? a : c) : (b > c ? b : c);
38+
}
39+
3540
Acceptor::Acceptor(ClientManager &clients, ipx_ctx_t *ctx) :
3641
m_epoll(),
3742
m_sockets(),
@@ -74,9 +79,11 @@ void Acceptor::add_address(IpAddress &adr, uint16_t port, bool ipv6_only) {
7479
}
7580

7681
UniqueFd Acceptor::bind_address(IpAddress &addr, uint16_t port, bool ipv6_only) {
77-
sockaddr saddr{};
78-
auto v4 = reinterpret_cast<sockaddr_in *>(&saddr);
79-
auto v6 = reinterpret_cast<sockaddr_in6 *>(&saddr);
82+
// Allocate enough data to fit any of the structures.
83+
std::array<char, max(sizeof(sockaddr), sizeof(sockaddr_in), sizeof(sockaddr_in6))> addr_data;
84+
auto saddr = reinterpret_cast<sockaddr *>(addr_data.data());
85+
auto v4 = reinterpret_cast<sockaddr_in *>(saddr);
86+
auto v6 = reinterpret_cast<sockaddr_in6 *>(saddr);
8087
size_t addr_len;
8188

8289
if (addr.version == IpVersion::IP4) {
@@ -94,7 +101,7 @@ UniqueFd Acceptor::bind_address(IpAddress &addr, uint16_t port, bool ipv6_only)
94101

95102
const char *err_str;
96103

97-
UniqueFd sd(socket(saddr.sa_family, SOCK_STREAM, 0));
104+
UniqueFd sd(socket(saddr->sa_family, SOCK_STREAM, 0));
98105
if (!sd) {
99106
ipx_strerror(errno, err_str);
100107
throw std::runtime_error("Failed to create socket: " + std::string(err_str));
@@ -128,7 +135,7 @@ UniqueFd Acceptor::bind_address(IpAddress &addr, uint16_t port, bool ipv6_only)
128135
std::array<char, INET6_ADDRSTRLEN> addr_str{};
129136
inet_ntop(static_cast<int>(addr.version), &addr.v6, addr_str.begin(), INET6_ADDRSTRLEN);
130137

131-
if (bind(sd.get(), &saddr, addr_len) == -1) {
138+
if (bind(sd.get(), saddr, addr_len) == -1) {
132139
ipx_strerror(errno, err_str);
133140
throw std::runtime_error(
134141
"Failed to bind to socket (local IP: "

0 commit comments

Comments
 (0)