tcp: correct read of TFO keys on big endian systems
When TFO keys are read back on big endian systems either via the global
sysctl interface or via getsockopt() using TCP_FASTOPEN_KEY, the values
don't match what was written.
For example, on s390x:
# echo "1-2-3-4" > /proc/sys/net/ipv4/tcp_fastopen_key
# cat /proc/sys/net/ipv4/tcp_fastopen_key
02000000-01000000-04000000-03000000
Instead of:
# cat /proc/sys/net/ipv4/tcp_fastopen_key
00000001-00000002-00000003-00000004
Fix this by converting to the correct endianness on read. This was
reported by Colin Ian King when running the 'tcp_fastopen_backup_key' net
selftest on s390x, which depends on the read value matching what was
written. I've confirmed that the test now passes on big and little endian
systems.
Signed-off-by: Jason Baron <jbaron@akamai.com>
Fixes: 438ac88009
("net: fastopen: robustness and endianness fixes for SipHash")
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Eric Dumazet <edumazet@google.com>
Reported-and-tested-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
56e287b3da
commit
f19008e676
@@ -301,24 +301,16 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
|
||||
struct ctl_table tbl = { .maxlen = ((TCP_FASTOPEN_KEY_LENGTH *
|
||||
2 * TCP_FASTOPEN_KEY_MAX) +
|
||||
(TCP_FASTOPEN_KEY_MAX * 5)) };
|
||||
struct tcp_fastopen_context *ctx;
|
||||
u32 user_key[TCP_FASTOPEN_KEY_MAX * 4];
|
||||
__le32 key[TCP_FASTOPEN_KEY_MAX * 4];
|
||||
u32 user_key[TCP_FASTOPEN_KEY_BUF_LENGTH / sizeof(u32)];
|
||||
__le32 key[TCP_FASTOPEN_KEY_BUF_LENGTH / sizeof(__le32)];
|
||||
char *backup_data;
|
||||
int ret, i = 0, off = 0, n_keys = 0;
|
||||
int ret, i = 0, off = 0, n_keys;
|
||||
|
||||
tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL);
|
||||
if (!tbl.data)
|
||||
return -ENOMEM;
|
||||
|
||||
rcu_read_lock();
|
||||
ctx = rcu_dereference(net->ipv4.tcp_fastopen_ctx);
|
||||
if (ctx) {
|
||||
n_keys = tcp_fastopen_context_len(ctx);
|
||||
memcpy(&key[0], &ctx->key[0], TCP_FASTOPEN_KEY_LENGTH * n_keys);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
n_keys = tcp_fastopen_get_cipher(net, NULL, (u64 *)key);
|
||||
if (!n_keys) {
|
||||
memset(&key[0], 0, TCP_FASTOPEN_KEY_LENGTH);
|
||||
n_keys = 1;
|
||||
|
Reference in New Issue
Block a user