[NETFILTER]: xt_connbytes: fix division by zero after overflow When the packet counter of a connection overflows a division by zero occurs in div64_64(). At that point we can't give calculate accurate values anymore, but at least make sure it doesn't crash. Additionally we're probably going to go back to 64 bit counters in 2.6.21. Based on patch from Jonas Berlin , with suggestions from KOVACS Krisztian . Signed-off-by: Patrick McHardy --- commit 57a227273018d7b507d01a67392a6faa082350e4 tree 01d37699758bd05f483b86ebe56405005c2e27c4 parent 9999a622b03b44e395c8388ff9ab99f99726dce0 author Patrick McHardy Fri, 26 Jan 2007 18:22:35 +0100 committer Patrick McHardy Fri, 26 Jan 2007 18:23:33 +0100 net/netfilter/xt_connbytes.c | 29 ++++++++++++----------------- 1 files changed, 12 insertions(+), 17 deletions(-) diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index d93cb09..6314601 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c @@ -53,6 +53,8 @@ match(const struct sk_buff *skb, const struct xt_connbytes_info *sinfo = matchinfo; u_int64_t what = 0; /* initialize to make gcc happy */ const struct ip_conntrack_counter *counters; + u_int64_t bytes; + u_int64_t pkts; if (!(counters = nf_ct_get_counters(skb))) return 0; /* no match */ @@ -89,29 +91,22 @@ match(const struct sk_buff *skb, case XT_CONNBYTES_AVGPKT: switch (sinfo->direction) { case XT_CONNBYTES_DIR_ORIGINAL: - what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, - counters[IP_CT_DIR_ORIGINAL].packets); + bytes = counters[IP_CT_DIR_ORIGINAL].bytes; + pkts = counters[IP_CT_DIR_ORIGINAL].packets; break; case XT_CONNBYTES_DIR_REPLY: - what = div64_64(counters[IP_CT_DIR_REPLY].bytes, - counters[IP_CT_DIR_REPLY].packets); + bytes = counters[IP_CT_DIR_REPLY].bytes; + pkts = counters[IP_CT_DIR_REPLY].packets; break; case XT_CONNBYTES_DIR_BOTH: - { - u_int64_t bytes; - u_int64_t pkts; - bytes = counters[IP_CT_DIR_ORIGINAL].bytes + - counters[IP_CT_DIR_REPLY].bytes; - pkts = counters[IP_CT_DIR_ORIGINAL].packets+ - counters[IP_CT_DIR_REPLY].packets; - - /* FIXME_THEORETICAL: what to do if sum - * overflows ? */ - - what = div64_64(bytes, pkts); - } + bytes = counters[IP_CT_DIR_ORIGINAL].bytes + + counters[IP_CT_DIR_REPLY].bytes; + pkts = counters[IP_CT_DIR_ORIGINAL].packets + + counters[IP_CT_DIR_REPLY].packets; break; } + if (pkts != 0) + what = div64_64(bytes, pkts); break; }