Skip to content

nss-resolve: fix blank check using is_blank_object instead of is_blank_array#42610

Merged
yuwata merged 1 commit into
systemd:mainfrom
lionheartyu:fix/nss-resolve-blank-array-check
Jun 25, 2026
Merged

nss-resolve: fix blank check using is_blank_object instead of is_blank_array#42610
yuwata merged 1 commit into
systemd:mainfrom
lionheartyu:fix/nss-resolve-blank-array-check

Conversation

@lionheartyu

@lionheartyu lionheartyu commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions github-actions Bot added resolve please-review PR is ready for (re-)review by a maintainer labels Jun 16, 2026
@lionheartyu lionheartyu changed the title nss-resolve: fix blank check using is_blank_object instead of is_blan… nss-resolve: fix blank check using is_blank_object instead of is_blank_array Jun 16, 2026
@yuwata yuwata added good-to-merge/waiting-for-ci 👍 PR is good to merge, but CI hasn't passed at time of review. Please merge if you see CI has passed and removed please-review PR is ready for (re-)review by a maintainer labels Jun 16, 2026
@lionheartyu lionheartyu force-pushed the fix/nss-resolve-blank-array-check branch from bc2143c to bf19f79 Compare June 16, 2026 02:25
@lionheartyu

Copy link
Copy Markdown
Contributor Author

@yuwata I initially only fixed the p.names check at line 651. After further review, the same bug exists for p.addresses at lines 267 and 432— both fields are declared as SD_JSON_VARIANT_ARRAY in the dispatch table, so the same is_blank_object → is_blank_array fix applies. I've updated the commit to include all three callsites.

@lionheartyu lionheartyu requested a review from yuwata June 16, 2026 02:29
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

Claude review of PR #42610 (9fc9b4c)

The core fix is correct and complete: sd_json_variant_is_blank_array() returns true for NULL/JSON-null/empty-array and matches the SD_JSON_VARIANT_ARRAY declarations of addresses and names, so the empty-[] case that slipped past is_blank_object() is now diverted to not_found/no_data. All three (and only three) affected callsites are converted, and the r_aliases[n_names-1] underflow is fully resolved. Two maintainer approvals already on record.

All robustness and h_errno-consistency gaps raised in earlier review rounds are now addressed: the added if (n_addresses == 0) guards in gethostbyname4_r/gethostbyname3_r close the all-filtered NULL-deref, and the gethostbyname3_r blank-array guard now routes to no_data, so both of its zero-result paths report NO_DATA consistently.

Suggestions

  • gethostbyname4_r still NULL-derefs on all-filtered addressessrc/nss-resolve/nss-resolve.c:267 — non-empty array with no AF_INET/AF_INET6 entries passes the guard but yields n_addresses==0, leaving r_tuple NULL at the assert / r_tuple->next write.
  • gethostbyname3_r blank-array path still returns HOST_NOT_FOUNDsrc/nss-resolve/nss-resolve.c:435 — changing line 458 to NO_DATA left the sibling blank-array guard at HOST_NOT_FOUND; for a family-specific query both conditions mean "name resolved, no record of this family", so this case should also goto no_data for consistency.

Nits

  • gethostbyname3_r returns SUCCESS with zero addressessrc/nss-resolve/nss-resolve.c:432 — same all-filtered pattern; harmless but returns NSS_STATUS_SUCCESS with an empty list instead of NSS_STATUS_NOTFOUND.
  • gethostbyname3_r NOTFOUND uses HOST_NOT_FOUND not NO_DATAsrc/nss-resolve/nss-resolve.c:458 — for the all-filtered case the name resolved but has no record of the requested family; the gethostby* contract classifies that as NO_DATA/NO_ADDRESS rather than HOST_NOT_FOUND. Consistent with the pre-existing empty-array handling, not a regression.
  • Early blank-array check now redundant with the n_addresses==0 guardsrc/nss-resolve/nss-resolve.c:290 — in gethostbyname4_r (and gethostbyname3_r at line 458) the early is_blank_array check targets the same label as the new post-loop guard, so it is technically redundant; optional cleanup, keeping it for symmetry with gethostbyaddr2_r is equally fine.

Workflow run

Comment thread src/nss-resolve/nss-resolve.c
Comment thread src/nss-resolve/nss-resolve.c
@bluca bluca added reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks and removed good-to-merge/waiting-for-ci 👍 PR is good to merge, but CI hasn't passed at time of review. Please merge if you see CI has passed labels Jun 16, 2026
@lionheartyu lionheartyu force-pushed the fix/nss-resolve-blank-array-check branch from bf19f79 to de6ae11 Compare June 16, 2026 11:54
@lionheartyu

Copy link
Copy Markdown
Contributor Author

@bluca Done, added if (n_addresses == 0) goto not_found; after the counting loop in both gethostbyname4_r and gethostbyname3_r paths. Thank you for the review!

@daandemeyer daandemeyer added good-to-merge/waiting-for-ci 👍 PR is good to merge, but CI hasn't passed at time of review. Please merge if you see CI has passed and removed reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels Jun 16, 2026

@yuwata yuwata left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! LGTM.

Comment thread src/nss-resolve/nss-resolve.c Outdated
@bluca bluca added good-to-merge/after-next-release and removed good-to-merge/waiting-for-ci 👍 PR is good to merge, but CI hasn't passed at time of review. Please merge if you see CI has passed labels Jun 16, 2026
@lionheartyu lionheartyu force-pushed the fix/nss-resolve-blank-array-check branch from de6ae11 to 10b499a Compare June 22, 2026 01:01
Comment thread src/nss-resolve/nss-resolve.c
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>
@lionheartyu lionheartyu force-pushed the fix/nss-resolve-blank-array-check branch from 10b499a to 9fc9b4c Compare June 22, 2026 01:14
Comment thread src/nss-resolve/nss-resolve.c
@lionheartyu

Copy link
Copy Markdown
Contributor Author

Completed. Please review.

@yuwata yuwata merged commit dc5c099 into systemd:main Jun 25, 2026
67 of 68 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants