]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
netaddrq: Fix crash if there are no IP addresses
authorStanislav Brabec <sbrabec@suse.cz>
Tue, 7 Oct 2025 23:14:32 +0000 (01:14 +0200)
committerStanislav Brabec <sbrabec@suse.cz>
Tue, 7 Oct 2025 23:19:29 +0000 (01:19 +0200)
If there are no IP addresses, ul_netaddrq_bestaddr() returns threshold
ULNETLINK_RATING_BAD, but there were no addresses in the best array, and
best_ifaceq remains unset, which caused crash. Setting the initial
threshold to __ULNETLINK_RATING_MAX and checking for that value fixes that.
And more, it also allows to accept IP addresses with ULNETLINK_RATING_BAD
rating.

Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
include/netaddrq.h
lib/netaddrq.c
term-utils/agetty.c

index 6d5e655f509dfd88752e2a29fc5633002b81db94..d9c595f326d42f269f16acd8b48a7f45a5f9806a 100644 (file)
@@ -94,8 +94,11 @@ ul_netaddrq_iface_bestaddr(struct list_head *ipq_list,
  *   best_iface: interface where the best address was seen
  *   best array: best ifa_valid lifetime seen per quality rating
  *   return value: best rating seen
- * Note: It can be needed to call it twice: once for ip_quality_list_4, once
- * for ip_quality_list_6.
+ * Notes:
+ * - It can be needed to call it twice: once for ip_quality_list_4, once
+ *   for ip_quality_list_6.
+ * - If no IP addresses are found, the function can return
+ *   _ULNETLINK_RATING_MAX!
  */
 enum ul_netaddrq_ip_rating
 ul_netaddrq_bestaddr(struct ul_nl_data *nl,
@@ -109,8 +112,11 @@ ul_netaddrq_bestaddr(struct ul_nl_data *nl,
  *   return value: The best address as a string
  *   threshold: The best rating ever seen.
  *   best_ifaceq: The best rated interfece ever seen.
- * Note: It can be needed to call it twice: once for AF_INET, once
- * for AF_INET6.
+ * Notes:
+ * - It can be needed to call it twice: once for AF_INET, once
+ *   for AF_INET6.
+ * - If the return value is NULL (i. e. there are no usable interfaces), then
+ *   *best_ifaceq remains unchanges and cannot be used.
  */
 const char *ul_netaddrq_get_best_ipp(struct ul_nl_data *nl,
                                     uint8_t ifa_family,
index 34431d8d3f6bbf273532d356070a7cd2bd9b087f..1ce454aafbbf66db63de88ab9508d9396b04bd97 100644 (file)
@@ -296,7 +296,7 @@ ul_netaddrq_iface_bestaddr(struct list_head *ipq_list,
        struct ul_netaddrq_ip *ipq;
        enum ul_netaddrq_ip_rating threshold;
 
-       threshold = ULNETLINK_RATING_BAD;
+       threshold = __ULNETLINK_RATING_MAX;
        list_for_each(li, ipq_list)
        {
                ipq = list_entry(li, struct ul_netaddrq_ip, entry);
@@ -342,7 +342,7 @@ ul_netaddrq_bestaddr(struct ul_nl_data *nl,
                ipqo = offsetof(struct ul_netaddrq_iface, ip_quality_list_6);
        }
 
-       threshold = ULNETLINK_RATING_BAD;
+       threshold = __ULNETLINK_RATING_MAX;
        list_for_each(li, &(addrq->ifaces))
        {
                struct list_head *ipq_list;
@@ -374,7 +374,7 @@ const char *ul_netaddrq_get_best_ipp(struct ul_nl_data *nl,
 
        memset(best, 0, sizeof(best));
        *threshold = ul_netaddrq_bestaddr(nl, best_ifaceq, &best, ifa_family);
-       if (best[*threshold])
+       if (*threshold != __ULNETLINK_RATING_MAX)
                return ul_nl_addr_ntop_address(best[*threshold]->addr);
        return NULL;
 }
@@ -423,7 +423,7 @@ static void dump_iface_best(struct ul_nl_data *nl,
        memset(best, 0, sizeof(best));
        threshold = ul_netaddrq_iface_bestaddr(&(ifaceq->ip_quality_list_4),
                                               &best);
-       if (best[threshold])
+       if (threshold != __ULNETLINK_RATING_MAX)
        {
                fprintf(netout, "%s IPv4: %s", (first ? "best address" : " "),
                       ul_nl_addr_ntop_address(best[threshold]->addr));
@@ -432,7 +432,7 @@ static void dump_iface_best(struct ul_nl_data *nl,
        memset(best, 0, sizeof(best));
        threshold = ul_netaddrq_iface_bestaddr(&(ifaceq->ip_quality_list_6),
                                               &best);
-       if (best[threshold])
+       if (threshold != __ULNETLINK_RATING_MAX)
        {
                fprintf(netout, "%s IPv6: %s", (first ? "best address" : " "),
                       ul_nl_addr_ntop_address(best[threshold]->addr));
index b7786ce7d72a39008e3fc92be26a00e974b86c98..ec922bd1119fe3b8018148499bd11d0d772b6bf6 100644 (file)
@@ -2603,7 +2603,7 @@ static void print_iface_best(struct issue *ie,
 
                threshold =
                        ul_netaddrq_iface_bestaddr(l, &best);
-               if (best[threshold])
+               if (threshold != __ULNETLINK_RATING_MAX)
                        fputs(ul_nl_addr_ntop_address(best[threshold]->addr),
                              ie->output);
        }