Skip to content

Commit cc1d4ec

Browse files
committed
Merge: sctp: stable backport for 9.7 phase 2
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6735 JIRA: https://issues.redhat.com/browse/RHEL-84590 Tested: compile only Signed-off-by: Xin Long <lxin@redhat.com> Approved-by: Davide Caratti <dcaratti@redhat.com> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents fb39c95 + d0eadd7 commit cc1d4ec

File tree

4 files changed

+30
-15
lines changed

4 files changed

+30
-15
lines changed

include/net/sctp/structs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,7 @@ struct sctp_transport {
775775

776776
/* Reference counting. */
777777
refcount_t refcnt;
778+
__u32 dead:1,
778779
/* RTO-Pending : A flag used to track if one of the DATA
779780
* chunks sent to this address is currently being
780781
* used to compute a RTT. If this flag is 0,
@@ -784,7 +785,7 @@ struct sctp_transport {
784785
* calculation completes (i.e. the DATA chunk
785786
* is SACK'd) clear this flag.
786787
*/
787-
__u32 rto_pending:1,
788+
rto_pending:1,
788789

789790
/*
790791
* hb_sent : a flag that signals that we have a pending

net/sctp/socket.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@
7272
/* Forward declarations for internal helper functions. */
7373
static bool sctp_writeable(const struct sock *sk);
7474
static void sctp_wfree(struct sk_buff *skb);
75-
static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
76-
size_t msg_len);
75+
static int sctp_wait_for_sndbuf(struct sctp_association *asoc,
76+
struct sctp_transport *transport,
77+
long *timeo_p, size_t msg_len);
7778
static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p);
7879
static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
7980
static int sctp_wait_for_accept(struct sock *sk, long timeo);
@@ -1828,7 +1829,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
18281829

18291830
if (sctp_wspace(asoc) <= 0 || !sk_wmem_schedule(sk, msg_len)) {
18301831
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1831-
err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
1832+
err = sctp_wait_for_sndbuf(asoc, transport, &timeo, msg_len);
18321833
if (err)
18331834
goto err;
18341835
if (unlikely(sinfo->sinfo_stream >= asoc->stream.outcnt)) {
@@ -9214,8 +9215,9 @@ void sctp_sock_rfree(struct sk_buff *skb)
92149215

92159216

92169217
/* Helper function to wait for space in the sndbuf. */
9217-
static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
9218-
size_t msg_len)
9218+
static int sctp_wait_for_sndbuf(struct sctp_association *asoc,
9219+
struct sctp_transport *transport,
9220+
long *timeo_p, size_t msg_len)
92199221
{
92209222
struct sock *sk = asoc->base.sk;
92219223
long current_timeo = *timeo_p;
@@ -9225,7 +9227,9 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
92259227
pr_debug("%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc,
92269228
*timeo_p, msg_len);
92279229

9228-
/* Increment the association's refcnt. */
9230+
/* Increment the transport and association's refcnt. */
9231+
if (transport)
9232+
sctp_transport_hold(transport);
92299233
sctp_association_hold(asoc);
92309234

92319235
/* Wait on the association specific sndbuf space. */
@@ -9234,7 +9238,7 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
92349238
TASK_INTERRUPTIBLE);
92359239
if (asoc->base.dead)
92369240
goto do_dead;
9237-
if (!*timeo_p)
9241+
if ((!*timeo_p) || (transport && transport->dead))
92389242
goto do_nonblock;
92399243
if (sk->sk_err || asoc->state >= SCTP_STATE_SHUTDOWN_PENDING)
92409244
goto do_error;
@@ -9259,7 +9263,9 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
92599263
out:
92609264
finish_wait(&asoc->wait, &wait);
92619265

9262-
/* Release the association's refcnt. */
9266+
/* Release the transport and association's refcnt. */
9267+
if (transport)
9268+
sctp_transport_put(transport);
92639269
sctp_association_put(asoc);
92649270

92659271
return err;

net/sctp/sysctl.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ static struct ctl_table sctp_net_table[] = {
391391
static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
392392
void *buffer, size_t *lenp, loff_t *ppos)
393393
{
394-
struct net *net = current->nsproxy->net_ns;
394+
struct net *net = container_of(ctl->data, struct net,
395+
sctp.sctp_hmac_alg);
395396
struct ctl_table tbl;
396397
bool changed = false;
397398
char *none = "none";
@@ -436,7 +437,7 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
436437
static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
437438
void *buffer, size_t *lenp, loff_t *ppos)
438439
{
439-
struct net *net = current->nsproxy->net_ns;
440+
struct net *net = container_of(ctl->data, struct net, sctp.rto_min);
440441
unsigned int min = *(unsigned int *) ctl->extra1;
441442
unsigned int max = *(unsigned int *) ctl->extra2;
442443
struct ctl_table tbl;
@@ -464,7 +465,7 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
464465
static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
465466
void *buffer, size_t *lenp, loff_t *ppos)
466467
{
467-
struct net *net = current->nsproxy->net_ns;
468+
struct net *net = container_of(ctl->data, struct net, sctp.rto_max);
468469
unsigned int min = *(unsigned int *) ctl->extra1;
469470
unsigned int max = *(unsigned int *) ctl->extra2;
470471
struct ctl_table tbl;
@@ -502,7 +503,7 @@ static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
502503
static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
503504
void *buffer, size_t *lenp, loff_t *ppos)
504505
{
505-
struct net *net = current->nsproxy->net_ns;
506+
struct net *net = container_of(ctl->data, struct net, sctp.auth_enable);
506507
struct ctl_table tbl;
507508
int new_value, ret;
508509

@@ -528,10 +529,12 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
528529
return ret;
529530
}
530531

532+
static DEFINE_MUTEX(sctp_sysctl_mutex);
533+
531534
static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
532535
void *buffer, size_t *lenp, loff_t *ppos)
533536
{
534-
struct net *net = current->nsproxy->net_ns;
537+
struct net *net = container_of(ctl->data, struct net, sctp.udp_port);
535538
unsigned int min = *(unsigned int *)ctl->extra1;
536539
unsigned int max = *(unsigned int *)ctl->extra2;
537540
struct ctl_table tbl;
@@ -552,6 +555,7 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
552555
if (new_value > max || new_value < min)
553556
return -EINVAL;
554557

558+
mutex_lock(&sctp_sysctl_mutex);
555559
net->sctp.udp_port = new_value;
556560
sctp_udp_sock_stop(net);
557561
if (new_value) {
@@ -564,6 +568,7 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
564568
lock_sock(sk);
565569
sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
566570
release_sock(sk);
571+
mutex_unlock(&sctp_sysctl_mutex);
567572
}
568573

569574
return ret;
@@ -572,7 +577,8 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
572577
static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
573578
void *buffer, size_t *lenp, loff_t *ppos)
574579
{
575-
struct net *net = current->nsproxy->net_ns;
580+
struct net *net = container_of(ctl->data, struct net,
581+
sctp.probe_interval);
576582
struct ctl_table tbl;
577583
int ret, new_value;
578584

net/sctp/transport.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ struct sctp_transport *sctp_transport_new(struct net *net,
117117
*/
118118
void sctp_transport_free(struct sctp_transport *transport)
119119
{
120+
transport->dead = 1;
121+
120122
/* Try to delete the heartbeat timer. */
121123
if (del_timer(&transport->hb_timer))
122124
sctp_transport_put(transport);

0 commit comments

Comments
 (0)