sctp: fix incorrect overflow check on autoclose
Commit8ffd3208
voids the previous patchesf6778aab
and810c0719
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: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Xi Wang <xi.wang@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2ca6cf06d9
commit
2692ba61a8
|
@ -241,6 +241,9 @@ extern struct sctp_globals {
|
||||||
* bits is an indicator of when to send and window update SACK.
|
* bits is an indicator of when to send and window update SACK.
|
||||||
*/
|
*/
|
||||||
int rwnd_update_shift;
|
int rwnd_update_shift;
|
||||||
|
|
||||||
|
/* Threshold for autoclose timeout, in seconds. */
|
||||||
|
unsigned long max_autoclose;
|
||||||
} sctp_globals;
|
} sctp_globals;
|
||||||
|
|
||||||
#define sctp_rto_initial (sctp_globals.rto_initial)
|
#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_auth_enable (sctp_globals.auth_enable)
|
||||||
#define sctp_checksum_disable (sctp_globals.checksum_disable)
|
#define sctp_checksum_disable (sctp_globals.checksum_disable)
|
||||||
#define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift)
|
#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. */
|
/* SCTP Socket type: UDP or TCP style. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -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_HEARTBEAT] = 0;
|
||||||
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
|
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
|
||||||
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
|
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
|
||||||
(unsigned long)sp->autoclose * HZ;
|
min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ;
|
||||||
|
|
||||||
/* Initializes the timers */
|
/* Initializes the timers */
|
||||||
for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
|
for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
|
||||||
|
|
|
@ -1285,6 +1285,9 @@ SCTP_STATIC __init int sctp_init(void)
|
||||||
sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
|
sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
|
||||||
sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
|
sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
|
||||||
|
|
||||||
|
/* Initialize maximum autoclose timeout. */
|
||||||
|
sctp_max_autoclose = INT_MAX / HZ;
|
||||||
|
|
||||||
/* Initialize handle used for association ids. */
|
/* Initialize handle used for association ids. */
|
||||||
idr_init(&sctp_assocs_id);
|
idr_init(&sctp_assocs_id);
|
||||||
|
|
||||||
|
|
|
@ -2200,8 +2200,6 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (copy_from_user(&sp->autoclose, optval, optlen))
|
if (copy_from_user(&sp->autoclose, optval, optlen))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
|
|
||||||
sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ static int sack_timer_min = 1;
|
||||||
static int sack_timer_max = 500;
|
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 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 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 long sysctl_sctp_mem[3];
|
||||||
extern int sysctl_sctp_rmem[3];
|
extern int sysctl_sctp_rmem[3];
|
||||||
|
@ -258,6 +262,15 @@ static ctl_table sctp_table[] = {
|
||||||
.extra1 = &one,
|
.extra1 = &one,
|
||||||
.extra2 = &rwnd_scale_max,
|
.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 */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue