diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/flow_dissector.c | 2 | ||||
| -rw-r--r-- | net/core/neighbour.c | 3 | ||||
| -rw-r--r-- | net/core/secure_seq.c | 31 | ||||
| -rw-r--r-- | net/core/sysctl_net_core.c | 6 |
4 files changed, 36 insertions, 6 deletions
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 5f3ae922fcd1..c9cf425303f8 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
| @@ -159,7 +159,7 @@ __skb_flow_dissect_arp(const struct sk_buff *skb, | |||
| 159 | unsigned char ar_tip[4]; | 159 | unsigned char ar_tip[4]; |
| 160 | } *arp_eth, _arp_eth; | 160 | } *arp_eth, _arp_eth; |
| 161 | const struct arphdr *arp; | 161 | const struct arphdr *arp; |
| 162 | struct arphdr *_arp; | 162 | struct arphdr _arp; |
| 163 | 163 | ||
| 164 | if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ARP)) | 164 | if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ARP)) |
| 165 | return FLOW_DISSECT_RET_OUT_GOOD; | 165 | return FLOW_DISSECT_RET_OUT_GOOD; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 7069f5e4a361..8ae87c591c8e 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -861,7 +861,8 @@ static void neigh_probe(struct neighbour *neigh) | |||
| 861 | if (skb) | 861 | if (skb) |
| 862 | skb = skb_clone(skb, GFP_ATOMIC); | 862 | skb = skb_clone(skb, GFP_ATOMIC); |
| 863 | write_unlock(&neigh->lock); | 863 | write_unlock(&neigh->lock); |
| 864 | neigh->ops->solicit(neigh, skb); | 864 | if (neigh->ops->solicit) |
| 865 | neigh->ops->solicit(neigh, skb); | ||
| 865 | atomic_inc(&neigh->probes); | 866 | atomic_inc(&neigh->probes); |
| 866 | kfree_skb(skb); | 867 | kfree_skb(skb); |
| 867 | } | 868 | } |
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c index fb87e78a2cc7..6bd2f8fb0476 100644 --- a/net/core/secure_seq.c +++ b/net/core/secure_seq.c | |||
| @@ -20,9 +20,11 @@ | |||
| 20 | #include <net/tcp.h> | 20 | #include <net/tcp.h> |
| 21 | 21 | ||
| 22 | static siphash_key_t net_secret __read_mostly; | 22 | static siphash_key_t net_secret __read_mostly; |
| 23 | static siphash_key_t ts_secret __read_mostly; | ||
| 23 | 24 | ||
| 24 | static __always_inline void net_secret_init(void) | 25 | static __always_inline void net_secret_init(void) |
| 25 | { | 26 | { |
| 27 | net_get_random_once(&ts_secret, sizeof(ts_secret)); | ||
| 26 | net_get_random_once(&net_secret, sizeof(net_secret)); | 28 | net_get_random_once(&net_secret, sizeof(net_secret)); |
| 27 | } | 29 | } |
| 28 | #endif | 30 | #endif |
| @@ -45,6 +47,23 @@ static u32 seq_scale(u32 seq) | |||
| 45 | #endif | 47 | #endif |
| 46 | 48 | ||
| 47 | #if IS_ENABLED(CONFIG_IPV6) | 49 | #if IS_ENABLED(CONFIG_IPV6) |
| 50 | static u32 secure_tcpv6_ts_off(const __be32 *saddr, const __be32 *daddr) | ||
| 51 | { | ||
| 52 | const struct { | ||
| 53 | struct in6_addr saddr; | ||
| 54 | struct in6_addr daddr; | ||
| 55 | } __aligned(SIPHASH_ALIGNMENT) combined = { | ||
| 56 | .saddr = *(struct in6_addr *)saddr, | ||
| 57 | .daddr = *(struct in6_addr *)daddr, | ||
| 58 | }; | ||
| 59 | |||
| 60 | if (sysctl_tcp_timestamps != 1) | ||
| 61 | return 0; | ||
| 62 | |||
| 63 | return siphash(&combined, offsetofend(typeof(combined), daddr), | ||
| 64 | &ts_secret); | ||
| 65 | } | ||
| 66 | |||
| 48 | u32 secure_tcpv6_seq_and_tsoff(const __be32 *saddr, const __be32 *daddr, | 67 | u32 secure_tcpv6_seq_and_tsoff(const __be32 *saddr, const __be32 *daddr, |
| 49 | __be16 sport, __be16 dport, u32 *tsoff) | 68 | __be16 sport, __be16 dport, u32 *tsoff) |
| 50 | { | 69 | { |
| @@ -63,7 +82,7 @@ u32 secure_tcpv6_seq_and_tsoff(const __be32 *saddr, const __be32 *daddr, | |||
| 63 | net_secret_init(); | 82 | net_secret_init(); |
| 64 | hash = siphash(&combined, offsetofend(typeof(combined), dport), | 83 | hash = siphash(&combined, offsetofend(typeof(combined), dport), |
| 65 | &net_secret); | 84 | &net_secret); |
| 66 | *tsoff = sysctl_tcp_timestamps == 1 ? (hash >> 32) : 0; | 85 | *tsoff = secure_tcpv6_ts_off(saddr, daddr); |
| 67 | return seq_scale(hash); | 86 | return seq_scale(hash); |
| 68 | } | 87 | } |
| 69 | EXPORT_SYMBOL(secure_tcpv6_seq_and_tsoff); | 88 | EXPORT_SYMBOL(secure_tcpv6_seq_and_tsoff); |
| @@ -88,6 +107,14 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral); | |||
| 88 | #endif | 107 | #endif |
| 89 | 108 | ||
| 90 | #ifdef CONFIG_INET | 109 | #ifdef CONFIG_INET |
| 110 | static u32 secure_tcp_ts_off(__be32 saddr, __be32 daddr) | ||
| 111 | { | ||
| 112 | if (sysctl_tcp_timestamps != 1) | ||
| 113 | return 0; | ||
| 114 | |||
| 115 | return siphash_2u32((__force u32)saddr, (__force u32)daddr, | ||
| 116 | &ts_secret); | ||
| 117 | } | ||
| 91 | 118 | ||
| 92 | /* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d), | 119 | /* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d), |
| 93 | * but fortunately, `sport' cannot be 0 in any circumstances. If this changes, | 120 | * but fortunately, `sport' cannot be 0 in any circumstances. If this changes, |
| @@ -102,7 +129,7 @@ u32 secure_tcp_seq_and_tsoff(__be32 saddr, __be32 daddr, | |||
| 102 | hash = siphash_3u32((__force u32)saddr, (__force u32)daddr, | 129 | hash = siphash_3u32((__force u32)saddr, (__force u32)daddr, |
| 103 | (__force u32)sport << 16 | (__force u32)dport, | 130 | (__force u32)sport << 16 | (__force u32)dport, |
| 104 | &net_secret); | 131 | &net_secret); |
| 105 | *tsoff = sysctl_tcp_timestamps == 1 ? (hash >> 32) : 0; | 132 | *tsoff = secure_tcp_ts_off(saddr, daddr); |
| 106 | return seq_scale(hash); | 133 | return seq_scale(hash); |
| 107 | } | 134 | } |
| 108 | 135 | ||
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 4ead336e14ea..7f9cc400eca0 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
| @@ -408,14 +408,16 @@ static struct ctl_table net_core_table[] = { | |||
| 408 | .data = &sysctl_net_busy_poll, | 408 | .data = &sysctl_net_busy_poll, |
| 409 | .maxlen = sizeof(unsigned int), | 409 | .maxlen = sizeof(unsigned int), |
| 410 | .mode = 0644, | 410 | .mode = 0644, |
| 411 | .proc_handler = proc_dointvec | 411 | .proc_handler = proc_dointvec_minmax, |
| 412 | .extra1 = &zero, | ||
| 412 | }, | 413 | }, |
| 413 | { | 414 | { |
| 414 | .procname = "busy_read", | 415 | .procname = "busy_read", |
| 415 | .data = &sysctl_net_busy_read, | 416 | .data = &sysctl_net_busy_read, |
| 416 | .maxlen = sizeof(unsigned int), | 417 | .maxlen = sizeof(unsigned int), |
| 417 | .mode = 0644, | 418 | .mode = 0644, |
| 418 | .proc_handler = proc_dointvec | 419 | .proc_handler = proc_dointvec_minmax, |
| 420 | .extra1 = &zero, | ||
| 419 | }, | 421 | }, |
| 420 | #endif | 422 | #endif |
| 421 | #ifdef CONFIG_NET_SCHED | 423 | #ifdef CONFIG_NET_SCHED |
