mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
sctp: Use sctp_clone_sock() in sctp_do_peeloff().
sctp_do_peeloff() calls sock_create() to allocate and initialise struct sock, inet_sock, and sctp_sock, but later sctp_copy_sock() and sctp_sock_migrate() overwrite most fields. What sctp_do_peeloff() does is more like accept(). Let's use sock_create_lite() and sctp_clone_sock(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Acked-by: Xin Long <lucien.xin@gmail.com> Link: https://patch.msgid.link/20251023231751.4168390-8-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
c49ed521f1
commit
b7ddb55f31
@@ -788,6 +788,7 @@ void __inet_accept(struct socket *sock, struct socket *newsock, struct sock *new
|
||||
|
||||
newsock->state = SS_CONNECTED;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__inet_accept);
|
||||
|
||||
/*
|
||||
* Accept a pending connection. The TCP layer now gives BSD semantics.
|
||||
|
||||
@@ -5671,11 +5671,11 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
|
||||
|
||||
/* Helper routine to branch off an association to a new socket. */
|
||||
static int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id,
|
||||
struct socket **sockp)
|
||||
struct socket **sockp)
|
||||
{
|
||||
struct sctp_association *asoc = sctp_id2assoc(sk, id);
|
||||
struct sctp_sock *sp = sctp_sk(sk);
|
||||
struct socket *sock;
|
||||
struct sock *newsk;
|
||||
int err = 0;
|
||||
|
||||
/* Do not peel off from one netns to another one. */
|
||||
@@ -5691,30 +5691,24 @@ static int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id,
|
||||
if (!sctp_style(sk, UDP))
|
||||
return -EINVAL;
|
||||
|
||||
/* Create a new socket. */
|
||||
err = sock_create(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
|
||||
if (err < 0)
|
||||
err = sock_create_lite(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sctp_copy_sock(sock->sk, sk, asoc);
|
||||
|
||||
/* Make peeled-off sockets more like 1-1 accepted sockets.
|
||||
* Set the daddr and initialize id to something more random and also
|
||||
* copy over any ip options.
|
||||
*/
|
||||
sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sock->sk);
|
||||
sp->pf->copy_ip_options(sk, sock->sk);
|
||||
|
||||
/* Populate the fields of the newsk from the oldsk and migrate the
|
||||
* asoc to the newsk.
|
||||
*/
|
||||
err = sctp_sock_migrate(sk, sock->sk, asoc,
|
||||
SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
|
||||
if (err) {
|
||||
newsk = sctp_clone_sock(sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
|
||||
if (IS_ERR(newsk)) {
|
||||
sock_release(sock);
|
||||
sock = NULL;
|
||||
*sockp = NULL;
|
||||
return PTR_ERR(newsk);
|
||||
}
|
||||
|
||||
lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
|
||||
__inet_accept(sk->sk_socket, sock, newsk);
|
||||
release_sock(newsk);
|
||||
|
||||
sock->ops = sk->sk_socket->ops;
|
||||
__module_get(sock->ops->owner);
|
||||
|
||||
*sockp = sock;
|
||||
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user