aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-03-13 00:26:33 -0400
committerPaul Mackerras <paulus@samba.org>2008-03-13 00:26:33 -0400
commitbed04a4413376265746053be2a9cfbfc80c98ec9 (patch)
tree8f582294a655f70496cd08aedeb86de31dbad140 /net/sctp/socket.c
parente37c772e36a7943b2e0bd8f48312e78474c0df15 (diff)
parentc463be3520065ef8c05e3cbdf946c69604e91ceb (diff)
Merge branch 'linux-2.6'
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 44797ad88a05..d994d822900d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1964,7 +1964,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk,
1964static int sctp_setsockopt_events(struct sock *sk, char __user *optval, 1964static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
1965 int optlen) 1965 int optlen)
1966{ 1966{
1967 if (optlen != sizeof(struct sctp_event_subscribe)) 1967 if (optlen > sizeof(struct sctp_event_subscribe))
1968 return -EINVAL; 1968 return -EINVAL;
1969 if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) 1969 if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen))
1970 return -EFAULT; 1970 return -EFAULT;
@@ -2933,17 +2933,39 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
2933 char __user *optval, 2933 char __user *optval,
2934 int optlen) 2934 int optlen)
2935{ 2935{
2936 struct sctp_assoc_value params;
2937 struct sctp_sock *sp;
2938 struct sctp_association *asoc;
2936 int val; 2939 int val;
2940 int assoc_id = 0;
2937 2941
2938 if (optlen != sizeof(int)) 2942 if (optlen < sizeof(int))
2939 return -EINVAL; 2943 return -EINVAL;
2940 if (get_user(val, (int __user *)optval))
2941 return -EFAULT;
2942 2944
2943 if (val < 0) 2945 if (optlen == sizeof(int)) {
2946 printk(KERN_WARNING
2947 "SCTP: Use of int in max_burst socket option deprecated\n");
2948 printk(KERN_WARNING
2949 "SCTP: Use struct sctp_assoc_value instead\n");
2950 if (copy_from_user(&val, optval, optlen))
2951 return -EFAULT;
2952 } else if (optlen == sizeof(struct sctp_assoc_value)) {
2953 if (copy_from_user(&params, optval, optlen))
2954 return -EFAULT;
2955 val = params.assoc_value;
2956 assoc_id = params.assoc_id;
2957 } else
2944 return -EINVAL; 2958 return -EINVAL;
2945 2959
2946 sctp_sk(sk)->max_burst = val; 2960 sp = sctp_sk(sk);
2961
2962 if (assoc_id != 0) {
2963 asoc = sctp_id2assoc(sk, assoc_id);
2964 if (!asoc)
2965 return -EINVAL;
2966 asoc->max_burst = val;
2967 } else
2968 sp->max_burst = val;
2947 2969
2948 return 0; 2970 return 0;
2949} 2971}
@@ -5005,20 +5027,45 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5005 char __user *optval, 5027 char __user *optval,
5006 int __user *optlen) 5028 int __user *optlen)
5007{ 5029{
5008 int val; 5030 struct sctp_assoc_value params;
5031 struct sctp_sock *sp;
5032 struct sctp_association *asoc;
5009 5033
5010 if (len < sizeof(int)) 5034 if (len < sizeof(int))
5011 return -EINVAL; 5035 return -EINVAL;
5012 5036
5013 len = sizeof(int); 5037 if (len == sizeof(int)) {
5038 printk(KERN_WARNING
5039 "SCTP: Use of int in max_burst socket option deprecated\n");
5040 printk(KERN_WARNING
5041 "SCTP: Use struct sctp_assoc_value instead\n");
5042 params.assoc_id = 0;
5043 } else if (len == sizeof (struct sctp_assoc_value)) {
5044 if (copy_from_user(&params, optval, len))
5045 return -EFAULT;
5046 } else
5047 return -EINVAL;
5014 5048
5015 val = sctp_sk(sk)->max_burst; 5049 sp = sctp_sk(sk);
5016 if (put_user(len, optlen)) 5050
5017 return -EFAULT; 5051 if (params.assoc_id != 0) {
5018 if (copy_to_user(optval, &val, len)) 5052 asoc = sctp_id2assoc(sk, params.assoc_id);
5019 return -EFAULT; 5053 if (!asoc)
5054 return -EINVAL;
5055 params.assoc_value = asoc->max_burst;
5056 } else
5057 params.assoc_value = sp->max_burst;
5058
5059 if (len == sizeof(int)) {
5060 if (copy_to_user(optval, &params.assoc_value, len))
5061 return -EFAULT;
5062 } else {
5063 if (copy_to_user(optval, &params, len))
5064 return -EFAULT;
5065 }
5066
5067 return 0;
5020 5068
5021 return -ENOTSUPP;
5022} 5069}
5023 5070
5024static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, 5071static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
@@ -5070,6 +5117,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5070 struct sctp_authchunks val; 5117 struct sctp_authchunks val;
5071 struct sctp_association *asoc; 5118 struct sctp_association *asoc;
5072 struct sctp_chunks_param *ch; 5119 struct sctp_chunks_param *ch;
5120 u32 num_chunks;
5073 char __user *to; 5121 char __user *to;
5074 5122
5075 if (len <= sizeof(struct sctp_authchunks)) 5123 if (len <= sizeof(struct sctp_authchunks))
@@ -5086,12 +5134,15 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5086 ch = asoc->peer.peer_chunks; 5134 ch = asoc->peer.peer_chunks;
5087 5135
5088 /* See if the user provided enough room for all the data */ 5136 /* See if the user provided enough room for all the data */
5089 if (len < ntohs(ch->param_hdr.length)) 5137 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
5138 if (len < num_chunks)
5090 return -EINVAL; 5139 return -EINVAL;
5091 5140
5092 len = ntohs(ch->param_hdr.length); 5141 len = num_chunks;
5093 if (put_user(len, optlen)) 5142 if (put_user(len, optlen))
5094 return -EFAULT; 5143 return -EFAULT;
5144 if (put_user(num_chunks, &p->gauth_number_of_chunks))
5145 return -EFAULT;
5095 if (copy_to_user(to, ch->chunks, len)) 5146 if (copy_to_user(to, ch->chunks, len))
5096 return -EFAULT; 5147 return -EFAULT;
5097 5148
@@ -5105,6 +5156,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5105 struct sctp_authchunks val; 5156 struct sctp_authchunks val;
5106 struct sctp_association *asoc; 5157 struct sctp_association *asoc;
5107 struct sctp_chunks_param *ch; 5158 struct sctp_chunks_param *ch;
5159 u32 num_chunks;
5108 char __user *to; 5160 char __user *to;
5109 5161
5110 if (len <= sizeof(struct sctp_authchunks)) 5162 if (len <= sizeof(struct sctp_authchunks))
@@ -5123,12 +5175,15 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5123 else 5175 else
5124 ch = sctp_sk(sk)->ep->auth_chunk_list; 5176 ch = sctp_sk(sk)->ep->auth_chunk_list;
5125 5177
5126 if (len < ntohs(ch->param_hdr.length)) 5178 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
5179 if (len < num_chunks)
5127 return -EINVAL; 5180 return -EINVAL;
5128 5181
5129 len = ntohs(ch->param_hdr.length); 5182 len = num_chunks;
5130 if (put_user(len, optlen)) 5183 if (put_user(len, optlen))
5131 return -EFAULT; 5184 return -EFAULT;
5185 if (put_user(num_chunks, &p->gauth_number_of_chunks))
5186 return -EFAULT;
5132 if (copy_to_user(to, ch->chunks, len)) 5187 if (copy_to_user(to, ch->chunks, len))
5133 return -EFAULT; 5188 return -EFAULT;
5134 5189