aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c96
1 files changed, 74 insertions, 22 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index dbb79adf8f3c..5ffb9dec1c3f 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))
@@ -3083,8 +3086,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
3083 int optlen) 3086 int optlen)
3084{ 3087{
3085 struct sctp_hmacalgo *hmacs; 3088 struct sctp_hmacalgo *hmacs;
3089 u32 idents;
3086 int err; 3090 int err;
3087 3091
3092 if (!sctp_auth_enable)
3093 return -EACCES;
3094
3088 if (optlen < sizeof(struct sctp_hmacalgo)) 3095 if (optlen < sizeof(struct sctp_hmacalgo))
3089 return -EINVAL; 3096 return -EINVAL;
3090 3097
@@ -3097,8 +3104,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
3097 goto out; 3104 goto out;
3098 } 3105 }
3099 3106
3100 if (hmacs->shmac_num_idents == 0 || 3107 idents = hmacs->shmac_num_idents;
3101 hmacs->shmac_num_idents > SCTP_AUTH_NUM_HMACS) { 3108 if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS ||
3109 (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) {
3102 err = -EINVAL; 3110 err = -EINVAL;
3103 goto out; 3111 goto out;
3104 } 3112 }
@@ -3123,6 +3131,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
3123 struct sctp_association *asoc; 3131 struct sctp_association *asoc;
3124 int ret; 3132 int ret;
3125 3133
3134 if (!sctp_auth_enable)
3135 return -EACCES;
3136
3126 if (optlen <= sizeof(struct sctp_authkey)) 3137 if (optlen <= sizeof(struct sctp_authkey))
3127 return -EINVAL; 3138 return -EINVAL;
3128 3139
@@ -3135,6 +3146,11 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
3135 goto out; 3146 goto out;
3136 } 3147 }
3137 3148
3149 if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) {
3150 ret = -EINVAL;
3151 goto out;
3152 }
3153
3138 asoc = sctp_id2assoc(sk, authkey->sca_assoc_id); 3154 asoc = sctp_id2assoc(sk, authkey->sca_assoc_id);
3139 if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) { 3155 if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) {
3140 ret = -EINVAL; 3156 ret = -EINVAL;
@@ -3160,6 +3176,9 @@ static int sctp_setsockopt_active_key(struct sock *sk,
3160 struct sctp_authkeyid val; 3176 struct sctp_authkeyid val;
3161 struct sctp_association *asoc; 3177 struct sctp_association *asoc;
3162 3178
3179 if (!sctp_auth_enable)
3180 return -EACCES;
3181
3163 if (optlen != sizeof(struct sctp_authkeyid)) 3182 if (optlen != sizeof(struct sctp_authkeyid))
3164 return -EINVAL; 3183 return -EINVAL;
3165 if (copy_from_user(&val, optval, optlen)) 3184 if (copy_from_user(&val, optval, optlen))
@@ -3185,6 +3204,9 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3185 struct sctp_authkeyid val; 3204 struct sctp_authkeyid val;
3186 struct sctp_association *asoc; 3205 struct sctp_association *asoc;
3187 3206
3207 if (!sctp_auth_enable)
3208 return -EACCES;
3209
3188 if (optlen != sizeof(struct sctp_authkeyid)) 3210 if (optlen != sizeof(struct sctp_authkeyid))
3189 return -EINVAL; 3211 return -EINVAL;
3190 if (copy_from_user(&val, optval, optlen)) 3212 if (copy_from_user(&val, optval, optlen))
@@ -5197,19 +5219,29 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5197static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, 5219static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
5198 char __user *optval, int __user *optlen) 5220 char __user *optval, int __user *optlen)
5199{ 5221{
5222 struct sctp_hmacalgo __user *p = (void __user *)optval;
5200 struct sctp_hmac_algo_param *hmacs; 5223 struct sctp_hmac_algo_param *hmacs;
5201 __u16 param_len; 5224 __u16 data_len = 0;
5225 u32 num_idents;
5226
5227 if (!sctp_auth_enable)
5228 return -EACCES;
5202 5229
5203 hmacs = sctp_sk(sk)->ep->auth_hmacs_list; 5230 hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
5204 param_len = ntohs(hmacs->param_hdr.length); 5231 data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
5205 5232
5206 if (len < param_len) 5233 if (len < sizeof(struct sctp_hmacalgo) + data_len)
5207 return -EINVAL; 5234 return -EINVAL;
5235
5236 len = sizeof(struct sctp_hmacalgo) + data_len;
5237 num_idents = data_len / sizeof(u16);
5238
5208 if (put_user(len, optlen)) 5239 if (put_user(len, optlen))
5209 return -EFAULT; 5240 return -EFAULT;
5210 if (copy_to_user(optval, hmacs->hmac_ids, len)) 5241 if (put_user(num_idents, &p->shmac_num_idents))
5242 return -EFAULT;
5243 if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
5211 return -EFAULT; 5244 return -EFAULT;
5212
5213 return 0; 5245 return 0;
5214} 5246}
5215 5247
@@ -5219,6 +5251,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
5219 struct sctp_authkeyid val; 5251 struct sctp_authkeyid val;
5220 struct sctp_association *asoc; 5252 struct sctp_association *asoc;
5221 5253
5254 if (!sctp_auth_enable)
5255 return -EACCES;
5256
5222 if (len < sizeof(struct sctp_authkeyid)) 5257 if (len < sizeof(struct sctp_authkeyid))
5223 return -EINVAL; 5258 return -EINVAL;
5224 if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) 5259 if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid)))
@@ -5233,6 +5268,12 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
5233 else 5268 else
5234 val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; 5269 val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
5235 5270
5271 len = sizeof(struct sctp_authkeyid);
5272 if (put_user(len, optlen))
5273 return -EFAULT;
5274 if (copy_to_user(optval, &val, len))
5275 return -EFAULT;
5276
5236 return 0; 5277 return 0;
5237} 5278}
5238 5279
@@ -5243,13 +5284,16 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5243 struct sctp_authchunks val; 5284 struct sctp_authchunks val;
5244 struct sctp_association *asoc; 5285 struct sctp_association *asoc;
5245 struct sctp_chunks_param *ch; 5286 struct sctp_chunks_param *ch;
5246 u32 num_chunks; 5287 u32 num_chunks = 0;
5247 char __user *to; 5288 char __user *to;
5248 5289
5249 if (len <= sizeof(struct sctp_authchunks)) 5290 if (!sctp_auth_enable)
5291 return -EACCES;
5292
5293 if (len < sizeof(struct sctp_authchunks))
5250 return -EINVAL; 5294 return -EINVAL;
5251 5295
5252 if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) 5296 if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
5253 return -EFAULT; 5297 return -EFAULT;
5254 5298
5255 to = p->gauth_chunks; 5299 to = p->gauth_chunks;
@@ -5258,20 +5302,21 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5258 return -EINVAL; 5302 return -EINVAL;
5259 5303
5260 ch = asoc->peer.peer_chunks; 5304 ch = asoc->peer.peer_chunks;
5305 if (!ch)
5306 goto num;
5261 5307
5262 /* See if the user provided enough room for all the data */ 5308 /* See if the user provided enough room for all the data */
5263 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); 5309 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
5264 if (len < num_chunks) 5310 if (len < num_chunks)
5265 return -EINVAL; 5311 return -EINVAL;
5266 5312
5267 len = num_chunks; 5313 if (copy_to_user(to, ch->chunks, num_chunks))
5268 if (put_user(len, optlen))
5269 return -EFAULT; 5314 return -EFAULT;
5315num:
5316 len = sizeof(struct sctp_authchunks) + num_chunks;
5317 if (put_user(len, optlen)) return -EFAULT;
5270 if (put_user(num_chunks, &p->gauth_number_of_chunks)) 5318 if (put_user(num_chunks, &p->gauth_number_of_chunks))
5271 return -EFAULT; 5319 return -EFAULT;
5272 if (copy_to_user(to, ch->chunks, len))
5273 return -EFAULT;
5274
5275 return 0; 5320 return 0;
5276} 5321}
5277 5322
@@ -5282,13 +5327,16 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5282 struct sctp_authchunks val; 5327 struct sctp_authchunks val;
5283 struct sctp_association *asoc; 5328 struct sctp_association *asoc;
5284 struct sctp_chunks_param *ch; 5329 struct sctp_chunks_param *ch;
5285 u32 num_chunks; 5330 u32 num_chunks = 0;
5286 char __user *to; 5331 char __user *to;
5287 5332
5288 if (len <= sizeof(struct sctp_authchunks)) 5333 if (!sctp_auth_enable)
5334 return -EACCES;
5335
5336 if (len < sizeof(struct sctp_authchunks))
5289 return -EINVAL; 5337 return -EINVAL;
5290 5338
5291 if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) 5339 if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
5292 return -EFAULT; 5340 return -EFAULT;
5293 5341
5294 to = p->gauth_chunks; 5342 to = p->gauth_chunks;
@@ -5301,17 +5349,21 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5301 else 5349 else
5302 ch = sctp_sk(sk)->ep->auth_chunk_list; 5350 ch = sctp_sk(sk)->ep->auth_chunk_list;
5303 5351
5352 if (!ch)
5353 goto num;
5354
5304 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); 5355 num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
5305 if (len < num_chunks) 5356 if (len < sizeof(struct sctp_authchunks) + num_chunks)
5306 return -EINVAL; 5357 return -EINVAL;
5307 5358
5308 len = num_chunks; 5359 if (copy_to_user(to, ch->chunks, num_chunks))
5360 return -EFAULT;
5361num:
5362 len = sizeof(struct sctp_authchunks) + num_chunks;
5309 if (put_user(len, optlen)) 5363 if (put_user(len, optlen))
5310 return -EFAULT; 5364 return -EFAULT;
5311 if (put_user(num_chunks, &p->gauth_number_of_chunks)) 5365 if (put_user(num_chunks, &p->gauth_number_of_chunks))
5312 return -EFAULT; 5366 return -EFAULT;
5313 if (copy_to_user(to, ch->chunks, len))
5314 return -EFAULT;
5315 5367
5316 return 0; 5368 return 0;
5317} 5369}