SecurityReason.com - Our Reason is

Security

Register | Forget Password | Login
SecurityReason
WLB
Services
RSS
Corporate
Note

If you have found a vulnerability, please send to our SecurityAlert Database :
secalert()securityreason()com

Also if you have new ( 0-day ) exploit, please send to our ExploitAlert Archive :
exploit()securityreason()com

Home arrow SecurityAlert Database

Arrow  Topic :

sctp: fix potential panics in the SCTP-AUTH API.


Arrow  SecurityAlert : 4210
Arrow  CVE : CVE-2008-3792
Arrow  CWE : CWE-Other
Arrow  SecurityRisk : High  Security Risk High  (About)
Arrow  Remote Exploit : Yes
Arrow  Local Exploit : No
Arrow  Victim interaction required : No
Arrow  Exploit Available : No
Arrow  Credit : Vlad Yasevich
Arrow  Published : 04.09.2008

Arrow  Affected Software : Linux, Kernel, 2.6.23.6



Arrow  Advisory Content :  

Andrew, David

This problem is not limited to only the reported socket
option. Most of the AUTH socket options suffer the
same or similar issues. Here is a patch that fixes
all the issues I saw the the API. The new tests for
this API have been created and all of them have passed.

-vlad

sctp: fix potential panics in the SCTP-AUTH API.

All of the SCTP-AUTH socket options could cause a panic
if the extension is disabled and the API is envoked.

Additionally, there were some additional assumptions that
certain pointers would always be valid which may not
always be the case.

This patch hardens the API and address all of the crash
scenarios.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
net/sctp/endpointola.c | 4 +-
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 e39a0cd..466eb75 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,

/* Initialize the CHUNKS parameter */
auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
+ auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t));

/* If the Add-IP functionality is enabled, we must
* authenticate, ASCONF and ASCONF-ACK chunks
@@ -110,8 +111,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct
sctp_endpoint *ep,
if (sctp_addip_enable) {
auth_chunks->chunks<A NAME="-0"></A>[0] = SCTP_CID_ASCONF;
auth_chunks->chunks<A NAME="-1"></A>[1] = SCTP_CID_ASCONF_ACK;
- auth_chunks->param_hdr.length =
- htons(sizeof(sctp_paramhdr_t) + 2);
+ auth_chunks->param_hdr.length += htons(2);
}
}

diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index dbb79ad..bb5c9ef 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -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;
}
--
1.5.2.5

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
<b>[prev in list] [next in list] [<font color="#c0c0c0">prev in
thread</font>] [next in thread] </b>
</pre>
</pre><br><center>
Configure |

About |
News |
Donate |
Add a list |
Sponsors: 10East, KoreLogic, Terra-International, Chakpak.com
</center>
</body>
</html>


Arrow  References :

http://www.openwall.com/lists/oss-security/2008/08/26/8
http://www.openwall.com/lists/oss-security/2008/08/26/6
http://www.openwall.com/lists/oss-security/2008/08/25/1
http://marc.info/?l=linux-netdev&m=121928747903176&w=2
http://lkml.org/lkml/2008/8/23/49
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=5e739d1752aca4e8f3e794d431503bfca3162df4




Arrow  Feedback :

If you have additional information or notice any errors regarding this security advisory, please use contact form or email us at info()securityreason()com.
Alert

libc:fts_*() Multiple Denial of Service

Security Risk Medium- 2009-10-02

The fts functions are provided for traversing UNIX file hierarchies...

Apache RSS Apache Alert

» Apache 1.3.41 mod_proxy
   Integer overflow (code
   execution)

» Apache Tomcat 6.0.20 and
   5.5.28 unexpected file
   deletion in work
   directory

» Apache Tomcat 6.0.20 and
   5.5.28 insecure partial
   deploy after failed
   undeploy

» Apache Tomcat 6.0.20 and
   5.5.28 unexpected file
   deletion and/or
   alteration

PHP RSS PHP Alert

» PHP 5.2.12/5.3.1
   session.save_path
   safe_mode and
   open_basedir bypass

» PHP 5.2.12/5.3.1 Multiple
   Vulnerabilities

» PHP 5.2.11 libgd multiple
   vulnerabilities

» PHP 5.2.11 tempnam()
   safe_mode bypass

Copyright © SecurityReason.com. All Rights Reserved.