diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2008-02-27 14:40:37 -0500 |
---|---|---|
committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2008-02-28 16:45:01 -0500 |
commit | b40db6846847e82daf175641987df29324c425fa (patch) | |
tree | 11f1f64c79c2da85eaf4bbd13828616058ea22af /net/sctp | |
parent | 15efbe763978d7cc327d824d9e8f8f9e525dd40d (diff) |
[SCTP]: Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option
The chunks are stored inside a parameter structure in the kernel
and when we copy them to the user, we need to account for
the parameter header.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/socket.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 44797ad88a05..848df21dc6c1 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -5070,6 +5070,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5070 | struct sctp_authchunks val; | 5070 | struct sctp_authchunks val; |
5071 | struct sctp_association *asoc; | 5071 | struct sctp_association *asoc; |
5072 | struct sctp_chunks_param *ch; | 5072 | struct sctp_chunks_param *ch; |
5073 | u32 num_chunks; | ||
5073 | char __user *to; | 5074 | char __user *to; |
5074 | 5075 | ||
5075 | if (len <= sizeof(struct sctp_authchunks)) | 5076 | if (len <= sizeof(struct sctp_authchunks)) |
@@ -5086,10 +5087,11 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5086 | ch = asoc->peer.peer_chunks; | 5087 | ch = asoc->peer.peer_chunks; |
5087 | 5088 | ||
5088 | /* See if the user provided enough room for all the data */ | 5089 | /* See if the user provided enough room for all the data */ |
5089 | if (len < ntohs(ch->param_hdr.length)) | 5090 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5091 | if (len < num_chunks) | ||
5090 | return -EINVAL; | 5092 | return -EINVAL; |
5091 | 5093 | ||
5092 | len = ntohs(ch->param_hdr.length); | 5094 | len = num_chunks; |
5093 | if (put_user(len, optlen)) | 5095 | if (put_user(len, optlen)) |
5094 | return -EFAULT; | 5096 | return -EFAULT; |
5095 | if (copy_to_user(to, ch->chunks, len)) | 5097 | if (copy_to_user(to, ch->chunks, len)) |
@@ -5105,6 +5107,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5105 | struct sctp_authchunks val; | 5107 | struct sctp_authchunks val; |
5106 | struct sctp_association *asoc; | 5108 | struct sctp_association *asoc; |
5107 | struct sctp_chunks_param *ch; | 5109 | struct sctp_chunks_param *ch; |
5110 | u32 num_chunks; | ||
5108 | char __user *to; | 5111 | char __user *to; |
5109 | 5112 | ||
5110 | if (len <= sizeof(struct sctp_authchunks)) | 5113 | if (len <= sizeof(struct sctp_authchunks)) |
@@ -5123,10 +5126,11 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5123 | else | 5126 | else |
5124 | ch = sctp_sk(sk)->ep->auth_chunk_list; | 5127 | ch = sctp_sk(sk)->ep->auth_chunk_list; |
5125 | 5128 | ||
5126 | if (len < ntohs(ch->param_hdr.length)) | 5129 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5130 | if (len < num_chunks) | ||
5127 | return -EINVAL; | 5131 | return -EINVAL; |
5128 | 5132 | ||
5129 | len = ntohs(ch->param_hdr.length); | 5133 | len = num_chunks; |
5130 | if (put_user(len, optlen)) | 5134 | if (put_user(len, optlen)) |
5131 | return -EFAULT; | 5135 | return -EFAULT; |
5132 | if (copy_to_user(to, ch->chunks, len)) | 5136 | if (copy_to_user(to, ch->chunks, len)) |