aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-09-28 18:18:35 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-09-28 18:18:35 -0400
commitf8ab18d2d987a59ccbf0495032b2aef05b730037 (patch)
tree7a24c79632c91e22235888875813950c6c30d929 /net
parente79ad711a0108475c1b3a03815527e7237020b08 (diff)
[TCP]: Fix MD5 signature handling on big-endian.
Based upon a report and initial patch by Peter Lieven. tcp4_md5sig_key and tcp6_md5sig_key need to start with the exact same members as tcp_md5sig_key. Because they are both cast to that type by tcp_v{4,6}_md5_do_lookup(). Unfortunately tcp{4,6}_md5sig_key use a u16 for the key length instead of a u8, which is what tcp_md5sig_key uses. This just so happens to work by accident on little-endian, but on big-endian it doesn't. Instead of casting, just place tcp_md5sig_key as the first member of the address-family specific structures, adjust the access sites, and kill off the ugly casts. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_ipv4.c19
-rw-r--r--net/ipv6/tcp_ipv6.c18
2 files changed, 18 insertions, 19 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 9c94627c8c7e..e089a978e128 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -833,8 +833,7 @@ static struct tcp_md5sig_key *
833 return NULL; 833 return NULL;
834 for (i = 0; i < tp->md5sig_info->entries4; i++) { 834 for (i = 0; i < tp->md5sig_info->entries4; i++) {
835 if (tp->md5sig_info->keys4[i].addr == addr) 835 if (tp->md5sig_info->keys4[i].addr == addr)
836 return (struct tcp_md5sig_key *) 836 return &tp->md5sig_info->keys4[i].base;
837 &tp->md5sig_info->keys4[i];
838 } 837 }
839 return NULL; 838 return NULL;
840} 839}
@@ -865,9 +864,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
865 key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr); 864 key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr);
866 if (key) { 865 if (key) {
867 /* Pre-existing entry - just update that one. */ 866 /* Pre-existing entry - just update that one. */
868 kfree(key->key); 867 kfree(key->base.key);
869 key->key = newkey; 868 key->base.key = newkey;
870 key->keylen = newkeylen; 869 key->base.keylen = newkeylen;
871 } else { 870 } else {
872 struct tcp_md5sig_info *md5sig; 871 struct tcp_md5sig_info *md5sig;
873 872
@@ -906,9 +905,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
906 md5sig->alloced4++; 905 md5sig->alloced4++;
907 } 906 }
908 md5sig->entries4++; 907 md5sig->entries4++;
909 md5sig->keys4[md5sig->entries4 - 1].addr = addr; 908 md5sig->keys4[md5sig->entries4 - 1].addr = addr;
910 md5sig->keys4[md5sig->entries4 - 1].key = newkey; 909 md5sig->keys4[md5sig->entries4 - 1].base.key = newkey;
911 md5sig->keys4[md5sig->entries4 - 1].keylen = newkeylen; 910 md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen;
912 } 911 }
913 return 0; 912 return 0;
914} 913}
@@ -930,7 +929,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
930 for (i = 0; i < tp->md5sig_info->entries4; i++) { 929 for (i = 0; i < tp->md5sig_info->entries4; i++) {
931 if (tp->md5sig_info->keys4[i].addr == addr) { 930 if (tp->md5sig_info->keys4[i].addr == addr) {
932 /* Free the key */ 931 /* Free the key */
933 kfree(tp->md5sig_info->keys4[i].key); 932 kfree(tp->md5sig_info->keys4[i].base.key);
934 tp->md5sig_info->entries4--; 933 tp->md5sig_info->entries4--;
935 934
936 if (tp->md5sig_info->entries4 == 0) { 935 if (tp->md5sig_info->entries4 == 0) {
@@ -964,7 +963,7 @@ static void tcp_v4_clear_md5_list(struct sock *sk)
964 if (tp->md5sig_info->entries4) { 963 if (tp->md5sig_info->entries4) {
965 int i; 964 int i;
966 for (i = 0; i < tp->md5sig_info->entries4; i++) 965 for (i = 0; i < tp->md5sig_info->entries4; i++)
967 kfree(tp->md5sig_info->keys4[i].key); 966 kfree(tp->md5sig_info->keys4[i].base.key);
968 tp->md5sig_info->entries4 = 0; 967 tp->md5sig_info->entries4 = 0;
969 tcp_free_md5sig_pool(); 968 tcp_free_md5sig_pool();
970 } 969 }
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0f7defb482e9..3e06799b37a6 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -539,7 +539,7 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
539 539
540 for (i = 0; i < tp->md5sig_info->entries6; i++) { 540 for (i = 0; i < tp->md5sig_info->entries6; i++) {
541 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0) 541 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0)
542 return (struct tcp_md5sig_key *)&tp->md5sig_info->keys6[i]; 542 return &tp->md5sig_info->keys6[i].base;
543 } 543 }
544 return NULL; 544 return NULL;
545} 545}
@@ -567,9 +567,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
567 key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer); 567 key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer);
568 if (key) { 568 if (key) {
569 /* modify existing entry - just update that one */ 569 /* modify existing entry - just update that one */
570 kfree(key->key); 570 kfree(key->base.key);
571 key->key = newkey; 571 key->base.key = newkey;
572 key->keylen = newkeylen; 572 key->base.keylen = newkeylen;
573 } else { 573 } else {
574 /* reallocate new list if current one is full. */ 574 /* reallocate new list if current one is full. */
575 if (!tp->md5sig_info) { 575 if (!tp->md5sig_info) {
@@ -603,8 +603,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
603 603
604 ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, 604 ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr,
605 peer); 605 peer);
606 tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey; 606 tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey;
607 tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen; 607 tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen;
608 608
609 tp->md5sig_info->entries6++; 609 tp->md5sig_info->entries6++;
610 } 610 }
@@ -626,7 +626,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
626 for (i = 0; i < tp->md5sig_info->entries6; i++) { 626 for (i = 0; i < tp->md5sig_info->entries6; i++) {
627 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { 627 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) {
628 /* Free the key */ 628 /* Free the key */
629 kfree(tp->md5sig_info->keys6[i].key); 629 kfree(tp->md5sig_info->keys6[i].base.key);
630 tp->md5sig_info->entries6--; 630 tp->md5sig_info->entries6--;
631 631
632 if (tp->md5sig_info->entries6 == 0) { 632 if (tp->md5sig_info->entries6 == 0) {
@@ -657,7 +657,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk)
657 657
658 if (tp->md5sig_info->entries6) { 658 if (tp->md5sig_info->entries6) {
659 for (i = 0; i < tp->md5sig_info->entries6; i++) 659 for (i = 0; i < tp->md5sig_info->entries6; i++)
660 kfree(tp->md5sig_info->keys6[i].key); 660 kfree(tp->md5sig_info->keys6[i].base.key);
661 tp->md5sig_info->entries6 = 0; 661 tp->md5sig_info->entries6 = 0;
662 tcp_free_md5sig_pool(); 662 tcp_free_md5sig_pool();
663 } 663 }
@@ -668,7 +668,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk)
668 668
669 if (tp->md5sig_info->entries4) { 669 if (tp->md5sig_info->entries4) {
670 for (i = 0; i < tp->md5sig_info->entries4; i++) 670 for (i = 0; i < tp->md5sig_info->entries4; i++)
671 kfree(tp->md5sig_info->keys4[i].key); 671 kfree(tp->md5sig_info->keys4[i].base.key);
672 tp->md5sig_info->entries4 = 0; 672 tp->md5sig_info->entries4 = 0;
673 tcp_free_md5sig_pool(); 673 tcp_free_md5sig_pool();
674 } 674 }