diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-10-24 01:52:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-24 01:52:35 -0400 |
commit | ca35a0ef85e8ed6df6d5ab01fb6c3530cca0c469 (patch) | |
tree | 3a6d0c107ec48823bb3e437f1f91d2276facb46d | |
parent | 01718e36df750670d0f840932a4d166522ead6c3 (diff) | |
download | linux-ca35a0ef85e8ed6df6d5ab01fb6c3530cca0c469.tar.gz linux-ca35a0ef85e8ed6df6d5ab01fb6c3530cca0c469.tar.bz2 linux-ca35a0ef85e8ed6df6d5ab01fb6c3530cca0c469.zip |
tcp: md5: dont write skb head in tcp_md5_hash_header()
tcp_md5_hash_header() writes into skb header a temporary zero value,
this might confuse other users of this area.
Since tcphdr is small (20 bytes), copy it in a temporary variable and
make the change in the copy.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/tcp.h | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 14 |
2 files changed, 9 insertions, 7 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h index 3edef0bebdd1..910cc29f9e97 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1209,7 +1209,7 @@ extern void tcp_free_md5sig_pool(void); extern struct tcp_md5sig_pool *tcp_get_md5sig_pool(void); extern void tcp_put_md5sig_pool(void); -extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, struct tcphdr *); +extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, const struct tcphdr *); extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, const struct sk_buff *, unsigned header_len); extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 704adad8f07f..eefc61e3d0e4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2994,17 +2994,19 @@ void tcp_put_md5sig_pool(void) EXPORT_SYMBOL(tcp_put_md5sig_pool); int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, - struct tcphdr *th) + const struct tcphdr *th) { struct scatterlist sg; + struct tcphdr hdr; int err; - __sum16 old_checksum = th->check; - th->check = 0; + /* We are not allowed to change tcphdr, make a local copy */ + memcpy(&hdr, th, sizeof(hdr)); + hdr.check = 0; + /* options aren't included in the hash */ - sg_init_one(&sg, th, sizeof(struct tcphdr)); - err = crypto_hash_update(&hp->md5_desc, &sg, sizeof(struct tcphdr)); - th->check = old_checksum; + sg_init_one(&sg, &hdr, sizeof(hdr)); + err = crypto_hash_update(&hp->md5_desc, &sg, sizeof(hdr)); return err; } EXPORT_SYMBOL(tcp_md5_hash_header); |