|
@@ -3055,6 +3055,9 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
|
|
|
{
|
|
|
struct sctp_authchunk val;
|
|
|
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
if (optlen != sizeof(struct sctp_authchunk))
|
|
|
return -EINVAL;
|
|
|
if (copy_from_user(&val, optval, optlen))
|
|
@@ -3085,6 +3088,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
|
|
|
struct sctp_hmacalgo *hmacs;
|
|
|
int err;
|
|
|
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
if (optlen < sizeof(struct sctp_hmacalgo))
|
|
|
return -EINVAL;
|
|
|
|
|
@@ -3123,6 +3129,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
|
|
|
struct sctp_association *asoc;
|
|
|
int ret;
|
|
|
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
if (optlen <= sizeof(struct sctp_authkey))
|
|
|
return -EINVAL;
|
|
|
|
|
@@ -3160,6 +3169,9 @@ static int sctp_setsockopt_active_key(struct sock *sk,
|
|
|
struct sctp_authkeyid val;
|
|
|
struct sctp_association *asoc;
|
|
|
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
if (optlen != sizeof(struct sctp_authkeyid))
|
|
|
return -EINVAL;
|
|
|
if (copy_from_user(&val, optval, optlen))
|
|
@@ -3185,6 +3197,9 @@ static int sctp_setsockopt_del_key(struct sock *sk,
|
|
|
struct sctp_authkeyid val;
|
|
|
struct sctp_association *asoc;
|
|
|
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
if (optlen != sizeof(struct sctp_authkeyid))
|
|
|
return -EINVAL;
|
|
|
if (copy_from_user(&val, optval, optlen))
|
|
@@ -5197,19 +5212,29 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
|
|
|
static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
|
|
|
char __user *optval, int __user *optlen)
|
|
|
{
|
|
|
+ struct sctp_hmacalgo __user *p = (void __user *)optval;
|
|
|
struct sctp_hmac_algo_param *hmacs;
|
|
|
- __u16 param_len;
|
|
|
+ __u16 data_len = 0;
|
|
|
+ u32 num_idents;
|
|
|
+
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
|
|
|
hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
|
|
|
- param_len = ntohs(hmacs->param_hdr.length);
|
|
|
+ data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
|
|
|
|
|
|
- if (len < param_len)
|
|
|
+ if (len < sizeof(struct sctp_hmacalgo) + data_len)
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
+ len = sizeof(struct sctp_hmacalgo) + data_len;
|
|
|
+ num_idents = data_len / sizeof(u16);
|
|
|
+
|
|
|
if (put_user(len, optlen))
|
|
|
return -EFAULT;
|
|
|
- if (copy_to_user(optval, hmacs->hmac_ids, len))
|
|
|
+ if (put_user(num_idents, &p->shmac_num_idents))
|
|
|
+ return -EFAULT;
|
|
|
+ if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
|
|
|
return -EFAULT;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -5219,6 +5244,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
|
|
|
struct sctp_authkeyid val;
|
|
|
struct sctp_association *asoc;
|
|
|
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
if (len < sizeof(struct sctp_authkeyid))
|
|
|
return -EINVAL;
|
|
|
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,
|
|
|
else
|
|
|
val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
|
|
|
|
|
|
+ len = sizeof(struct sctp_authkeyid);
|
|
|
+ if (put_user(len, optlen))
|
|
|
+ return -EFAULT;
|
|
|
+ if (copy_to_user(optval, &val, len))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -5243,13 +5277,16 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
|
|
|
struct sctp_authchunks val;
|
|
|
struct sctp_association *asoc;
|
|
|
struct sctp_chunks_param *ch;
|
|
|
- u32 num_chunks;
|
|
|
+ u32 num_chunks = 0;
|
|
|
char __user *to;
|
|
|
|
|
|
- if (len <= sizeof(struct sctp_authchunks))
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
+ if (len < sizeof(struct sctp_authchunks))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (copy_from_user(&val, p, sizeof(struct sctp_authchunks)))
|
|
|
+ if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
|
|
|
return -EFAULT;
|
|
|
|
|
|
to = p->gauth_chunks;
|
|
@@ -5258,20 +5295,21 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
|
|
|
return -EINVAL;
|
|
|
|
|
|
ch = asoc->peer.peer_chunks;
|
|
|
+ if (!ch)
|
|
|
+ goto num;
|
|
|
|
|
|
/* See if the user provided enough room for all the data */
|
|
|
num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
|
|
|
if (len < num_chunks)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- len = num_chunks;
|
|
|
- if (put_user(len, optlen))
|
|
|
+ if (copy_to_user(to, ch->chunks, num_chunks))
|
|
|
return -EFAULT;
|
|
|
+num:
|
|
|
+ len = sizeof(struct sctp_authchunks) + num_chunks;
|
|
|
+ if (put_user(len, optlen)) return -EFAULT;
|
|
|
if (put_user(num_chunks, &p->gauth_number_of_chunks))
|
|
|
return -EFAULT;
|
|
|
- if (copy_to_user(to, ch->chunks, len))
|
|
|
- return -EFAULT;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -5282,13 +5320,16 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
|
|
|
struct sctp_authchunks val;
|
|
|
struct sctp_association *asoc;
|
|
|
struct sctp_chunks_param *ch;
|
|
|
- u32 num_chunks;
|
|
|
+ u32 num_chunks = 0;
|
|
|
char __user *to;
|
|
|
|
|
|
- if (len <= sizeof(struct sctp_authchunks))
|
|
|
+ if (!sctp_auth_enable)
|
|
|
+ return -EACCES;
|
|
|
+
|
|
|
+ if (len < sizeof(struct sctp_authchunks))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (copy_from_user(&val, p, sizeof(struct sctp_authchunks)))
|
|
|
+ if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
|
|
|
return -EFAULT;
|
|
|
|
|
|
to = p->gauth_chunks;
|
|
@@ -5301,17 +5342,21 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
|
|
|
else
|
|
|
ch = sctp_sk(sk)->ep->auth_chunk_list;
|
|
|
|
|
|
+ if (!ch)
|
|
|
+ goto num;
|
|
|
+
|
|
|
num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
|
|
|
- if (len < num_chunks)
|
|
|
+ if (len < sizeof(struct sctp_authchunks) + num_chunks)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- len = num_chunks;
|
|
|
+ if (copy_to_user(to, ch->chunks, num_chunks))
|
|
|
+ return -EFAULT;
|
|
|
+num:
|
|
|
+ len = sizeof(struct sctp_authchunks) + num_chunks;
|
|
|
if (put_user(len, optlen))
|
|
|
return -EFAULT;
|
|
|
if (put_user(num_chunks, &p->gauth_number_of_chunks))
|
|
|
return -EFAULT;
|
|
|
- if (copy_to_user(to, ch->chunks, len))
|
|
|
- return -EFAULT;
|
|
|
|
|
|
return 0;
|
|
|
}
|