summaryrefslogtreecommitdiff
path: root/src/nss-resolve
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-03-31 16:20:30 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-03-31 16:28:14 +0200
commit77fac974fe396dbe4fb679b748bfa89db1136e0c (patch)
tree44c18c114d13d026bc5faafbe467d5010c63baff /src/nss-resolve
parent907952bbc92dd6656807d9b2eb0d0c94a4c9e865 (diff)
downloadsystemd-77fac974fe396dbe4fb679b748bfa89db1136e0c.tar.gz
nss-resolve: fix parsing of io.systemd.Resolve.ResolveAddress reply
Since the switch to varlink in 0c73f4f075a2d23f7cabe708b589f19f4bbbec37, the code wasn't functional. The JSON_VARIANT_UNSIGNED/JSON_VARIANT_STRING mismatch meant that we'd reject any reply. Once past that, the code would use unitialized 'c' and 'n' variables, so it's lucky we never got that far ;) With -Wmaybe-unitialized, gcc would warn. I think that declaring the huge list of local variables with very short names at the top of the function was making it harder to understand what is going on in the function. So let's rename the variables a bit, and initialize them upon declaration if possible. $ build/test-nss-hosts resolve 1.1.1.1 1.0.0.1 10.38.5.41 ======== resolve ======== _nss_resolve_gethostbyaddr2_r("1.1.1.1") → status=NSS_STATUS_SUCCESS errno=999/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "one.one.one.one" AF_INET 1.1.1.1 _nss_resolve_gethostbyaddr_r("1.1.1.1") → status=NSS_STATUS_SUCCESS errno=999/--- h_errno=0/Resolver Error 0 (no error) "one.one.one.one" AF_INET 1.1.1.1 _nss_resolve_gethostbyaddr2_r("1.0.0.1") → status=NSS_STATUS_SUCCESS errno=999/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "one.one.one.one" AF_INET 1.0.0.1 _nss_resolve_gethostbyaddr_r("1.0.0.1") → status=NSS_STATUS_SUCCESS errno=999/--- h_errno=0/Resolver Error 0 (no error) "one.one.one.one" AF_INET 1.0.0.1 _nss_resolve_gethostbyaddr2_r("10.38.5.41") → status=NSS_STATUS_SUCCESS errno=999/--- h_errno=0/Resolver Error 0 (no error) ttl=0 "squid.redhat.com" alias "squid.corp.redhat.com" alias "squid2.corp.redhat.com" alias "squid3.corp.redhat.com" alias "squid4.corp.redhat.com" alias "squid5.corp.redhat.com" AF_INET 10.38.5.41 _nss_resolve_gethostbyaddr_r("10.38.5.41") → status=NSS_STATUS_SUCCESS errno=999/--- h_errno=0/Resolver Error 0 (no error) "squid.redhat.com" alias "squid.corp.redhat.com" alias "squid2.corp.redhat.com" alias "squid3.corp.redhat.com" alias "squid4.corp.redhat.com" alias "squid5.corp.redhat.com" AF_INET 10.38.5.41 (I have 10.38.5.41 squid.redhat.com squid.corp.redhat.com squid2.corp.redhat.com squid3.corp.redhat.com squid4.corp.redhat.com squid5.corp.redhat.com in /etc/hosts for testing.)
Diffstat (limited to 'src/nss-resolve')
-rw-r--r--src/nss-resolve/nss-resolve.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
index dfc0977c84..e5b5079c16 100644
--- a/src/nss-resolve/nss-resolve.c
+++ b/src/nss-resolve/nss-resolve.c
@@ -540,8 +540,8 @@ static void name_parameters_destroy(NameParameters *p) {
}
static const JsonDispatch name_parameters_dispatch_table[] = {
- { "ifindex", JSON_VARIANT_INTEGER, json_dispatch_ifindex, offsetof(NameParameters, ifindex), 0 },
- { "name", JSON_VARIANT_UNSIGNED, json_dispatch_string, offsetof(NameParameters, name), JSON_MANDATORY },
+ { "ifindex", JSON_VARIANT_INTEGER, json_dispatch_ifindex, offsetof(NameParameters, ifindex), 0 },
+ { "name", JSON_VARIANT_STRING, json_dispatch_string, offsetof(NameParameters, name), JSON_MANDATORY },
{}
};
@@ -555,12 +555,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
_cleanup_(resolve_address_reply_destroy) ResolveAddressReply p = {};
_cleanup_(json_variant_unrefp) JsonVariant *cparams = NULL;
- char *r_name, *r_aliases, *r_addr, *r_addr_list;
_cleanup_(varlink_unrefp) Varlink *link = NULL;
- JsonVariant *entry, *rparams;
- const char *n, *error_id;
- unsigned c = 0, i = 0;
- size_t ms = 0, idx;
+ JsonVariant *rparams, *entry;
int r;
PROTECT_ERRNO;
@@ -594,6 +590,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
if (r < 0)
goto fail;
+ const char* error_id;
r = varlink_call(link, "io.systemd.Resolve.ResolveAddress", cparams, &rparams, &error_id, NULL);
if (r < 0)
goto fail;
@@ -609,6 +606,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
if (json_variant_is_blank_object(p.names))
goto not_found;
+ size_t ms = 0, idx;
+
JSON_VARIANT_ARRAY_FOREACH(entry, p.names) {
_cleanup_(name_parameters_destroy) NameParameters q = {};
@@ -619,9 +618,10 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
ms += ALIGN(strlen(q.name) + 1);
}
- ms += ALIGN(len) + /* the address */
- 2 * sizeof(char*) + /* pointers to the address, plus trailing NULL */
- json_variant_elements(p.names) * sizeof(char*); /* pointers to aliases, plus trailing NULL */
+ size_t n_names = json_variant_elements(p.names);
+ ms += ALIGN(len) + /* the address */
+ 2 * sizeof(char*) + /* pointer to the address, plus trailing NULL */
+ n_names * sizeof(char*); /* pointers to aliases, plus trailing NULL */
if (buflen < ms) {
UNPROTECT_ERRNO;
@@ -631,44 +631,43 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
}
/* First, place address */
- r_addr = buffer;
+ char *r_addr = buffer;
memcpy(r_addr, addr, len);
idx = ALIGN(len);
/* Second, place address list */
- r_addr_list = buffer + idx;
+ char *r_addr_list = buffer + idx;
((char**) r_addr_list)[0] = r_addr;
((char**) r_addr_list)[1] = NULL;
idx += sizeof(char*) * 2;
- /* Third, reserve space for the aliases array */
- r_aliases = buffer + idx;
- idx += sizeof(char*) * c;
+ /* Third, reserve space for the aliases array, plus trailing NULL */
+ char *r_aliases = buffer + idx;
+ idx += sizeof(char*) * n_names;
/* Fourth, place aliases */
- i = 0;
- r_name = buffer + idx;
+ char *r_name = buffer + idx;
+
+ size_t i = 0;
JSON_VARIANT_ARRAY_FOREACH(entry, p.names) {
_cleanup_(name_parameters_destroy) NameParameters q = {};
- size_t l;
- char *z;
r = json_dispatch(entry, name_parameters_dispatch_table, NULL, json_dispatch_flags, &q);
if (r < 0)
goto fail;
- l = strlen(q.name);
- z = buffer + idx;
- memcpy(z, n, l+1);
+ size_t l = strlen(q.name);
+ char *z = buffer + idx;
+ memcpy(z, q.name, l + 1);
if (i > 0)
- ((char**) r_aliases)[i-1] = z;
+ ((char**) r_aliases)[i - 1] = z;
i++;
- idx += ALIGN(l+1);
+ idx += ALIGN(l + 1);
}
+ ((char**) r_aliases)[n_names - 1] = NULL;
- ((char**) r_aliases)[c-1] = NULL;
assert(idx == ms);
result->h_name = r_name;