diff options
-rw-r--r-- | net/sctp/endpointola.c | 4 | ||||
-rw-r--r-- | net/sctp/socket.c | 85 |
2 files changed, 67 insertions, 22 deletions
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index e39a0cdef184..4c8d9f45ce09 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -103,6 +103,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
103 | 103 | ||
104 | /* Initialize the CHUNKS parameter */ | 104 | /* Initialize the CHUNKS parameter */ |
105 | auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; | 105 | auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; |
106 | auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t)); | ||
106 | 107 | ||
107 | /* If the Add-IP functionality is enabled, we must | 108 | /* If the Add-IP functionality is enabled, we must |
108 | * authenticate, ASCONF and ASCONF-ACK chunks | 109 | * authenticate, ASCONF and ASCONF-ACK chunks |
@@ -110,8 +111,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
110 | if (sctp_addip_enable) { | 111 | if (sctp_addip_enable) { |
111 | auth_chunks->chunks[0] = SCTP_CID_ASCONF; | 112 | auth_chunks->chunks[0] = SCTP_CID_ASCONF; |
112 | auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; | 113 | auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; |
113 | auth_chunks->param_hdr.length = | 114 | auth_chunks->param_hdr.length += htons(2); |
114 | htons(sizeof(sctp_paramhdr_t) + 2); | ||
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index dbb79adf8f3c..bb5c9ef13046 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 | ||
@@ -3160,6 +3169,9 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3160 | struct sctp_authkeyid val; | 3169 | struct sctp_authkeyid val; |
3161 | struct sctp_association *asoc; | 3170 | struct sctp_association *asoc; |
3162 | 3171 | ||
3172 | if (!sctp_auth_enable) | ||
3173 | return -EACCES; | ||
3174 | |||
3163 | if (optlen != sizeof(struct sctp_authkeyid)) | 3175 | if (optlen != sizeof(struct sctp_authkeyid)) |
3164 | return -EINVAL; | 3176 | return -EINVAL; |
3165 | if (copy_from_user(&val, optval, optlen)) | 3177 | if (copy_from_user(&val, optval, optlen)) |
@@ -3185,6 +3197,9 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3185 | struct sctp_authkeyid val; | 3197 | struct sctp_authkeyid val; |
3186 | struct sctp_association *asoc; | 3198 | struct sctp_association *asoc; |
3187 | 3199 | ||
3200 | if (!sctp_auth_enable) | ||
3201 | return -EACCES; | ||
3202 | |||
3188 | if (optlen != sizeof(struct sctp_authkeyid)) | 3203 | if (optlen != sizeof(struct sctp_authkeyid)) |
3189 | return -EINVAL; | 3204 | return -EINVAL; |
3190 | if (copy_from_user(&val, optval, optlen)) | 3205 | if (copy_from_user(&val, optval, optlen)) |
@@ -5197,19 +5212,29 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5197 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | 5212 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, |
5198 | char __user *optval, int __user *optlen) | 5213 | char __user *optval, int __user *optlen) |
5199 | { | 5214 | { |
5215 | struct sctp_hmacalgo __user *p = (void __user *)optval; | ||
5200 | struct sctp_hmac_algo_param *hmacs; | 5216 | struct sctp_hmac_algo_param *hmacs; |
5201 | __u16 param_len; | 5217 | __u16 data_len = 0; |
5218 | u32 num_idents; | ||
5219 | |||
5220 | if (!sctp_auth_enable) | ||
5221 | return -EACCES; | ||
5202 | 5222 | ||
5203 | hmacs = sctp_sk(sk)->ep->auth_hmacs_list; | 5223 | hmacs = sctp_sk(sk)->ep->auth_hmacs_list; |
5204 | param_len = ntohs(hmacs->param_hdr.length); | 5224 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5205 | 5225 | ||
5206 | if (len < param_len) | 5226 | if (len < sizeof(struct sctp_hmacalgo) + data_len) |
5207 | return -EINVAL; | 5227 | return -EINVAL; |
5228 | |||
5229 | len = sizeof(struct sctp_hmacalgo) + data_len; | ||
5230 | num_idents = data_len / sizeof(u16); | ||
5231 | |||
5208 | if (put_user(len, optlen)) | 5232 | if (put_user(len, optlen)) |
5209 | return -EFAULT; | 5233 | return -EFAULT; |
5210 | if (copy_to_user(optval, hmacs->hmac_ids, len)) | 5234 | if (put_user(num_idents, &p->shmac_num_idents)) |
5235 | return -EFAULT; | ||
5236 | if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len)) | ||
5211 | return -EFAULT; | 5237 | return -EFAULT; |
5212 | |||
5213 | return 0; | 5238 | return 0; |
5214 | } | 5239 | } |
5215 | 5240 | ||
@@ -5219,6 +5244,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5219 | struct sctp_authkeyid val; | 5244 | struct sctp_authkeyid val; |
5220 | struct sctp_association *asoc; | 5245 | struct sctp_association *asoc; |
5221 | 5246 | ||
5247 | if (!sctp_auth_enable) | ||
5248 | return -EACCES; | ||
5249 | |||
5222 | if (len < sizeof(struct sctp_authkeyid)) | 5250 | if (len < sizeof(struct sctp_authkeyid)) |
5223 | return -EINVAL; | 5251 | return -EINVAL; |
5224 | if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) | 5252 | if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) |
@@ -5233,6 +5261,12 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5233 | else | 5261 | else |
5234 | val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; | 5262 | val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; |
5235 | 5263 | ||
5264 | len = sizeof(struct sctp_authkeyid); | ||
5265 | if (put_user(len, optlen)) | ||
5266 | return -EFAULT; | ||
5267 | if (copy_to_user(optval, &val, len)) | ||
5268 | return -EFAULT; | ||
5269 | |||
5236 | return 0; | 5270 | return 0; |
5237 | } | 5271 | } |
5238 | 5272 | ||
@@ -5243,13 +5277,16 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5243 | struct sctp_authchunks val; | 5277 | struct sctp_authchunks val; |
5244 | struct sctp_association *asoc; | 5278 | struct sctp_association *asoc; |
5245 | struct sctp_chunks_param *ch; | 5279 | struct sctp_chunks_param *ch; |
5246 | u32 num_chunks; | 5280 | u32 num_chunks = 0; |
5247 | char __user *to; | 5281 | char __user *to; |
5248 | 5282 | ||
5249 | if (len <= sizeof(struct sctp_authchunks)) | 5283 | if (!sctp_auth_enable) |
5284 | return -EACCES; | ||
5285 | |||
5286 | if (len < sizeof(struct sctp_authchunks)) | ||
5250 | return -EINVAL; | 5287 | return -EINVAL; |
5251 | 5288 | ||
5252 | if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) | 5289 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) |
5253 | return -EFAULT; | 5290 | return -EFAULT; |
5254 | 5291 | ||
5255 | to = p->gauth_chunks; | 5292 | to = p->gauth_chunks; |
@@ -5258,20 +5295,21 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5258 | return -EINVAL; | 5295 | return -EINVAL; |
5259 | 5296 | ||
5260 | ch = asoc->peer.peer_chunks; | 5297 | ch = asoc->peer.peer_chunks; |
5298 | if (!ch) | ||
5299 | goto num; | ||
5261 | 5300 | ||
5262 | /* See if the user provided enough room for all the data */ | 5301 | /* See if the user provided enough room for all the data */ |
5263 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); | 5302 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5264 | if (len < num_chunks) | 5303 | if (len < num_chunks) |
5265 | return -EINVAL; | 5304 | return -EINVAL; |
5266 | 5305 | ||
5267 | len = num_chunks; | 5306 | if (copy_to_user(to, ch->chunks, num_chunks)) |
5268 | if (put_user(len, optlen)) | ||
5269 | return -EFAULT; | 5307 | return -EFAULT; |
5308 | num: | ||
5309 | len = sizeof(struct sctp_authchunks) + num_chunks; | ||
5310 | if (put_user(len, optlen)) return -EFAULT; | ||
5270 | if (put_user(num_chunks, &p->gauth_number_of_chunks)) | 5311 | if (put_user(num_chunks, &p->gauth_number_of_chunks)) |
5271 | return -EFAULT; | 5312 | return -EFAULT; |
5272 | if (copy_to_user(to, ch->chunks, len)) | ||
5273 | return -EFAULT; | ||
5274 | |||
5275 | return 0; | 5313 | return 0; |
5276 | } | 5314 | } |
5277 | 5315 | ||
@@ -5282,13 +5320,16 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5282 | struct sctp_authchunks val; | 5320 | struct sctp_authchunks val; |
5283 | struct sctp_association *asoc; | 5321 | struct sctp_association *asoc; |
5284 | struct sctp_chunks_param *ch; | 5322 | struct sctp_chunks_param *ch; |
5285 | u32 num_chunks; | 5323 | u32 num_chunks = 0; |
5286 | char __user *to; | 5324 | char __user *to; |
5287 | 5325 | ||
5288 | if (len <= sizeof(struct sctp_authchunks)) | 5326 | if (!sctp_auth_enable) |
5327 | return -EACCES; | ||
5328 | |||
5329 | if (len < sizeof(struct sctp_authchunks)) | ||
5289 | return -EINVAL; | 5330 | return -EINVAL; |
5290 | 5331 | ||
5291 | if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) | 5332 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) |
5292 | return -EFAULT; | 5333 | return -EFAULT; |
5293 | 5334 | ||
5294 | to = p->gauth_chunks; | 5335 | to = p->gauth_chunks; |
@@ -5301,17 +5342,21 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5301 | else | 5342 | else |
5302 | ch = sctp_sk(sk)->ep->auth_chunk_list; | 5343 | ch = sctp_sk(sk)->ep->auth_chunk_list; |
5303 | 5344 | ||
5345 | if (!ch) | ||
5346 | goto num; | ||
5347 | |||
5304 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); | 5348 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5305 | if (len < num_chunks) | 5349 | if (len < sizeof(struct sctp_authchunks) + num_chunks) |
5306 | return -EINVAL; | 5350 | return -EINVAL; |
5307 | 5351 | ||
5308 | len = num_chunks; | 5352 | if (copy_to_user(to, ch->chunks, num_chunks)) |
5353 | return -EFAULT; | ||
5354 | num: | ||
5355 | len = sizeof(struct sctp_authchunks) + num_chunks; | ||
5309 | if (put_user(len, optlen)) | 5356 | if (put_user(len, optlen)) |
5310 | return -EFAULT; | 5357 | return -EFAULT; |
5311 | if (put_user(num_chunks, &p->gauth_number_of_chunks)) | 5358 | if (put_user(num_chunks, &p->gauth_number_of_chunks)) |
5312 | return -EFAULT; | 5359 | return -EFAULT; |
5313 | if (copy_to_user(to, ch->chunks, len)) | ||
5314 | return -EFAULT; | ||
5315 | 5360 | ||
5316 | return 0; | 5361 | return 0; |
5317 | } | 5362 | } |