nss-resolve: fix blank array checks and improve NSS status codes

Use sd_json_variant_is_blank_array() instead of is_blank_object() for
p.addresses and p.names, which are declared as JSON arrays. The wrong
predicate never triggered, allowing empty arrays to bypass the guards:
for p.names this caused a size_t underflow leading to an out-of-bounds
heap write; for p.addresses it returned success with no addresses.

Add explicit n_addresses == 0 guards after the family-filter loops so
entries with unsupported families also return NOTFOUND rather than
crashing on a NULL dereference.

In gethostbyname3_r (family-specific entry point), return NO_DATA for
all zero-address results — both blank array and all-filtered — since
both mean "name resolved, no record of the requested family". Keep
HOST_NOT_FOUND in gethostbyname4_r (both-families) where a blank or
all-unsupported result genuinely means the name was not found.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
dongshengyuan
2026-06-16 09:19:15 +08:00
committed by Yu Watanabe
parent 27556c03c2
commit dc5c09917e

View File

@@ -264,7 +264,7 @@ enum nss_status _nss_resolve_gethostbyname4_r(
r = sd_json_dispatch(rparams, resolve_hostname_reply_dispatch_table, nss_json_dispatch_flags, &p);
if (r < 0)
goto fail;
if (sd_json_variant_is_blank_object(p.addresses))
if (sd_json_variant_is_blank_array(p.addresses))
goto not_found;
size_t n_addresses = 0;
@@ -286,6 +286,9 @@ enum nss_status _nss_resolve_gethostbyname4_r(
n_addresses++;
}
if (n_addresses == 0)
goto not_found;
const char *canonical = p.name ?: name;
size_t l = strlen(canonical);
size_t idx, ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * n_addresses;
@@ -429,8 +432,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
r = sd_json_dispatch(rparams, resolve_hostname_reply_dispatch_table, nss_json_dispatch_flags, &p);
if (r < 0)
goto fail;
if (sd_json_variant_is_blank_object(p.addresses))
goto not_found;
if (sd_json_variant_is_blank_array(p.addresses))
goto no_data;
size_t n_addresses = 0;
JSON_VARIANT_ARRAY_FOREACH(entry, p.addresses) {
@@ -451,6 +454,9 @@ enum nss_status _nss_resolve_gethostbyname3_r(
n_addresses++;
}
if (n_addresses == 0)
goto no_data;
const char *canonical = p.name ?: name;
size_t alen = FAMILY_ADDRESS_SIZE(af);
@@ -648,7 +654,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
r = sd_json_dispatch(rparams, resolve_address_reply_dispatch_table, nss_json_dispatch_flags, &p);
if (r < 0)
goto fail;
if (sd_json_variant_is_blank_object(p.names))
if (sd_json_variant_is_blank_array(p.names))
goto not_found;
size_t ms = 0, idx;