--- /dev/null
+From stable-bounces@linux.kernel.org Sat May 20 00:35:28 2006
+Date: Sat, 20 May 2006 09:31:26 +0200
+From: Patrick McHardy <kaber@trash.net>
+To: "David S. Miller" <davem@davemloft.net>
+Cc: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>
+Subject: NETFILTER: SNMP NAT: fix memory corruption (CVE-2006-2444)
+
+CVE-2006-2444 - Potential remote DoS in SNMP NAT helper.
+
+Fix memory corruption caused by snmp_trap_decode:
+
+- When snmp_trap_decode fails before the id and address are allocated,
+ the pointers contain random memory, but are freed by the caller
+ (snmp_parse_mangle).
+
+- When snmp_trap_decode fails after allocating just the ID, it tries
+ to free both address and ID, but the address pointer still contains
+ random memory. The caller frees both ID and random memory again.
+
+- When snmp_trap_decode fails after allocating both, it frees both,
+ and the callers frees both again.
+
+The corruption can be triggered remotely when the ip_nat_snmp_basic
+module is loaded and traffic on port 161 or 162 is NATed.
+
+Found by multiple testcases of the trap-app and trap-enc groups of the
+PROTOS c06-snmpv1 testsuite.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/ipv4/netfilter/ip_nat_snmp_basic.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+--- linux-2.6.16.17.orig/net/ipv4/netfilter/ip_nat_snmp_basic.c
++++ linux-2.6.16.17/net/ipv4/netfilter/ip_nat_snmp_basic.c
+@@ -1000,12 +1000,12 @@ static unsigned char snmp_trap_decode(st
+
+ return 1;
+
++err_addr_free:
++ kfree((unsigned long *)trap->ip_address);
++
+ err_id_free:
+ kfree(trap->id);
+
+-err_addr_free:
+- kfree((unsigned long *)trap->ip_address);
+-
+ return 0;
+ }
+
+@@ -1123,11 +1123,10 @@ static int snmp_parse_mangle(unsigned ch
+ struct snmp_v1_trap trap;
+ unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
+
+- /* Discard trap allocations regardless */
+- kfree(trap.id);
+- kfree((unsigned long *)trap.ip_address);
+-
+- if (!ret)
++ if (ret) {
++ kfree(trap.id);
++ kfree((unsigned long *)trap.ip_address);
++ } else
+ return ret;
+
+ } else {