diff options
author | wangweidong <wangweidong1@huawei.com> | 2013-12-10 20:50:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-10 22:54:34 -0500 |
commit | 85f935d41af097a87067367be66de52896b964e1 (patch) | |
tree | 80f8717fe0c3df5009675763c566aba726e22f18 /net/sctp/socket.c | |
parent | ce7a3bdf18a8dbcba1409f5d335c56fde432ca89 (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.c | 32 |
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; |