const int type = static_cast<int>(ibuffer.readUint32());
const int protocol = static_cast<int>(ibuffer.readUint32());
const socklen_t local_end_len = ibuffer.readUint32();
- if (local_end_len > sizeof(impl_->ss_local_)) {
- isc_throw(SocketSessionError, "Local SA length too large: " <<
+ const socklen_t endpoint_minlen = (family == AF_INET) ?
+ sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
+ if (local_end_len < endpoint_minlen ||
+ local_end_len > sizeof(impl_->ss_local_)) {
+ isc_throw(SocketSessionError, "Invalid local SA length: " <<
local_end_len);
}
ibuffer.readData(&impl_->ss_local_, local_end_len);
const socklen_t remote_end_len = ibuffer.readUint32();
- if (remote_end_len > sizeof(impl_->ss_remote_)) {
- isc_throw(SocketSessionError, "Remote SA length too large: " <<
+ if (remote_end_len < endpoint_minlen ||
+ remote_end_len > sizeof(impl_->ss_remote_)) {
+ isc_throw(SocketSessionError, "Invalid remote SA length: " <<
remote_end_len);
}
ibuffer.readData(&impl_->ss_remote_, remote_end_len);
- if (family != impl_->sa_local_->sa_family) {
+ if (family != impl_->sa_local_->sa_family ||
+ family != impl_->sa_remote_->sa_family) {
isc_throw(SocketSessionError, "SA family inconsistent: " <<
static_cast<int>(impl_->sa_local_->sa_family) << ", " <<
static_cast<int>(impl_->sa_remote_->sa_family) <<
#include <cerrno>
#include <cstring>
+#include <algorithm>
#include <string>
#include <utility>
#include <vector>
obuffer.writeUint32(static_cast<uint32_t>(type));
obuffer.writeUint32(static_cast<uint32_t>(protocol));
obuffer.writeUint32(static_cast<uint32_t>(local_len));
- obuffer.writeData(&local, getSALength(local));
+ obuffer.writeData(&local, min(local_len, getSALength(local)));
obuffer.writeUint32(static_cast<uint32_t>(remote_len));
- obuffer.writeData(&remote, getSALength(remote));
+ obuffer.writeData(&remote, min(remote_len, getSALength(remote)));
obuffer.writeUint32(static_cast<uint32_t>(data_len));
pushSessionHeader(obuffer.getLength());
if (send(dummy_forwarder_.fd, obuffer.getData(), obuffer.getLength(),
pushSession(AF_INET, SOCK_DGRAM, IPPROTO_UDP, sai_local.second,
*sai_local.first, sai6.second, *sai6.first);
dummy_forwarder_.reset(-1);
+ EXPECT_THROW(receiver_->pop(), SocketSessionError);
// Pass too big sa length for local
pushSession(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
dummy_forwarder_.reset(-1);
EXPECT_THROW(receiver_->pop(), SocketSessionError);
+ // Pass too small sa length for local
+ pushSession(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+ sizeof(struct sockaddr_in) - 1, *sai_local.first,
+ sai_remote.second, *sai_remote.first);
+ dummy_forwarder_.reset(-1);
+ EXPECT_THROW(receiver_->pop(), SocketSessionError);
+
+ // Same for remote
+ pushSession(AF_INET6, SOCK_DGRAM, IPPROTO_UDP,
+ sai6.second, *sai6.first, sizeof(struct sockaddr_in6) - 1,
+ *sai6.first);
+ dummy_forwarder_.reset(-1);
+ EXPECT_THROW(receiver_->pop(), SocketSessionError);
+
// Data length is too large
pushSession(AF_INET, SOCK_DGRAM, IPPROTO_UDP, sai_local.second,
*sai_local.first, sai_remote.second,