[PATCH ulogd2 2/6] db, IP2BIN: correct `format_ipv6()` output buffer sizes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



`format_ipv6()` formats IPv6 addresses as hex-strings.  However, sizing for the
output buffer is not done quite right.

`format_ipv6()` itself uses the size of `struct in6_addr` to verify that the
buffer size is large enough, and the output buffer for the call in util/db.c is
sized the same way.  However, the size that should be used is that of the
`s6_addr` member of `struct in6_addr`, not that of the whole structure.

The elements of the `ipbin_array` array in ulogd_filter_IP2BIN.c are sized using
a local macro, `IPADDR_LENGTH`, which is defined as 128, the number of bits in
an IPv6 address; this is much larger than necessary.

Define an appropriate macro and use that instead.

Signed-off-by: Jeremy Sowden <jeremy@xxxxxxxxxx>
---
 filter/ulogd_filter_IP2BIN.c |  6 ++----
 include/ulogd/ulogd.h        | 13 +++++++++++--
 util/db.c                    |  2 +-
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/filter/ulogd_filter_IP2BIN.c b/filter/ulogd_filter_IP2BIN.c
index 7f7bea5071a7..f1ca4eee7d76 100644
--- a/filter/ulogd_filter_IP2BIN.c
+++ b/filter/ulogd_filter_IP2BIN.c
@@ -28,8 +28,6 @@
 #include <ulogd/ulogd.h>
 #include <netinet/if_ether.h>
 
-#define IPADDR_LENGTH 128
-
 enum input_keys {
 	KEY_OOB_FAMILY,
 	KEY_OOB_PROTOCOL,
@@ -114,7 +112,7 @@ static struct ulogd_key ip2bin_keys[] = {
 
 };
 
-static char ipbin_array[MAX_KEY - START_KEY + 1][IPADDR_LENGTH];
+static char ipbin_array[MAX_KEY - START_KEY + 1][FORMAT_IPV6_BUFSZ];
 
 static int ip2bin(struct ulogd_key *inp, int index, int oindex)
 {
@@ -161,7 +159,7 @@ static int ip2bin(struct ulogd_key *inp, int index, int oindex)
 			return ULOGD_IRET_ERR;
 	}
 
-	format_ipv6(ipbin_array[oindex], IPADDR_LENGTH, addr);
+	format_ipv6(ipbin_array[oindex], sizeof(ipbin_array[oindex]), addr);
 
 	return ULOGD_IRET_OK;
 }
diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
index 5eafb21f9cfe..5b6134d94ea3 100644
--- a/include/ulogd/ulogd.h
+++ b/include/ulogd/ulogd.h
@@ -23,6 +23,15 @@
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
+/*
+ * Minimum size of buffer required to hold an ipv6 address encoded as a
+ * hex-string, e.g.:
+ *
+ *                          ::1 -> "0x00000000000000000000000000000001"
+ * 2600:1408:ec00:36::1736:7f28 -> "0x26001408ec0000360000000017367f28"
+ */
+#define FORMAT_IPV6_BUFSZ (2 + sizeof(((struct in6_addr) {}).s6_addr) * 2 + 1)
+
 /* All types with MSB = 1 make use of value.ptr
  * other types use one of the union's member */
 
@@ -233,11 +242,11 @@ format_ipv6(char *buf, size_t size, const struct in6_addr *ipv6)
 {
 	unsigned i = 0;
 
-	if (size > 2 + sizeof (*ipv6) * 2) {
+	if (size >= FORMAT_IPV6_BUFSZ) {
 		buf[i++] = '0';
 		buf[i++] = 'x';
 
-		for (unsigned j = 0; i < sizeof(*ipv6); j += 4, i += 8) {
+		for (unsigned j = 0; i < sizeof(ipv6->s6_addr); j += 4, i += 8) {
 			sprintf(buf + i, "%02hhx%02hhx%02hhx%02hhx",
 				ipv6->s6_addr[j + 0],
 				ipv6->s6_addr[j + 1],
diff --git a/util/db.c b/util/db.c
index 11c3e6ad8454..69f4290f5c87 100644
--- a/util/db.c
+++ b/util/db.c
@@ -370,7 +370,7 @@ static void __format_query_db(struct ulogd_pluginstance *upi, char *start)
 				sprintf(stmt_ins, "%u,", res->u.value.ui32);
 			else {
 				struct in6_addr ipv6;
-				char addrbuf[2 + sizeof(ipv6) * 2  + 1];
+				char addrbuf[FORMAT_IPV6_BUFSZ];
 
 				memcpy(ipv6.s6_addr, res->u.value.ui128,
 				       sizeof(ipv6.s6_addr));
-- 
2.47.2





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux