aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-08-26 12:56:05 -0400
committerSteve French <sfrench@us.ibm.com>2008-08-26 12:56:05 -0400
commit3dae49abef945c55c10fa7c479cfd8fd13af55db (patch)
tree487c47c6d23cc28a259b913396aeaff0b792d32d /net/sctp/socket.c
parent6ce5eecb9cd3ac97b952c50309b87c31488a45e9 (diff)
parentb8e6c91c74e9f0279b7c51048779b3d62da60b88 (diff)
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c90
1 files changed, 70 insertions, 20 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index dbb79adf8f3c..afa952e726d7 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3055,6 +3055,9 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
3055{ 3055{
3056 struct sctp_authchunk val; 3056 struct sctp_authchunk val;
3057 3057
3058 if (!sctp_auth_enable)
3059 return -EACCES;
3060
3058 if (optlen != sizeof(struct sctp_authchunk)) 3061 if (optlen != sizeof(struct sctp_authchunk))
3059 return -EINVAL; 3062 return -EINVAL;
3060 if (copy_from_user(&val, optval, optlen)) 3063 if (copy_from_user(&val, optval, optlen))
@@ -3085,6 +3088,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
3085 struct sctp_hmacalgo *hmacs; 3088 struct sctp_hmacalgo *hmacs;
3086 int err; 3089 int err;
3087 3090
3091 if (!sctp_auth_enable)
3092 return -EACCES;
3093
3088 if (optlen < sizeof(struct sctp_hmacalgo)) 3094 if (optlen < sizeof(struct sctp_hmacalgo))
3089 return -EINVAL; 3095 return -EINVAL;
3090 3096
@@ -3123,6 +3129,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
3123 struct sctp_association *asoc; 3129 struct sctp_association *asoc;
3124 int ret; 3130 int ret;
3125 3131
3132 if (!sctp_auth_enable)
3133 return -EACCES;
3134
3126 if (optlen <= sizeof(struct sctp_authkey)) 3135 if (optlen <= sizeof(struct sctp_authkey))
3127 return -EINVAL; 3136 return -EINVAL;
3128 3137
@@ -3135,6 +3144,11 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
3135 goto out; 3144 goto out;
3136 } 3145 }
3137 3146
3147 if (authkey->sca_keylength > optlen) {
3148 ret = -EINVAL;
3149 goto out;
3150 }
3151
3138 asoc = sctp_id2assoc(sk, authkey->sca_assoc_id); 3152 asoc = sctp_id2assoc(sk, authkey->sca_assoc_id);
3139 if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) { 3153 if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) {
3140 ret = -EINVAL; 3154 ret = -EINVAL;
@@ -3160,6 +3174,9 @@ static int sctp_setsockopt_active_key(struct sock *sk,
3160 struct sctp_authkeyid val; 3174 struct sctp_authkeyid val;
3161 struct sctp_association *asoc; 3175 struct sctp_association *asoc;
3162 3176
3177 if (!sctp_auth_enable)
3178 return -EACCES;
3179
3163 if (optlen != sizeof(struct sctp_authkeyid)) 3180 if (optlen != sizeof(struct sctp_authkeyid))
3164 return -EINVAL; 3181 return -EINVAL;
3165 if (copy_from_user(&val, optval, optlen)) 3182 if (copy_from_user(&val, optval, optlen))
@@ -3185,6 +3202,9 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3185 struct sctp_authkeyid val; 3202 struct sctp_authkeyid val;
3186 struct sctp_association *asoc; 3203 struct sctp_association *asoc;
3187 3204
3205 if (!sctp_auth_enable)
3206 return -EACCES;
3207
3188 if (optlen != sizeof(struct sctp_authkeyid)) 3208 if (optlen != sizeof(struct sctp_authkeyid))
3189 return -EINVAL; 3209 return -EINVAL;
3190 if (copy_from_user(&val, optval, optlen)) 3210 if (copy_from_user(&val, optval, optlen))
@@ -5197,19 +5217,29 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5197static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, 5217static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
5198 char __user *optval, int __user *optlen) 5218 char __user *optval, int __user *optlen)
5199{ 5219{
5220 struct sctp_hmacalgo __user *p = (void __user *)optval;
5200 struct sctp_hmac_algo_param *hmacs; 5221 struct sctp_hmac_algo_param *hmacs;
5201 __u16 param_len; 5222 __u16 data_len = 0;
5223 u32 num_idents;
5224
5225 if (!sctp_auth_enable)
5226 return -EACCES;
5202 5227
5203 hmacs = sctp_sk(sk)->ep->auth_hmacs_list; 5228 hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
5204 param_len = ntohs(hmacs->param_hdr.length); 5229 data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
5205 5230
5206 if (len < param_len) 5231 if (len < sizeof(struct sctp_hmacalgo) + data_len)
5207 return -EINVAL; 5232 return -EINVAL;
5233
5234 len = sizeof(struct sctp_hmacalgo) + data_len;
5235 num_idents = data_len / sizeof(u16);
5236
5208 if (put_user(len, optlen)) 5237 if (put_user(len, optlen))
5209 return -EFAULT; 5238 return -EFAULT;
5210 if (copy_to_user(optval, hmacs->hmac_ids, len)) 5239 if (put_user(num_idents, &p->shmac_num_idents))
5240 return -EFAULT;
5241 if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
5211 return -EFAULT; 5242 return -EFAULT;
5212
5213 return 0; 5243 return 0;
5214} 5244}
5215 5245
@@ -5219,6 +5249,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
5219 struct sctp_authkeyid val; 5249 struct sctp_authkeyid val;
5220 struct sctp_association *asoc; 5250 struct sctp_association *asoc;
5221 5251
5252 if (!sctp_auth_enable)
5253 return -EACCES;
5254
5222 if (len < sizeof(struct sctp_authkeyid)) 5255 if (len < sizeof(struct sctp_authkeyid))
5223 return -EINVAL; 5256 return -EINVAL;
5224 if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) 5257 if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid)))
@@ -5233,6 +5266,12 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
5233 else 5266 else
5234 val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; 5267 val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
5235 5268
5269 len = sizeof(struct sctp_authkeyid);
5270 if (put_user(len, optlen))
5271 return -EFAULT;
5272 if (copy_to_user(optval, &val, len))
5273 return -EFAULT;
5274
5236 return 0; 5275 return 0;
5237} 5276}
5238 5277
@@ -5243,13 +5282,16 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5243 struct sctp_authchunks val; 5282 struct sctp_authchunks val;
5244 struct sctp_association *asoc; 5283 struct sctp_association *asoc;
5245 struct sctp_chunks_param *ch; 5284 struct sctp_chunks_param *ch;
5246 u32 num_chunks; 5285 u32 num_chunks = 0;
5247 char __user *to; 5286 char __user *to;
5248 5287
5249 if (len <= sizeof(struct sctp_authchunks)) 5288 if (!sctp_auth_enable)
5289 return -EACCES;
5290
5291 if (len < sizeof(struct sctp_authchunks))
5250 return -EINVAL; 5292 return -EINVAL;
5251 5293
5252 if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) 5294 if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
5253 return -EFAULT; 5295 return -EFAULT;
5254 5296
5255 to = p->gauth_chunks; 5297 to = p->gauth_chunks;
@@ -5258,20 +5300,21 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5258 return -EINVAL; 5300 return -EINVAL;
5259 5301
5260 ch = asoc->peer.peer_chunks; 5302 ch = asoc->peer.peer_chunks;
5303 if (!ch)
5304 goto num;
5261 5305
5262 /* See if the user provided enough room for all the data */ 5306 /* See if the user provided enough room for all the data */
5263 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); 5307 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
5264 if (len < num_chunks) 5308 if (len < num_chunks)
5265 return -EINVAL; 5309 return -EINVAL;
5266 5310
5267 len = num_chunks; 5311 if (copy_to_user(to, ch->chunks, num_chunks))
5268 if (put_user(len, optlen))
5269 return -EFAULT; 5312 return -EFAULT;
5313num:
5314 len = sizeof(struct sctp_authchunks) + num_chunks;
5315 if (put_user(len, optlen)) return -EFAULT;
5270 if (put_user(num_chunks, &p->gauth_number_of_chunks)) 5316 if (put_user(num_chunks, &p->gauth_number_of_chunks))
5271 return -EFAULT; 5317 return -EFAULT;
5272 if (copy_to_user(to, ch->chunks, len))
5273 return -EFAULT;
5274
5275 return 0; 5318 return 0;
5276} 5319}
5277 5320
@@ -5282,13 +5325,16 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5282 struct sctp_authchunks val; 5325 struct sctp_authchunks val;
5283 struct sctp_association *asoc; 5326 struct sctp_association *asoc;
5284 struct sctp_chunks_param *ch; 5327 struct sctp_chunks_param *ch;
5285 u32 num_chunks; 5328 u32 num_chunks = 0;
5286 char __user *to; 5329 char __user *to;
5287 5330
5288 if (len <= sizeof(struct sctp_authchunks)) 5331 if (!sctp_auth_enable)
5332 return -EACCES;
5333
5334 if (len < sizeof(struct sctp_authchunks))
5289 return -EINVAL; 5335 return -EINVAL;
5290 5336
5291 if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) 5337 if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
5292 return -EFAULT; 5338 return -EFAULT;
5293 5339
5294 to = p->gauth_chunks; 5340 to = p->gauth_chunks;
@@ -5301,17 +5347,21 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5301 else 5347 else
5302 ch = sctp_sk(sk)->ep->auth_chunk_list; 5348 ch = sctp_sk(sk)->ep->auth_chunk_list;
5303 5349
5350 if (!ch)
5351 goto num;
5352
5304 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); 5353 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
5305 if (len < num_chunks) 5354 if (len < sizeof(struct sctp_authchunks) + num_chunks)
5306 return -EINVAL; 5355 return -EINVAL;
5307 5356
5308 len = num_chunks; 5357 if (copy_to_user(to, ch->chunks, num_chunks))
5358 return -EFAULT;
5359num:
5360 len = sizeof(struct sctp_authchunks) + num_chunks;
5309 if (put_user(len, optlen)) 5361 if (put_user(len, optlen))
5310 return -EFAULT; 5362 return -EFAULT;
5311 if (put_user(num_chunks, &p->gauth_number_of_chunks)) 5363 if (put_user(num_chunks, &p->gauth_number_of_chunks))
5312 return -EFAULT; 5364 return -EFAULT;
5313 if (copy_to_user(to, ch->chunks, len))
5314 return -EFAULT;
5315 5365
5316 return 0; 5366 return 0;
5317} 5367}