net: tcp: Verify if IPv4/IPv6 is enabled before processing addr family

TCP processed IPv4/IPv6 packets w/o verifying first if IPv4/IPv6 is
enabled in the system. This could lead to problems especially for IPv6,
where in case it's disabled the sockaddr structure is not large enough
to accomodate IPv6 address, leading to possible out-of-bound access on
the sockaddr structure.

Fix this by adding appropriate checks where applicable.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2022-03-15 14:24:37 +01:00 committed by Marti Bolivar
commit 2f2c356ca7

View file

@ -2305,6 +2305,11 @@ int net_tcp_connect(struct net_context *context,
const struct in6_addr *ip6; const struct in6_addr *ip6;
case AF_INET: case AF_INET:
if (!IS_ENABLED(CONFIG_NET_IPV4)) {
ret = -EINVAL;
goto out;
}
memset(&conn->src, 0, sizeof(struct sockaddr_in)); memset(&conn->src, 0, sizeof(struct sockaddr_in));
memset(&conn->dst, 0, sizeof(struct sockaddr_in)); memset(&conn->dst, 0, sizeof(struct sockaddr_in));
@ -2327,6 +2332,11 @@ int net_tcp_connect(struct net_context *context,
break; break;
case AF_INET6: case AF_INET6:
if (!IS_ENABLED(CONFIG_NET_IPV6)) {
ret = -EINVAL;
goto out;
}
memset(&conn->src, 0, sizeof(struct sockaddr_in6)); memset(&conn->src, 0, sizeof(struct sockaddr_in6));
memset(&conn->dst, 0, sizeof(struct sockaddr_in6)); memset(&conn->dst, 0, sizeof(struct sockaddr_in6));
@ -2419,6 +2429,10 @@ int net_tcp_accept(struct net_context *context, net_tcp_accept_cb_t cb,
struct sockaddr_in6 *in6; struct sockaddr_in6 *in6;
case AF_INET: case AF_INET:
if (!IS_ENABLED(CONFIG_NET_IPV4)) {
return -EINVAL;
}
in = (struct sockaddr_in *)&local_addr; in = (struct sockaddr_in *)&local_addr;
if (net_sin_ptr(&context->local)->sin_addr) { if (net_sin_ptr(&context->local)->sin_addr) {
@ -2434,6 +2448,10 @@ int net_tcp_accept(struct net_context *context, net_tcp_accept_cb_t cb,
break; break;
case AF_INET6: case AF_INET6:
if (!IS_ENABLED(CONFIG_NET_IPV6)) {
return -EINVAL;
}
in6 = (struct sockaddr_in6 *)&local_addr; in6 = (struct sockaddr_in6 *)&local_addr;
if (net_sin6_ptr(&context->local)->sin6_addr) { if (net_sin6_ptr(&context->local)->sin6_addr) {