[NETFILTER]: SNMP NAT: fix memory corruption
Linux Kernel Mailing List <[email protected]> Fri, 26 May 2006 19:59:01 GMT
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
commit 818593c85a382705afd1bcb5570d89a19238fc18 tree 89e410493eb313a19abe1dfc6bd1b3bbb13d8909 parent c9630f474354b2a63e981dfc953e0523ed80870c author Patrick McHardy <[email protected]> Tue, 23 May 2006 15:05:41 -0700 committer David S. Miller <[email protected]> Tue, 23 May 2006 15:05:41 -0700 [NETFILTER]: SNMP NAT: fix memory corruption 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 <[email protected]> Signed-off-by: David S. Miller <[email protected]> net/ipv4/netfilter/ip_nat_snmp_basic.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-) diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index 3ee0477..efc651c 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -996,12 +996,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; } @@ -1119,11 +1119,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 {