| From foo@baz Thu Jul 19 10:08:15 CEST 2018 |
| From: Yuchung Cheng <ycheng@google.com> |
| Date: Wed, 27 Jun 2018 16:04:48 -0700 |
| Subject: tcp: fix Fast Open key endianness |
| |
| From: Yuchung Cheng <ycheng@google.com> |
| |
| [ Upstream commit c860e997e9170a6d68f9d1e6e2cf61f572191aaf ] |
| |
| Fast Open key could be stored in different endian based on the CPU. |
| Previously hosts in different endianness in a server farm using |
| the same key config (sysctl value) would produce different cookies. |
| This patch fixes it by always storing it as little endian to keep |
| same API for LE hosts. |
| |
| Reported-by: Daniele Iamartino <danielei@google.com> |
| Signed-off-by: Yuchung Cheng <ycheng@google.com> |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Signed-off-by: Neal Cardwell <ncardwell@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ipv4/sysctl_net_ipv4.c | 18 +++++++++++++----- |
| 1 file changed, 13 insertions(+), 5 deletions(-) |
| |
| --- a/net/ipv4/sysctl_net_ipv4.c |
| +++ b/net/ipv4/sysctl_net_ipv4.c |
| @@ -213,8 +213,9 @@ static int proc_tcp_fastopen_key(struct |
| { |
| struct ctl_table tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) }; |
| struct tcp_fastopen_context *ctxt; |
| - int ret; |
| u32 user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */ |
| + __le32 key[4]; |
| + int ret, i; |
| |
| tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL); |
| if (!tbl.data) |
| @@ -223,11 +224,14 @@ static int proc_tcp_fastopen_key(struct |
| rcu_read_lock(); |
| ctxt = rcu_dereference(tcp_fastopen_ctx); |
| if (ctxt) |
| - memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); |
| + memcpy(key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); |
| else |
| - memset(user_key, 0, sizeof(user_key)); |
| + memset(key, 0, sizeof(key)); |
| rcu_read_unlock(); |
| |
| + for (i = 0; i < ARRAY_SIZE(key); i++) |
| + user_key[i] = le32_to_cpu(key[i]); |
| + |
| snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x", |
| user_key[0], user_key[1], user_key[2], user_key[3]); |
| ret = proc_dostring(&tbl, write, buffer, lenp, ppos); |
| @@ -243,12 +247,16 @@ static int proc_tcp_fastopen_key(struct |
| * first invocation of tcp_fastopen_cookie_gen |
| */ |
| tcp_fastopen_init_key_once(false); |
| - tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH); |
| + |
| + for (i = 0; i < ARRAY_SIZE(user_key); i++) |
| + key[i] = cpu_to_le32(user_key[i]); |
| + |
| + tcp_fastopen_reset_cipher(key, TCP_FASTOPEN_KEY_LENGTH); |
| } |
| |
| bad_key: |
| pr_debug("proc FO key set 0x%x-%x-%x-%x <- 0x%s: %u\n", |
| - user_key[0], user_key[1], user_key[2], user_key[3], |
| + user_key[0], user_key[1], user_key[2], user_key[3], |
| (char *)tbl.data, ret); |
| kfree(tbl.data); |
| return ret; |