aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorwangweidong <wangweidong1@huawei.com>2013-12-10 20:50:38 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-10 22:54:34 -0500
commit85f935d41af097a87067367be66de52896b964e1 (patch)
tree80f8717fe0c3df5009675763c566aba726e22f18 /net/sctp/socket.c
parentce7a3bdf18a8dbcba1409f5d335c56fde432ca89 (diff)
sctp: check the rto_min and rto_max in setsockopt
When we set 0 to rto_min or rto_max, just not change the value. Also we should check the rto_min > rto_max. Suggested-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: Wang Weidong <wangweidong1@huawei.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5455043f4496..42b709c95cf3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2815,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
2815{ 2815{
2816 struct sctp_rtoinfo rtoinfo; 2816 struct sctp_rtoinfo rtoinfo;
2817 struct sctp_association *asoc; 2817 struct sctp_association *asoc;
2818 unsigned long rto_min, rto_max;
2819 struct sctp_sock *sp = sctp_sk(sk);
2818 2820
2819 if (optlen != sizeof (struct sctp_rtoinfo)) 2821 if (optlen != sizeof (struct sctp_rtoinfo))
2820 return -EINVAL; 2822 return -EINVAL;
@@ -2828,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
2828 if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) 2830 if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP))
2829 return -EINVAL; 2831 return -EINVAL;
2830 2832
2833 rto_max = rtoinfo.srto_max;
2834 rto_min = rtoinfo.srto_min;
2835
2836 if (rto_max)
2837 rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max;
2838 else
2839 rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max;
2840
2841 if (rto_min)
2842 rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min;
2843 else
2844 rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min;
2845
2846 if (rto_min > rto_max)
2847 return -EINVAL;
2848
2831 if (asoc) { 2849 if (asoc) {
2832 if (rtoinfo.srto_initial != 0) 2850 if (rtoinfo.srto_initial != 0)
2833 asoc->rto_initial = 2851 asoc->rto_initial =
2834 msecs_to_jiffies(rtoinfo.srto_initial); 2852 msecs_to_jiffies(rtoinfo.srto_initial);
2835 if (rtoinfo.srto_max != 0) 2853 asoc->rto_max = rto_max;
2836 asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max); 2854 asoc->rto_min = rto_min;
2837 if (rtoinfo.srto_min != 0)
2838 asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min);
2839 } else { 2855 } else {
2840 /* If there is no association or the association-id = 0 2856 /* If there is no association or the association-id = 0
2841 * set the values to the endpoint. 2857 * set the values to the endpoint.
2842 */ 2858 */
2843 struct sctp_sock *sp = sctp_sk(sk);
2844
2845 if (rtoinfo.srto_initial != 0) 2859 if (rtoinfo.srto_initial != 0)
2846 sp->rtoinfo.srto_initial = rtoinfo.srto_initial; 2860 sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
2847 if (rtoinfo.srto_max != 0) 2861 sp->rtoinfo.srto_max = rto_max;
2848 sp->rtoinfo.srto_max = rtoinfo.srto_max; 2862 sp->rtoinfo.srto_min = rto_min;
2849 if (rtoinfo.srto_min != 0)
2850 sp->rtoinfo.srto_min = rtoinfo.srto_min;
2851 } 2863 }
2852 2864
2853 return 0; 2865 return 0;