aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-01-30 17:24:29 -0500
committerDavid S. Miller <davem@davemloft.net>2007-01-30 17:24:29 -0500
commitfb74a8416022c033e1a950689c264c453f8f98d8 (patch)
tree24ec91647e5a1356afda6d85a13be8bff1b74912
parent24a1dec55073000264f2da6278baef759929a14f (diff)
[NETFILTER]: xt_connbytes: fix division by zero
When the packet counter of a connection is zero a division by zero occurs in div64_64(). Fix that by using zero as average value, which is correct as long as the packet counter didn't overflow, at which point we have lost anyway. Additionally we're probably going to go back to 64 bit counters in 2.6.21. Based on patch from Jonas Berlin <xkr47@outerspace.dyndns.org>, with suggestions from KOVACS Krisztian <hidden@balabit.hu>. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/netfilter/xt_connbytes.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index d93cb096a675..5e32dfa2668b 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -52,6 +52,8 @@ match(const struct sk_buff *skb,
52{ 52{
53 const struct xt_connbytes_info *sinfo = matchinfo; 53 const struct xt_connbytes_info *sinfo = matchinfo;
54 u_int64_t what = 0; /* initialize to make gcc happy */ 54 u_int64_t what = 0; /* initialize to make gcc happy */
55 u_int64_t bytes = 0;
56 u_int64_t pkts = 0;
55 const struct ip_conntrack_counter *counters; 57 const struct ip_conntrack_counter *counters;
56 58
57 if (!(counters = nf_ct_get_counters(skb))) 59 if (!(counters = nf_ct_get_counters(skb)))
@@ -89,29 +91,22 @@ match(const struct sk_buff *skb,
89 case XT_CONNBYTES_AVGPKT: 91 case XT_CONNBYTES_AVGPKT:
90 switch (sinfo->direction) { 92 switch (sinfo->direction) {
91 case XT_CONNBYTES_DIR_ORIGINAL: 93 case XT_CONNBYTES_DIR_ORIGINAL:
92 what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, 94 bytes = counters[IP_CT_DIR_ORIGINAL].bytes;
93 counters[IP_CT_DIR_ORIGINAL].packets); 95 pkts = counters[IP_CT_DIR_ORIGINAL].packets;
94 break; 96 break;
95 case XT_CONNBYTES_DIR_REPLY: 97 case XT_CONNBYTES_DIR_REPLY:
96 what = div64_64(counters[IP_CT_DIR_REPLY].bytes, 98 bytes = counters[IP_CT_DIR_REPLY].bytes;
97 counters[IP_CT_DIR_REPLY].packets); 99 pkts = counters[IP_CT_DIR_REPLY].packets;
98 break; 100 break;
99 case XT_CONNBYTES_DIR_BOTH: 101 case XT_CONNBYTES_DIR_BOTH:
100 { 102 bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
101 u_int64_t bytes; 103 counters[IP_CT_DIR_REPLY].bytes;
102 u_int64_t pkts; 104 pkts = counters[IP_CT_DIR_ORIGINAL].packets +
103 bytes = counters[IP_CT_DIR_ORIGINAL].bytes + 105 counters[IP_CT_DIR_REPLY].packets;
104 counters[IP_CT_DIR_REPLY].bytes;
105 pkts = counters[IP_CT_DIR_ORIGINAL].packets+
106 counters[IP_CT_DIR_REPLY].packets;
107
108 /* FIXME_THEORETICAL: what to do if sum
109 * overflows ? */
110
111 what = div64_64(bytes, pkts);
112 }
113 break; 106 break;
114 } 107 }
108 if (pkts != 0)
109 what = div64_64(bytes, pkts);
115 break; 110 break;
116 } 111 }
117 112