From: Tom Lane <tgl@sss.pgh.pa.us>
To: petervandivier@gmail.com
Cc: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #16695: pg_hba_file_rules NULL address and netmask
Date: Mon, 02 Nov 2020 20:27:38 -0500
Message-ID: <871849.1604366858@sss.pgh.pa.us> (raw)
In-Reply-To: <832503.1604361320@sss.pgh.pa.us>
References: <16695-a665558e2f630be7@postgresql.org>
<832503.1604361320@sss.pgh.pa.us>
I wrote:
> PG Bug reporting form <noreply@postgresql.org> writes:
>> pg_hba_file_rules reports NULL address and netmask values incorrectly on
>> FreeBSD 11 for tested postgres versions 10-13 (at least). e.g.
> So for the archives' sake: what I suppose Peter means is that the addr
> and netmask come out as NULL on every line, even where they should not.
> At least, that's what I've reproduced here on FreeBSD 11.0.
> I traced through this, and the proximate cause seems to be that
> getnameinfo(3) is failing because it is expecting the passed "salen"
> to be exactly the length it is expecting for the given sa_family.
> Which it is not, because alone among our callers of pg_getnameinfo_all(),
> fill_hba_line() thinks it can get away with passing sizeof(struct
> sockaddr_storage) rather than the actual addrlen previously returned by
> getaddrinfo().
The attached seems to fix it for me. (This is against HEAD, but a quick
check suggests it will apply cleanly down to v10.) As I mentioned,
I'm planning to put the new fields at the end of struct HbaLine in
the back branches.
regards, tom lane
Attachments:fix-bogus-addrlen-in-hba-view.patch (text/x-diff, 3.1K) downloaddiff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.cindex 4c86fb6087..3a78d2043e 100644--- a/src/backend/libpq/hba.c+++ b/src/backend/libpq/hba.c@@ -1188,8 +1188,11 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
ret = pg_getaddrinfo_all(str, NULL, &hints, &gai_result);
if (ret == 0 && gai_result)
+ {
memcpy(&parsedline->addr, gai_result->ai_addr,
gai_result->ai_addrlen);
+ parsedline->addrlen = gai_result->ai_addrlen;+ }
else if (ret == EAI_NONAME)
parsedline->hostname = str;
else
@@ -1238,6 +1241,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
token->string);
return NULL;
}
+ parsedline->masklen = parsedline->addrlen;
pfree(str);
}
else if (!parsedline->hostname)
@@ -1288,6 +1292,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
memcpy(&parsedline->mask, gai_result->ai_addr,
gai_result->ai_addrlen);
+ parsedline->masklen = gai_result->ai_addrlen;
pg_freeaddrinfo_all(hints.ai_family, gai_result);
if (parsedline->addr.ss_family != parsedline->mask.ss_family)
@@ -2538,20 +2543,26 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
}
else
{
- if (pg_getnameinfo_all(&hba->addr, sizeof(hba->addr),- buffer, sizeof(buffer),- NULL, 0,- NI_NUMERICHOST) == 0)+ /*+ * Note: if pg_getnameinfo_all fails, it'll set buffer to+ * "???", which we want to return.+ */+ if (hba->addrlen > 0)
{
- clean_ipv6_addr(hba->addr.ss_family, buffer);+ if (pg_getnameinfo_all(&hba->addr, hba->addrlen,+ buffer, sizeof(buffer),+ NULL, 0,+ NI_NUMERICHOST) == 0)+ clean_ipv6_addr(hba->addr.ss_family, buffer);
addrstr = pstrdup(buffer);
}
- if (pg_getnameinfo_all(&hba->mask, sizeof(hba->mask),- buffer, sizeof(buffer),- NULL, 0,- NI_NUMERICHOST) == 0)+ if (hba->masklen > 0)
{
- clean_ipv6_addr(hba->mask.ss_family, buffer);+ if (pg_getnameinfo_all(&hba->mask, hba->masklen,+ buffer, sizeof(buffer),+ NULL, 0,+ NI_NUMERICHOST) == 0)+ clean_ipv6_addr(hba->mask.ss_family, buffer);
maskstr = pstrdup(buffer);
}
}
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.hindex d638479d88..8f09b5638f 100644--- a/src/include/libpq/hba.h+++ b/src/include/libpq/hba.h@@ -42,6 +42,10 @@ typedef enum UserAuth
#define USER_AUTH_LAST uaPeer /* Must be last value of this enum */
} UserAuth;
+/*+ * Data structures representing pg_hba.conf entries+ */+
typedef enum IPCompareMethod
{
ipCmpMask,
@@ -75,11 +79,12 @@ typedef struct HbaLine
List *databases;
List *roles;
struct sockaddr_storage addr;
+ int addrlen; /* zero if we don't have a valid addr */
struct sockaddr_storage mask;
+ int masklen; /* zero if we don't have a valid mask */
IPCompareMethod ip_cmp_method;
char *hostname;
UserAuth auth_method;
-
char *usermap;
char *pamservice;
bool pam_use_hostname;
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: tgl@sss.pgh.pa.us, petervandivier@gmail.com, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #16695: pg_hba_file_rules NULL address and netmask
In-Reply-To: <871849.1604366858@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox