From 2d5b4ef2be429a694758a6795d3d229da59d71af Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 27 Aug 2020 16:24:59 +0200 Subject: Validate correctly against IPv6 addresses in osmo_ss7_asp_peer_set_hosts() Until now, host list validation was only taking into account a set of ipv4-only addresses. As a set can contain now IPv4 and Ipv6 addresses at the same time, we need to do ANYADDAR validation against addresses of that specific version inside the set. Change-Id: I18f3cc59149d478259d7afc456bdc5213c1406e5 --- src/osmo_ss7.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c index bae9904..b58de34 100644 --- a/src/osmo_ss7.c +++ b/src/osmo_ss7.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -1137,6 +1138,16 @@ int osmo_ss7_asp_peer_set_hosts(struct osmo_ss7_asp_peer *peer, void *talloc_ctx return 0; } +/* Is string formatted IPv4/v6 addr considered IN(6)ADDR_ANY? */ +static inline bool host_is_ip_anyaddr(const char *host, bool is_v6) +{ + /* NULL addr is resolved as 0.0.0.0 (IPv4) by getaddrinfo(), most + * probably for backward-compatibility reasons. + */ + return is_v6 ? (host && !strcmp(host, "::")) + : (!host || !strcmp(host, "0.0.0.0")); +} + /*! \brief Append (copy) address to a given ASP peer. Previous addresses are kept. * \param[in] peer Application Server Process peer the address is appened to. * \param[in] talloc_ctx talloc context used to allocate new address. @@ -1146,28 +1157,28 @@ int osmo_ss7_asp_peer_add_host(struct osmo_ss7_asp_peer *peer, void *talloc_ctx, { int i; - bool new_is_any = !host || !strcmp(host, "0.0.0.0"); - bool iter_is_any; + bool new_is_v6 = osmo_ip_str_type(host) == AF_INET6; + bool new_is_any = host_is_ip_anyaddr(host, new_is_v6); + bool iter_is_v6; if (peer->host_cnt >= ARRAY_SIZE(peer->host)) return -EINVAL; - /* Makes no sense to have INET_ANY many times, or INET_ANY together with - specific addresses: */ + /* Makes no sense to have INET(6)_ANY many times, or INET(6)_ANY + together with specific addresses, be it of same or different + IP version:*/ if (new_is_any && peer->host_cnt != 0) return -EINVAL; - /* Makes no sense to add specific address to set if INET_ANY is - already set: */ if (!new_is_any) { + /* Makes no sense to add specific address to set if INET(6)_ANY + is already set, be it from same or different IP version: */ for (i = 0; i < peer->host_cnt; i++) { - iter_is_any = !peer->host[i] || - !strcmp(peer->host[i], "0.0.0.0"); - if (iter_is_any) + iter_is_v6 = osmo_ip_str_type(peer->host[i]) == AF_INET6; + if (host_is_ip_anyaddr(peer->host[i], iter_is_v6)) return -EINVAL; } } - osmo_talloc_replace_string(talloc_ctx, &peer->host[peer->host_cnt], host); peer->host_cnt++; return 0; -- cgit v1.2.3