summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2022-06-06 11:01:55 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2022-06-06 11:01:55 +0200
commit1f161a096b52aff01e5ababb9da7e76e5e4e12ff (patch)
treea42dbb27d6c9cdf5c49b79e702365091c025b83e /net
parent3bf624404a1a02784205e5bf3a80681663c3be0d (diff)
parentb8f3be299d5176348b15cc59d55b85faa3dece68 (diff)
Merge 4.14.282 into android-4.14-stable
Changes in 4.14.282 x86/pci/xen: Disable PCI/MSI[-X] masking for XEN_HVM guests staging: rtl8723bs: prevent ->Ssid overflow in rtw_wx_set_scan() tcp: change source port randomizarion at connect() time secure_seq: use the 64 bits of the siphash for port offset calculation ACPI: sysfs: Make sparse happy about address space in use ACPI: sysfs: Fix BERT error region memory mapping net: af_key: check encryption module availability consistency net: ftgmac100: Disable hardware checksum on AST2600 drivers: i2c: thunderx: Allow driver to work with ACPI defined TWSI controllers assoc_array: Fix BUG_ON during garbage collect drm/i915: Fix -Wstringop-overflow warning in call to intel_read_wm_latency() block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern exec: Force single empty string when argv is empty netfilter: conntrack: re-fetch conntrack after insertion zsmalloc: fix races between asynchronous zspage free and page migration dm integrity: fix error code in dm_integrity_ctr() dm crypt: make printing of the key constant-time dm stats: add cond_resched when looping over entries dm verity: set DM_TARGET_IMMUTABLE feature flag tpm: ibmvtpm: Correct the return value in tpm_ibmvtpm_probe() docs: submitting-patches: Fix crossref to 'The canonical patch format' NFSD: Fix possible sleep during nfsd4_release_lockowner() bpf: Enlarge offset check value to INT_MAX in bpf_skb_{load,store}_bytes Linux 4.14.282 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ieb45fbca1afbc9bf3a97a5beda24be2f82b65abe
Diffstat (limited to 'net')
-rw-r--r--net/core/filter.c4
-rw-r--r--net/core/secure_seq.c4
-rw-r--r--net/ipv4/inet_hashtables.c28
-rw-r--r--net/ipv6/inet6_hashtables.c4
-rw-r--r--net/key/af_key.c6
5 files changed, 31 insertions, 15 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index 6adb7969367d..5c9028ac3b7a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1443,7 +1443,7 @@ BPF_CALL_5(bpf_skb_store_bytes, struct sk_buff *, skb, u32, offset,
if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM | BPF_F_INVALIDATE_HASH)))
return -EINVAL;
- if (unlikely(offset > 0xffff))
+ if (unlikely(offset > INT_MAX))
return -EFAULT;
if (unlikely(bpf_try_make_writable(skb, offset + len)))
return -EFAULT;
@@ -1478,7 +1478,7 @@ BPF_CALL_4(bpf_skb_load_bytes, const struct sk_buff *, skb, u32, offset,
{
void *ptr;
- if (unlikely(offset > 0xffff))
+ if (unlikely(offset > INT_MAX))
goto err_clear;
ptr = skb_header_pointer(skb, offset, len, to);
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index 17683aea8a35..4aaae9220908 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -96,7 +96,7 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
}
EXPORT_SYMBOL(secure_tcpv6_seq);
-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
__be16 dport)
{
const struct {
@@ -145,7 +145,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
return seq_scale(hash);
}
-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
+u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
{
net_secret_init();
return siphash_4u32((__force u32)saddr, (__force u32)daddr,
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 1346e45cf8d1..1ebad5a024a7 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -389,7 +389,7 @@ not_unique:
return -EADDRNOTAVAIL;
}
-static u32 inet_sk_port_offset(const struct sock *sk)
+static u64 inet_sk_port_offset(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
@@ -587,8 +587,19 @@ void inet_unhash(struct sock *sk)
}
EXPORT_SYMBOL_GPL(inet_unhash);
+/* RFC 6056 3.3.4. Algorithm 4: Double-Hash Port Selection Algorithm
+ * Note that we use 32bit integers (vs RFC 'short integers')
+ * because 2^16 is not a multiple of num_ephemeral and this
+ * property might be used by clever attacker.
+ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement,
+ * we use 256 instead to really give more isolation and
+ * privacy, this only consumes 1 KB of kernel memory.
+ */
+#define INET_TABLE_PERTURB_SHIFT 8
+static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
+
int __inet_hash_connect(struct inet_timewait_death_row *death_row,
- struct sock *sk, u32 port_offset,
+ struct sock *sk, u64 port_offset,
int (*check_established)(struct inet_timewait_death_row *,
struct sock *, __u16, struct inet_timewait_sock **))
{
@@ -600,7 +611,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
struct inet_bind_bucket *tb;
u32 remaining, offset;
int ret, i, low, high;
- static u32 hint;
+ u32 index;
if (port) {
head = &hinfo->bhash[inet_bhashfn(net, port,
@@ -625,7 +636,12 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
if (likely(remaining > 1))
remaining &= ~1U;
- offset = (hint + port_offset) % remaining;
+ net_get_random_once(table_perturb, sizeof(table_perturb));
+ index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
+
+ offset = READ_ONCE(table_perturb[index]) + port_offset;
+ offset %= remaining;
+
/* In first pass we try ports of @low parity.
* inet_csk_get_port() does the opposite choice.
*/
@@ -678,7 +694,7 @@ next_port:
return -EADDRNOTAVAIL;
ok:
- hint += i + 2;
+ WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2);
/* Head lock still held and bh's disabled */
inet_bind_hash(sk, tb, port);
@@ -701,7 +717,7 @@ ok:
int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk)
{
- u32 port_offset = 0;
+ u64 port_offset = 0;
if (!inet_sk(sk)->inet_num)
port_offset = inet_sk_port_offset(sk);
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 24a21979d7df..7d83ab627b09 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -248,7 +248,7 @@ not_unique:
return -EADDRNOTAVAIL;
}
-static u32 inet6_sk_port_offset(const struct sock *sk)
+static u64 inet6_sk_port_offset(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
@@ -260,7 +260,7 @@ static u32 inet6_sk_port_offset(const struct sock *sk)
int inet6_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk)
{
- u32 port_offset = 0;
+ u64 port_offset = 0;
if (!inet_sk(sk)->inet_num)
port_offset = inet6_sk_port_offset(sk);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index e94b02eff557..6628ee1bc24d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2908,7 +2908,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
break;
if (!aalg->pfkey_supported)
continue;
- if (aalg_tmpl_set(t, aalg))
+ if (aalg_tmpl_set(t, aalg) && aalg->available)
sz += sizeof(struct sadb_comb);
}
return sz + sizeof(struct sadb_prop);
@@ -2926,7 +2926,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
if (!ealg->pfkey_supported)
continue;
- if (!(ealg_tmpl_set(t, ealg)))
+ if (!(ealg_tmpl_set(t, ealg) && ealg->available))
continue;
for (k = 1; ; k++) {
@@ -2937,7 +2937,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
if (!aalg->pfkey_supported)
continue;
- if (aalg_tmpl_set(t, aalg))
+ if (aalg_tmpl_set(t, aalg) && aalg->available)
sz += sizeof(struct sadb_comb);
}
}