New: Funcation tcp_v6_md5_do_del return has error.
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): [email protected]/
Quoted 60 lines · On Tue, 20 Nov 2007 07:13:00 -0800 (PST) [email protected] wrote:
http://bugzilla.kernel.org/show_bug.cgi?id=9418
Summary: Funcation tcp_v6_md5_do_del return has error. Product: Networking Version: 2.5 KernelVersion: 2.6.23 Platform: All OS/Version: Linux Tree: Mainline Status: NEW Severity: normal Priority: P1 Component: IPV6 AssignedTo: [email protected] ReportedBy: [email protected]Most recent kernel where this bug did not occur:
None, I always had this problem with the md5 in tcpv6. Distribution:
Hardware Environment:
Software Environment:
Problem Description:
When you creat two or more tcpv6 md5 entries,and you may del someone.For example, if you added two ipv6address(2000::9, 2000::10)to a sk, so the sk first md5 entry is for 2000::9 and second entry is for 2000::10, and then the sk has two entries. If you want to del the second md5 entry , the funcation "tcp_v6_md5_do_del" will not sub thetp->md5sig_info->entries6for the first loop, because this time the address is not 2000::9.For the second loop, thetp->md5sig_info->entries6will sub 1,but this timetp->md5sig_info->entries6is not 0 but 1, so the funcation return -ENOENT.When application get the return vlaue may occur error.for (i = 0; i < tp->md5sig_info->entries6; i++) { if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { /* Free the key */ kfree(tp->md5sig_info->keys6[i].base.key); tp->md5sig_info->entries6--; if (tp->md5sig_info->entries6 == 0) { kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; tp->md5sig_info->alloced6 = 0; tcp_free_md5sig_pool(); /*return 0;*/ /*not in here*/ } else { /* shrink the database */ if (tp->md5sig_info->entries6 != i) memmove(&tp->md5sig_info->keys6[i], &tp->md5sig_info->keys6[i+1], (tp->md5sig_info->entries6 - i) * sizeof (tp->md5sig_info->keys6[0])); } } return 0;/*should be return here*/ }
Quoted 3 lines
Steps to reproduce:
Create two tcpv6 md5 entry ,and then delete the second.
and
Quoted 34 lines
I have a mistake. The code shoule be :
static inttcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer){ struct tcp_sock *tp = tcp_sk(sk); int i; for (i = 0; i < tp->md5sig_info->entries6; i++) { if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { /* Free the key */ kfree(tp->md5sig_info->keys6[i].base.key); tp->md5sig_info->entries6--; if (tp->md5sig_info->entries6 == 0) { kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; tp->md5sig_info->alloced6 = 0; /*tcp_free_md5sig_pool();*/ /*this also wrong*/ /*return 0;*/ /*not in here*/ } else { /* shrink the database */ if (tp->md5sig_info->entries6 != i) memmove(&tp->md5sig_info->keys6[i], &tp->md5sig_info->keys6[i+1], (tp->md5sig_info->entries6 - i) * sizeof (tp->md5sig_info->keys6[0])); } tcp_free_md5sig_pool(); /*should be put here*/ return 0; /*should be return here*/ } } return -ENOENT; }
David Miller
maintainerYoshifuji just posted 4 patches which together should fix this one, I'll add them to my net-2.6 tree.
Thanks.