The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
Possible dependencies:
2c02d41d71f9 ("net/ulp: prevent ULP without clone op from entering the LISTEN status")
e276d62dcfde ("net/ulp: remove SOCK_SUPPORT_ZC from tls sockets")
e7049395b1c3 ("dccp/tcp: Remove an unused argument in inet_csk_listen_start().")
53632e111946 ("bpf: selftest: Use bpf_sk_storage in FENTRY/FEXIT/RAW_TP")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2c02d41d71f90a5168391b6a5f2954112ba2307c Mon Sep 17 00:00:00 2001
From: Paolo Abeni <pabeni(a)redhat.com>
Date: Tue, 3 Jan 2023 12:19:17 +0100
Subject: [PATCH] net/ulp: prevent ULP without clone op from entering the
LISTEN status
When an ULP-enabled socket enters the LISTEN status, the listener ULP data
pointer is copied inside the child/accepted sockets by sk_clone_lock().
The relevant ULP can take care of de-duplicating the context pointer via
the clone() operation, but only MPTCP and SMC implement such op.
Other ULPs may end-up with a double-free at socket disposal time.
We can't simply clear the ULP data at clone time, as TLS replaces the
socket ops with custom ones assuming a valid TLS ULP context is
available.
Instead completely prevent clone-less ULP sockets from entering the
LISTEN status.
Fixes: 734942cc4ea6 ("tcp: ULP infrastructure")
Reported-by: slipper <slipper.alive(a)gmail.com>
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
Link: https://lore.kernel.org/r/4b80c3d1dbe3d0ab072f80450c202d9bc88b4b03.16727406…
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 848ffc3e0239..d1f837579398 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1200,12 +1200,26 @@ void inet_csk_prepare_forced_close(struct sock *sk)
}
EXPORT_SYMBOL(inet_csk_prepare_forced_close);
+static int inet_ulp_can_listen(const struct sock *sk)
+{
+ const struct inet_connection_sock *icsk = inet_csk(sk);
+
+ if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
+ return -EINVAL;
+
+ return 0;
+}
+
int inet_csk_listen_start(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct inet_sock *inet = inet_sk(sk);
int err;
+ err = inet_ulp_can_listen(sk);
+ if (unlikely(err))
+ return err;
+
reqsk_queue_alloc(&icsk->icsk_accept_queue);
sk->sk_ack_backlog = 0;
diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
index 9ae50b1bd844..05b6077b9f2c 100644
--- a/net/ipv4/tcp_ulp.c
+++ b/net/ipv4/tcp_ulp.c
@@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
if (sk->sk_socket)
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ err = -EINVAL;
+ if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
+ goto out_err;
+
err = ulp_ops->init(sk);
if (err)
goto out_err;
The patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
Possible dependencies:
2c02d41d71f9 ("net/ulp: prevent ULP without clone op from entering the LISTEN status")
e276d62dcfde ("net/ulp: remove SOCK_SUPPORT_ZC from tls sockets")
e7049395b1c3 ("dccp/tcp: Remove an unused argument in inet_csk_listen_start().")
53632e111946 ("bpf: selftest: Use bpf_sk_storage in FENTRY/FEXIT/RAW_TP")
8b27dae5a2e8 ("tcp: add one skb cache for rx")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2c02d41d71f90a5168391b6a5f2954112ba2307c Mon Sep 17 00:00:00 2001
From: Paolo Abeni <pabeni(a)redhat.com>
Date: Tue, 3 Jan 2023 12:19:17 +0100
Subject: [PATCH] net/ulp: prevent ULP without clone op from entering the
LISTEN status
When an ULP-enabled socket enters the LISTEN status, the listener ULP data
pointer is copied inside the child/accepted sockets by sk_clone_lock().
The relevant ULP can take care of de-duplicating the context pointer via
the clone() operation, but only MPTCP and SMC implement such op.
Other ULPs may end-up with a double-free at socket disposal time.
We can't simply clear the ULP data at clone time, as TLS replaces the
socket ops with custom ones assuming a valid TLS ULP context is
available.
Instead completely prevent clone-less ULP sockets from entering the
LISTEN status.
Fixes: 734942cc4ea6 ("tcp: ULP infrastructure")
Reported-by: slipper <slipper.alive(a)gmail.com>
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
Link: https://lore.kernel.org/r/4b80c3d1dbe3d0ab072f80450c202d9bc88b4b03.16727406…
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 848ffc3e0239..d1f837579398 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1200,12 +1200,26 @@ void inet_csk_prepare_forced_close(struct sock *sk)
}
EXPORT_SYMBOL(inet_csk_prepare_forced_close);
+static int inet_ulp_can_listen(const struct sock *sk)
+{
+ const struct inet_connection_sock *icsk = inet_csk(sk);
+
+ if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
+ return -EINVAL;
+
+ return 0;
+}
+
int inet_csk_listen_start(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct inet_sock *inet = inet_sk(sk);
int err;
+ err = inet_ulp_can_listen(sk);
+ if (unlikely(err))
+ return err;
+
reqsk_queue_alloc(&icsk->icsk_accept_queue);
sk->sk_ack_backlog = 0;
diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
index 9ae50b1bd844..05b6077b9f2c 100644
--- a/net/ipv4/tcp_ulp.c
+++ b/net/ipv4/tcp_ulp.c
@@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
if (sk->sk_socket)
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ err = -EINVAL;
+ if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
+ goto out_err;
+
err = ulp_ops->init(sk);
if (err)
goto out_err;
The patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
Possible dependencies:
2c02d41d71f9 ("net/ulp: prevent ULP without clone op from entering the LISTEN status")
e276d62dcfde ("net/ulp: remove SOCK_SUPPORT_ZC from tls sockets")
e7049395b1c3 ("dccp/tcp: Remove an unused argument in inet_csk_listen_start().")
53632e111946 ("bpf: selftest: Use bpf_sk_storage in FENTRY/FEXIT/RAW_TP")
8b27dae5a2e8 ("tcp: add one skb cache for rx")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2c02d41d71f90a5168391b6a5f2954112ba2307c Mon Sep 17 00:00:00 2001
From: Paolo Abeni <pabeni(a)redhat.com>
Date: Tue, 3 Jan 2023 12:19:17 +0100
Subject: [PATCH] net/ulp: prevent ULP without clone op from entering the
LISTEN status
When an ULP-enabled socket enters the LISTEN status, the listener ULP data
pointer is copied inside the child/accepted sockets by sk_clone_lock().
The relevant ULP can take care of de-duplicating the context pointer via
the clone() operation, but only MPTCP and SMC implement such op.
Other ULPs may end-up with a double-free at socket disposal time.
We can't simply clear the ULP data at clone time, as TLS replaces the
socket ops with custom ones assuming a valid TLS ULP context is
available.
Instead completely prevent clone-less ULP sockets from entering the
LISTEN status.
Fixes: 734942cc4ea6 ("tcp: ULP infrastructure")
Reported-by: slipper <slipper.alive(a)gmail.com>
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
Link: https://lore.kernel.org/r/4b80c3d1dbe3d0ab072f80450c202d9bc88b4b03.16727406…
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 848ffc3e0239..d1f837579398 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1200,12 +1200,26 @@ void inet_csk_prepare_forced_close(struct sock *sk)
}
EXPORT_SYMBOL(inet_csk_prepare_forced_close);
+static int inet_ulp_can_listen(const struct sock *sk)
+{
+ const struct inet_connection_sock *icsk = inet_csk(sk);
+
+ if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
+ return -EINVAL;
+
+ return 0;
+}
+
int inet_csk_listen_start(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct inet_sock *inet = inet_sk(sk);
int err;
+ err = inet_ulp_can_listen(sk);
+ if (unlikely(err))
+ return err;
+
reqsk_queue_alloc(&icsk->icsk_accept_queue);
sk->sk_ack_backlog = 0;
diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
index 9ae50b1bd844..05b6077b9f2c 100644
--- a/net/ipv4/tcp_ulp.c
+++ b/net/ipv4/tcp_ulp.c
@@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
if (sk->sk_socket)
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ err = -EINVAL;
+ if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
+ goto out_err;
+
err = ulp_ops->init(sk);
if (err)
goto out_err;
Hi all,
Since updating to 6.0.16 the bind() system call no longer fails with
EADDRINUSE when the address is already in use.
Instead bind() returns 1 in such a case, which is not a valid return
value for this system call.
It works with the 6.0.15 kernel and earlier, 6.1.4 and 6.2-rc3 also
seem to work.
Fedora bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2159066
To reproduce you can just run `ncat -l 5000` two times, the second one
should fail. However it just uses a random port instead.
As far as I can tell this problem is caused by
https://lore.kernel.org/stable/20221228144337.512799851@linuxfoundation.org/
which did not backport commit 7a7160edf1bf properly.
The line `int ret = -EADDRINUSE, port = snum, l3mdev;` is missing in
net/ipv4/inet_connection_sock.c.
This is the working 6.1 patch:
https://lore.kernel.org/all/20221228144339.969733443@linuxfoundation.org/
Best regards,
Paul
The code to extract a peripheral's currently supported Pin Assignments
is repeated in a couple of locations. Factor it out into a separate
function.
This will also make it easier to add fixes (we only need to update 1
location instead of 2).
Fixes: c1e5c2f0cb8a ("usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles")
Cc: stable(a)vger.kernel.org
Cc: Heikki Krogerus <heikki.krogerus(a)linux.intel.com>
Signed-off-by: Prashant Malani <pmalani(a)chromium.org>
---
While this patch doesn't fix anything, it is required by the actual
fix (which is Patch 2/3 in this series). So, I've add the "Fixes" tag
and "Cc stable" tag to ensure that both patches are picked.
If this is the incorrect approach and there is a better way, my
apologies, and please let me know the appropriate process.
drivers/usb/typec/altmodes/displayport.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c
index 06fb4732f8cd..f9d4a7648bc9 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -420,6 +420,18 @@ static const char * const pin_assignments[] = {
[DP_PIN_ASSIGN_F] = "F",
};
+/*
+ * Helper function to extract a peripheral's currently supported
+ * Pin Assignments from its DisplayPort alternate mode state.
+ */
+static u8 get_current_pin_assignments(struct dp_altmode *dp)
+{
+ if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
+ return DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo);
+ else
+ return DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo);
+}
+
static ssize_t
pin_assignment_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
@@ -446,10 +458,7 @@ pin_assignment_store(struct device *dev, struct device_attribute *attr,
goto out_unlock;
}
- if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
- assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo);
- else
- assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo);
+ assignments = get_current_pin_assignments(dp);
if (!(DP_CONF_GET_PIN_ASSIGN(conf) & assignments)) {
ret = -EINVAL;
@@ -486,10 +495,7 @@ static ssize_t pin_assignment_show(struct device *dev,
cur = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf));
- if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
- assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo);
- else
- assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo);
+ assignments = get_current_pin_assignments(dp);
for (i = 0; assignments; assignments >>= 1, i++) {
if (assignments & 1) {
--
2.39.0.314.g84b9a713c41-goog