Hello,
OpenSSL (1.0.1h and older) contains following problematic part of code in
/crypto/bio/bss_dgram.c, dgram_sctp_read():
---
static int dgram_sctp_read(BIO *b, char *out, int outl)
{
int ret = 0, n = 0, i, optval;
socklen_t optlen;
bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
union sctp_notification *snp;
struct msghdr msg;
struct iovec iov;
struct cmsghdr *cmsg;
char cmsgbuf[512];
if (out != NULL)
{
clear_socket_error();
do
{
memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
iov.iov_base = out;
iov.iov_len = outl;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = 512;
msg.msg_flags = 0;
n = recvmsg(b->num, &msg, 0);
if (msg.msg_controllen > 0)
{
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg,
cmsg))
...
...
---
"msg" structure is accessed even if recvmsg() called previously returned -1
(some error) or 0 (remote endpoint has closed the connection). This can cause
process crash with SIGSEGV, or infinite loop (for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)).
We have encountered with this problem during development of proprietary
communication software using OpenSSL/DTLS on RHEL6. But other systems using
OpenSSL DTLS are also affected.
Please have a look at the patch attached, it could solve this issue.
Thank you.
Best Regards,
Jan Hykel
Acision
________________________________
This e-mail and any attachment is for authorised use by the intended
recipient(s) only. It may contain proprietary material, confidential
information and/or be subject to legal privilege. It should not be copied,
disclosed to, retained or used by, any other party. If you are not an intended
recipient then please promptly delete this e-mail and any attachment and all
copies and inform the sender. Thank you for understanding.
--- a/openssl-1.0.1h/crypto/bio/bss_dgram.c 2014-06-05 11:44:33.000000000 +0200
+++ b/openssl-1.0.1h/crypto/bio/bss_dgram.c 2014-07-23 16:48:53.659651003 +0200
@@ -1034,6 +1034,13 @@
msg.msg_flags = 0;
n = recvmsg(b->num, &msg, 0);
+ if (n <= 0)
+ {
+ if (n < 0)
+ ret = n;
+ break;
+ }
+
if (msg.msg_controllen > 0)
{
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
@@ -1073,13 +1080,6 @@
}
}
- if (n <= 0)
- {
- if (n < 0)
- ret = n;
- break;
- }
-
if (msg.msg_flags & MSG_NOTIFICATION)
{
snp = (union sctp_notification*) out;