Skip to content

Commit 16942cf

Browse files
q2venkuba-moo
authored andcommitted
sctp: Use sk_clone() in sctp_accept().
sctp_accept() calls sctp_v[46]_create_accept_sk() to allocate a new socket and calls sctp_sock_migrate() to copy fields from the parent socket to the new socket. sctp_v4_create_accept_sk() allocates sk by sk_alloc(), initialises it by sock_init_data(), and copy a bunch of fields from the parent socekt by sctp_copy_sock(). sctp_sock_migrate() calls sctp_copy_descendant() to copy most fields in sctp_sock from the parent socket by memcpy(). These can be simply replaced by sk_clone(). Let's consolidate sctp_v[46]_create_accept_sk() to sctp_clone_sock() with sk_clone(). We will reuse sctp_clone_sock() for sctp_do_peeloff() and then remove sctp_copy_descendant(). Note that sock_reset_flag(newsk, SOCK_ZAPPED) is not copied to sctp_clone_sock() as sctp does not use SOCK_ZAPPED at all. Signed-off-by: Kuniyuki Iwashima <[email protected]> Acked-by: Xin Long <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 151b98d commit 16942cf

File tree

2 files changed

+77
-40
lines changed

2 files changed

+77
-40
lines changed

net/ipv4/af_inet.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,9 +755,7 @@ EXPORT_SYMBOL(inet_stream_connect);
755755

756756
void __inet_accept(struct socket *sock, struct socket *newsock, struct sock *newsk)
757757
{
758-
/* TODO: use sk_clone_lock() in SCTP and remove protocol checks */
759-
if (mem_cgroup_sockets_enabled &&
760-
(!IS_ENABLED(CONFIG_IP_SCTP) || sk_is_tcp(newsk))) {
758+
if (mem_cgroup_sockets_enabled) {
761759
gfp_t gfp = GFP_KERNEL | __GFP_NOFAIL;
762760

763761
mem_cgroup_sk_alloc(newsk);

net/sctp/socket.c

Lines changed: 76 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4842,6 +4842,74 @@ static int sctp_disconnect(struct sock *sk, int flags)
48424842
return 0;
48434843
}
48444844

4845+
static struct sock *sctp_clone_sock(struct sock *sk,
4846+
struct sctp_association *asoc,
4847+
enum sctp_socket_type type)
4848+
{
4849+
struct sock *newsk = sk_clone(sk, GFP_KERNEL, false);
4850+
struct inet_sock *newinet;
4851+
struct sctp_sock *newsp;
4852+
int err = -ENOMEM;
4853+
4854+
if (!newsk)
4855+
return ERR_PTR(err);
4856+
4857+
/* sk_clone() sets refcnt to 2 */
4858+
sock_put(newsk);
4859+
4860+
newinet = inet_sk(newsk);
4861+
newsp = sctp_sk(newsk);
4862+
4863+
newsp->pf->to_sk_daddr(&asoc->peer.primary_addr, newsk);
4864+
newinet->inet_dport = htons(asoc->peer.port);
4865+
4866+
newsp->pf->copy_ip_options(sk, newsk);
4867+
atomic_set(&newinet->inet_id, get_random_u16());
4868+
4869+
inet_set_bit(MC_LOOP, newsk);
4870+
newinet->mc_ttl = 1;
4871+
newinet->mc_index = 0;
4872+
newinet->mc_list = NULL;
4873+
4874+
#if IS_ENABLED(CONFIG_IPV6)
4875+
if (sk->sk_family == AF_INET6) {
4876+
struct ipv6_pinfo *newnp = inet6_sk(newsk);
4877+
4878+
newinet->pinet6 = &((struct sctp6_sock *)newsk)->inet6;
4879+
newinet->ipv6_fl_list = NULL;
4880+
4881+
memcpy(newnp, inet6_sk(sk), sizeof(struct ipv6_pinfo));
4882+
newnp->ipv6_mc_list = NULL;
4883+
newnp->ipv6_ac_list = NULL;
4884+
}
4885+
#endif
4886+
4887+
skb_queue_head_init(&newsp->pd_lobby);
4888+
4889+
newsp->ep = sctp_endpoint_new(newsk, GFP_KERNEL);
4890+
if (!newsp->ep)
4891+
goto out_release;
4892+
4893+
SCTP_DBG_OBJCNT_INC(sock);
4894+
sk_sockets_allocated_inc(newsk);
4895+
sock_prot_inuse_add(sock_net(sk), newsk->sk_prot, 1);
4896+
4897+
err = sctp_sock_migrate(sk, newsk, asoc, type);
4898+
if (err)
4899+
goto out_release;
4900+
4901+
/* Set newsk security attributes from original sk and connection
4902+
* security attribute from asoc.
4903+
*/
4904+
security_sctp_sk_clone(asoc, sk, newsk);
4905+
4906+
return newsk;
4907+
4908+
out_release:
4909+
sk_common_release(newsk);
4910+
return ERR_PTR(err);
4911+
}
4912+
48454913
/* 4.1.4 accept() - TCP Style Syntax
48464914
*
48474915
* Applications use accept() call to remove an established SCTP
@@ -4851,18 +4919,13 @@ static int sctp_disconnect(struct sock *sk, int flags)
48514919
*/
48524920
static struct sock *sctp_accept(struct sock *sk, struct proto_accept_arg *arg)
48534921
{
4854-
struct sctp_sock *sp, *newsp;
4855-
struct sctp_endpoint *ep;
4856-
struct sock *newsk = NULL;
48574922
struct sctp_association *asoc;
4858-
long timeo;
4923+
struct sock *newsk = NULL;
48594924
int error = 0;
4925+
long timeo;
48604926

48614927
lock_sock(sk);
48624928

4863-
sp = sctp_sk(sk);
4864-
ep = sp->ep;
4865-
48664929
if (!sctp_style(sk, TCP)) {
48674930
error = -EOPNOTSUPP;
48684931
goto out;
@@ -4883,43 +4946,19 @@ static struct sock *sctp_accept(struct sock *sk, struct proto_accept_arg *arg)
48834946
/* We treat the list of associations on the endpoint as the accept
48844947
* queue and pick the first association on the list.
48854948
*/
4886-
asoc = list_entry(ep->asocs.next, struct sctp_association, asocs);
4887-
4888-
newsk = sp->pf->create_accept_sk(sk, asoc, arg->kern);
4889-
if (!newsk) {
4890-
error = -ENOMEM;
4891-
goto out;
4892-
}
4949+
asoc = list_entry(sctp_sk(sk)->ep->asocs.next,
4950+
struct sctp_association, asocs);
48934951

4894-
newsp = sctp_sk(newsk);
4895-
newsp->ep = sctp_endpoint_new(newsk, GFP_KERNEL);
4896-
if (!newsp->ep) {
4897-
error = -ENOMEM;
4898-
goto out_release;
4952+
newsk = sctp_clone_sock(sk, asoc, SCTP_SOCKET_TCP);
4953+
if (IS_ERR(newsk)) {
4954+
error = PTR_ERR(newsk);
4955+
newsk = NULL;
48994956
}
49004957

4901-
skb_queue_head_init(&newsp->pd_lobby);
4902-
4903-
sk_sockets_allocated_inc(newsk);
4904-
sock_prot_inuse_add(sock_net(sk), newsk->sk_prot, 1);
4905-
SCTP_DBG_OBJCNT_INC(sock);
4906-
4907-
/* Populate the fields of the newsk from the oldsk and migrate the
4908-
* asoc to the newsk.
4909-
*/
4910-
error = sctp_sock_migrate(sk, newsk, asoc, SCTP_SOCKET_TCP);
4911-
if (error)
4912-
goto out_release;
4913-
49144958
out:
49154959
release_sock(sk);
49164960
arg->err = error;
49174961
return newsk;
4918-
4919-
out_release:
4920-
sk_common_release(newsk);
4921-
newsk = NULL;
4922-
goto out;
49234962
}
49244963

49254964
/* The SCTP ioctl handler. */

0 commit comments

Comments
 (0)