[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>

+20 -23
+2 -4
include/net/tcp.h
··· 1059 1059 }; 1060 1060 1061 1061 struct tcp4_md5sig_key { 1062 - u8 *key; 1063 - u16 keylen; 1062 + struct tcp_md5sig_key base; 1064 1063 __be32 addr; 1065 1064 }; 1066 1065 1067 1066 struct tcp6_md5sig_key { 1068 - u8 *key; 1069 - u16 keylen; 1067 + struct tcp_md5sig_key base; 1070 1068 #if 0 1071 1069 u32 scope_id; /* XXX */ 1072 1070 #endif
+9 -10
net/ipv4/tcp_ipv4.c
··· 833 833 return NULL; 834 834 for (i = 0; i < tp->md5sig_info->entries4; i++) { 835 835 if (tp->md5sig_info->keys4[i].addr == addr) 836 - return (struct tcp_md5sig_key *) 837 - &tp->md5sig_info->keys4[i]; 836 + return &tp->md5sig_info->keys4[i].base; 838 837 } 839 838 return NULL; 840 839 } ··· 864 865 key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr); 865 866 if (key) { 866 867 /* Pre-existing entry - just update that one. */ 867 - kfree(key->key); 868 - key->key = newkey; 869 - key->keylen = newkeylen; 868 + kfree(key->base.key); 869 + key->base.key = newkey; 870 + key->base.keylen = newkeylen; 870 871 } else { 871 872 struct tcp_md5sig_info *md5sig; 872 873 ··· 905 906 md5sig->alloced4++; 906 907 } 907 908 md5sig->entries4++; 908 - md5sig->keys4[md5sig->entries4 - 1].addr = addr; 909 - md5sig->keys4[md5sig->entries4 - 1].key = newkey; 910 - md5sig->keys4[md5sig->entries4 - 1].keylen = newkeylen; 909 + md5sig->keys4[md5sig->entries4 - 1].addr = addr; 910 + md5sig->keys4[md5sig->entries4 - 1].base.key = newkey; 911 + md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen; 911 912 } 912 913 return 0; 913 914 } ··· 929 930 for (i = 0; i < tp->md5sig_info->entries4; i++) { 930 931 if (tp->md5sig_info->keys4[i].addr == addr) { 931 932 /* Free the key */ 932 - kfree(tp->md5sig_info->keys4[i].key); 933 + kfree(tp->md5sig_info->keys4[i].base.key); 933 934 tp->md5sig_info->entries4--; 934 935 935 936 if (tp->md5sig_info->entries4 == 0) { ··· 963 964 if (tp->md5sig_info->entries4) { 964 965 int i; 965 966 for (i = 0; i < tp->md5sig_info->entries4; i++) 966 - kfree(tp->md5sig_info->keys4[i].key); 967 + kfree(tp->md5sig_info->keys4[i].base.key); 967 968 tp->md5sig_info->entries4 = 0; 968 969 tcp_free_md5sig_pool(); 969 970 }
+9 -9
net/ipv6/tcp_ipv6.c
··· 539 539 540 540 for (i = 0; i < tp->md5sig_info->entries6; i++) { 541 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 544 return NULL; 545 545 } ··· 567 567 key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer); 568 568 if (key) { 569 569 /* modify existing entry - just update that one */ 570 - kfree(key->key); 571 - key->key = newkey; 572 - key->keylen = newkeylen; 570 + kfree(key->base.key); 571 + key->base.key = newkey; 572 + key->base.keylen = newkeylen; 573 573 } else { 574 574 /* reallocate new list if current one is full. */ 575 575 if (!tp->md5sig_info) { ··· 603 603 604 604 ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, 605 605 peer); 606 - tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey; 607 - tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen; 606 + tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey; 607 + tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen; 608 608 609 609 tp->md5sig_info->entries6++; 610 610 } ··· 626 626 for (i = 0; i < tp->md5sig_info->entries6; i++) { 627 627 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { 628 628 /* Free the key */ 629 - kfree(tp->md5sig_info->keys6[i].key); 629 + kfree(tp->md5sig_info->keys6[i].base.key); 630 630 tp->md5sig_info->entries6--; 631 631 632 632 if (tp->md5sig_info->entries6 == 0) { ··· 657 657 658 658 if (tp->md5sig_info->entries6) { 659 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 661 tp->md5sig_info->entries6 = 0; 662 662 tcp_free_md5sig_pool(); 663 663 } ··· 668 668 669 669 if (tp->md5sig_info->entries4) { 670 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 672 tp->md5sig_info->entries4 = 0; 673 673 tcp_free_md5sig_pool(); 674 674 }