Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2692ba61 authored by Xi Wang's avatar Xi Wang Committed by David S. Miller
Browse files

sctp: fix incorrect overflow check on autoclose



Commit 8ffd3208 voids the previous patches f6778aab and 810c0719 for
limiting the autoclose value.  If userspace passes in -1 on 32-bit
platform, the overflow check didn't work and autoclose would be set
to 0xffffffff.

This patch defines a max_autoclose (in seconds) for limiting the value
and exposes it through sysctl, with the following intentions.

1) Avoid overflowing autoclose * HZ.

2) Keep the default autoclose bound consistent across 32- and 64-bit
   platforms (INT_MAX / HZ in this patch).

3) Keep the autoclose value consistent between setsockopt() and
   getsockopt() calls.

Suggested-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarXi Wang <xi.wang@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2ca6cf06
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -241,6 +241,9 @@ extern struct sctp_globals {
	 * bits is an indicator of when to send and window update SACK.
	 */
	int rwnd_update_shift;

	/* Threshold for autoclose timeout, in seconds. */
	unsigned long max_autoclose;
} sctp_globals;

#define sctp_rto_initial		(sctp_globals.rto_initial)
@@ -281,6 +284,7 @@ extern struct sctp_globals {
#define sctp_auth_enable		(sctp_globals.auth_enable)
#define sctp_checksum_disable		(sctp_globals.checksum_disable)
#define sctp_rwnd_upd_shift		(sctp_globals.rwnd_update_shift)
#define sctp_max_autoclose		(sctp_globals.max_autoclose)

/* SCTP Socket type: UDP or TCP style. */
typedef enum {
+1 −1
Original line number Diff line number Diff line
@@ -173,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
	asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
	asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
	asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
		(unsigned long)sp->autoclose * HZ;
		min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ;

	/* Initializes the timers */
	for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
+3 −0
Original line number Diff line number Diff line
@@ -1285,6 +1285,9 @@ SCTP_STATIC __init int sctp_init(void)
	sctp_max_instreams    		= SCTP_DEFAULT_INSTREAMS;
	sctp_max_outstreams   		= SCTP_DEFAULT_OUTSTREAMS;

	/* Initialize maximum autoclose timeout. */
	sctp_max_autoclose		= INT_MAX / HZ;

	/* Initialize handle used for association ids. */
	idr_init(&sctp_assocs_id);

+0 −2
Original line number Diff line number Diff line
@@ -2200,8 +2200,6 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
		return -EINVAL;
	if (copy_from_user(&sp->autoclose, optval, optlen))
		return -EFAULT;
	/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
	sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ);

	return 0;
}
+13 −0
Original line number Diff line number Diff line
@@ -53,6 +53,10 @@ static int sack_timer_min = 1;
static int sack_timer_max = 500;
static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
static int rwnd_scale_max = 16;
static unsigned long max_autoclose_min = 0;
static unsigned long max_autoclose_max =
	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;

extern long sysctl_sctp_mem[3];
extern int sysctl_sctp_rmem[3];
@@ -258,6 +262,15 @@ static ctl_table sctp_table[] = {
		.extra1		= &one,
		.extra2		= &rwnd_scale_max,
	},
	{
		.procname	= "max_autoclose",
		.data		= &sctp_max_autoclose,
		.maxlen		= sizeof(unsigned long),
		.mode		= 0644,
		.proc_handler	= &proc_doulongvec_minmax,
		.extra1		= &max_autoclose_min,
		.extra2		= &max_autoclose_max,
	},

	{ /* sentinel */ }
};