[PATCH 1/4] check nfct_get_attr()!=NULL

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

 



from time to time, conntrackd segfaults in cache.c, function hash(),
because it does not check the return value of nfct_get_attr().  For
some reason (which I have not investigated), there is no
ATTR_ORIG_IPV4_SRC.  A gdb dump of *ct after the segfault says the
following:

(gdb) p *ct
$3 = {tuple = {{src = {v4 = 4161143072, v6 = {in6_u = {u6_addr8 = " \001\006ø\023\205\000\001\000\000\000\000\000\000\000\002",
            u6_addr16 = {288, 63494, 34067, 256, 0, 0, 0, 512}, u6_addr32 = {4161143072, 16811283, 0, 33554432}}}}, dst = {
        v4 = 4161143072, v6 = {in6_u = {u6_addr8 = " \001\006ø\023\205ÿÿÿÿÿÿÿÿ\000\002", u6_addr16 = {288, 63494, 34067, 65535,
              65535, 65535, 65535, 512}, u6_addr32 = {4161143072, 4294935827, 4294967295, 33619967}}}}, l3protonum = 10 '\n',
      protonum = 6 '\006', l4src = {all = 64727, tcp = {port = 64727}, udp = {port = 64727}, icmp = {type = 215 '×',
          code = 252 'ü', id = 0}, sctp = {port = 64727}}, l4dst = {all = 53767, tcp = {port = 53767}, udp = {port = 53767},
        icmp = {type = 7 '\a', code = 210 'Ò', id = 0}, sctp = {port = 53767}}}, {src = {v4 = 4161143072, v6 = {in6_u = {
            u6_addr8 = " \001\006ø\023\205ÿÿÿÿÿÿÿÿ\000\002", u6_addr16 = {288, 63494, 34067, 65535, 65535, 65535, 65535, 512},
            u6_addr32 = {4161143072, 4294935827, 4294967295, 33619967}}}}, dst = {v4 = 4161143072, v6 = {in6_u = {
            u6_addr8 = " \001\006ø\023\205\000\001\000\000\000\000\000\000\000\002", u6_addr16 = {288, 63494, 34067, 256, 0, 0,
              0, 512}, u6_addr32 = {4161143072, 16811283, 0, 33554432}}}}, l3protonum = 10 '\n', protonum = 6 '\006', l4src = {
        all = 53767, tcp = {port = 53767}, udp = {port = 53767}, icmp = {type = 7 '\a', code = 210 'Ò', id = 0}, sctp = {
          port = 53767}}, l4dst = {all = 64727, tcp = {port = 64727}, udp = {port = 64727}, icmp = {type = 215 '×',
          code = 252 'ü', id = 0}, sctp = {port = 64727}}}, {src = {v4 = 0, v6 = {in6_u = {u6_addr8 = '\0' <repeats 15 times>,
            u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, u6_addr32 = {0, 0, 0, 0}}}}, dst = {v4 = 0, v6 = {in6_u = {
            u6_addr8 = '\0' <repeats 15 times>, u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, u6_addr32 = {0, 0, 0, 0}}}},
      l3protonum = 0 '\0', protonum = 0 '\0', l4src = {all = 0, tcp = {port = 0}, udp = {port = 0}, icmp = {type = 0 '\0',
          code = 0 '\0', id = 0}, sctp = {port = 0}}, l4dst = {all = 0, tcp = {port = 0}, udp = {port = 0}, icmp = {
          type = 0 '\0', code = 0 '\0', id = 0}, sctp = {port = 0}}}}, timeout = 120, mark = 0, secmark = 0, status = 8, use = 0,
  id = 0, protoinfo = {tcp = {state = 1 '\001', flags = {{value = 3 '\003', mask = 0 '\0'}, {value = 0 '\0', mask = 0 '\0'}, {
          value = 0 '\0', mask = 0 '\0'}}}}, counters = {{packets = 0, bytes = 0}, {packets = 0, bytes = 0}, {packets = 0,
      bytes = 0}}, snat = {min_ip = 0, max_ip = 0, l4min = {all = 0, tcp = {port = 0}, udp = {port = 0}, icmp = {type = 0 '\0',
        code = 0 '\0', id = 0}, sctp = {port = 0}}, l4max = {all = 0, tcp = {port = 0}, udp = {port = 0}, icmp = {type = 0 '\0',
        code = 0 '\0', id = 0}, sctp = {port = 0}}}, dnat = {min_ip = 0, max_ip = 0, l4min = {all = 0, tcp = {port = 0}, udp = {
        port = 0}, icmp = {type = 0 '\0', code = 0 '\0', id = 0}, sctp = {port = 0}}, l4max = {all = 0, tcp = {port = 0}, udp = {
        port = 0}, icmp = {type = 0 '\0', code = 0 '\0', id = 0}, sctp = {port = 0}}}, set = {1019888, 31}}
---

 src/cache.c |   46 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 32 insertions(+), 14 deletions(-)


diff --git a/src/cache.c b/src/cache.c
index 2f0e57a..d0fb210 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -29,17 +29,26 @@
 
 static uint32_t hash(const void *data, struct hashtable *table)
 {
+	const void *p;
 	unsigned int a, b;
 	const struct us_conntrack *u = data;
 	struct nf_conntrack *ct = u->ct;
 
-	a = jhash(nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC), sizeof(uint32_t),
-		  ((nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16) |
-		   (nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO))));
-
-	b = jhash(nfct_get_attr(ct, ATTR_ORIG_IPV4_DST), sizeof(uint32_t),
-		  ((nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16) |
-		   (nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST))));
+	p = nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC);
+	if (p == NULL)
+		a = 0;
+	else
+		a = jhash(p, sizeof(uint32_t),
+			  ((nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16) |
+			   (nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO))));
+
+	p = nfct_get_attr(ct, ATTR_ORIG_IPV4_DST);
+	if (p == NULL)
+		b = 0;
+	else
+		b = jhash(p, sizeof(uint32_t),
+			  ((nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16) |
+			   (nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST))));
 
 	/*
 	 * Instead of returning hash % table->hashsize (implying a divide)
@@ -53,17 +62,26 @@ static uint32_t hash(const void *data, struct hashtable *table)
 
 static uint32_t hash6(const void *data, struct hashtable *table)
 {
+	const void *p;
 	unsigned int a, b;
 	const struct us_conntrack *u = data;
 	struct nf_conntrack *ct = u->ct;
 
-	a = jhash(nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC), sizeof(uint32_t)*4,
-		  ((nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16) |
-		   (nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO))));
-
-	b = jhash(nfct_get_attr(ct, ATTR_ORIG_IPV6_DST), sizeof(uint32_t)*4,
-		  ((nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16) |
-		   (nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST))));
+	p = nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC);
+	if (p == NULL)
+		a = 0;
+	else
+		a = jhash(p, sizeof(uint32_t)*4,
+			  ((nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16) |
+			   (nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO))));
+
+	p = nfct_get_attr(ct, ATTR_ORIG_IPV6_DST);
+	if (p == NULL)
+		b = 0;
+	else
+		b = jhash(nfct_get_attr(ct, ATTR_ORIG_IPV6_DST), sizeof(uint32_t)*4,
+			  ((nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16) |
+			   (nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST))));
 
 	return ((uint64_t)jhash_2words(a, b, 0) * table->hashsize) >> 32;
 }


-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux