Page MenuHomeFreeBSD

D53491.diff
No OneTemporary

D53491.diff

diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c
--- a/lib/libc/inet/inet_net_pton.c
+++ b/lib/libc/inet/inet_net_pton.c
@@ -211,15 +211,18 @@
static int
inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
{
- struct in6_addr in6;
int ret;
int bits;
- size_t bytes;
char buf[INET6_ADDRSTRLEN + sizeof("/128")];
char *sep;
const char *errstr;
- if (strlcpy(buf, src, sizeof buf) >= sizeof buf) {
+ if (size < sizeof(struct in6_addr)) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+
+ if (strlcpy(buf, src, sizeof(buf)) >= sizeof(buf)) {
errno = EMSGSIZE;
return (-1);
}
@@ -228,7 +231,7 @@
if (sep != NULL)
*sep++ = '\0';
- ret = inet_pton(AF_INET6, buf, &in6);
+ ret = inet_pton(AF_INET6, buf, dst);
if (ret != 1)
return (-1);
@@ -242,12 +245,6 @@
}
}
- bytes = (bits + 7) / 8;
- if (bytes > size) {
- errno = EMSGSIZE;
- return (-1);
- }
- memcpy(dst, &in6.s6_addr, bytes);
return (bits);
}
diff --git a/lib/libc/tests/net/inet_net_test.cc b/lib/libc/tests/net/inet_net_test.cc
--- a/lib/libc/tests/net/inet_net_test.cc
+++ b/lib/libc/tests/net/inet_net_test.cc
@@ -153,12 +153,11 @@
// A prefix with an infix ::.
{ "2001:db8::1/128", 128, "2001:db8::1/128" },
- // A prefix with bits set which are outside the prefix;
- // these should be silently ignored.
- { "2001:db8:1:1:1:1:1:1/32", 32, "2001:db8::/32" },
+ // A prefix with bits set which are outside the prefix.
+ { "2001:db8:1:1:1:1:1:1/32", 32, "2001:db8:1:1:1:1:1:1/32" },
// As above but with infix ::.
- { "2001:db8::1/32", 32, "2001:db8::/32" },
+ { "2001:db8::1/32", 32, "2001:db8::1/32" },
// A prefix with only ::, commonly used to represent the
// entire address space.
@@ -182,11 +181,13 @@
{ "2001:db8::1", 128, "2001:db8::1/128" },
// Test vectors provided in PR bin/289198.
- { "fe80::1/64", 64, "fe80::/64" },
+ { "fe80::1/64", 64, "fe80::1/64" },
{ "fe80::f000:74ff:fe54:bed2/64",
- 64, "fe80::/64" },
+ 64,
+ "fe80::f000:74ff:fe54:bed2/64" },
{ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64",
- 64, "ffff:ffff:ffff:ffff::/64" },
+ 64,
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64" },
{ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128,
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" },
};
@@ -324,10 +325,48 @@
ATF_REQUIRE_EQ(ret, nullptr);
}
+ATF_TEST_CASE_WITHOUT_HEAD(inet_net_pton4_zero)
+ATF_TEST_CASE_BODY(inet_net_pton4_zero)
+{
+ /*
+ * Ensure inet_net_pton() zeroes the address before returning it.
+ */
+ auto addr = in_addr{};
+
+ std::memset(&addr, 0xFF, sizeof(addr));
+ auto bits = inet_net_pton(AF_INET, "10/8", &addr, sizeof(addr));
+ ATF_REQUIRE(bits == 8);
+
+ auto buf = std::vector<char>(INET_ADDRSTRLEN + 3 + 1);
+ auto p = inet_net_ntop(AF_INET, &addr, bits, buf.data(), buf.size());
+ ATF_REQUIRE(p != nullptr);
+ ATF_REQUIRE_EQ("10/8"s, p);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(inet_net_pton6_zero)
+ATF_TEST_CASE_BODY(inet_net_pton6_zero)
+{
+ /*
+ * Ensure inet_net_pton() zeroes the address before returning it.
+ */
+ auto addr = in6_addr{};
+
+ std::memset(&addr, 0xFF, sizeof(addr));
+ auto bits = inet_net_pton(AF_INET6, "2001:db8::/32", &addr, sizeof(addr));
+ ATF_REQUIRE(bits == 32);
+
+ auto buf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1);
+ auto p = inet_net_ntop(AF_INET6, &addr, bits, buf.data(), buf.size());
+ ATF_REQUIRE(p != nullptr);
+ ATF_REQUIRE_EQ("2001:db8::/32"s, p);
+}
+
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, inet_net_inet4);
ATF_ADD_TEST_CASE(tcs, inet_net_inet6);
+ ATF_ADD_TEST_CASE(tcs, inet_net_pton4_zero);
+ ATF_ADD_TEST_CASE(tcs, inet_net_pton6_zero);
ATF_ADD_TEST_CASE(tcs, inet_net_pton_invalid);
ATF_ADD_TEST_CASE(tcs, inet_net_ntop_invalid);
}

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 29, 5:16 PM (1 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28086905
Default Alt Text
D53491.diff (3 KB)

Event Timeline