diff --git a/openslp/common/slp_buffer.c b/openslp/common/slp_buffer.c index 1cab3f55..2d4b1e0c 100644 --- a/openslp/common/slp_buffer.c +++ b/openslp/common/slp_buffer.c @@ -30,6 +30,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *-------------------------------------------------------------------------*/ +/* Copyright (c) 2019 VMware, Inc. + * SPDX-License-Identifier: BSD-3-Clause + * This file is provided under the BSD-3-Clause license. + * See COPYING file for more details and other copyrights + * that may apply. + */ + /** Functions for managing SLP message buffers. * * This file provides a higher level abstraction over malloc and free that @@ -153,4 +160,20 @@ void SLPBufferFree(SLPBuffer buf) xfree(buf); } +/** Report remaining free buffer size in bytes. + * + * Check if buffer is allocated and if so return bytes left in a + * @c SLPBuffer object. + * + * @param[in] buf The SLPBuffer to get the free space size from. + */ +size_t +RemainingBufferSpace(SLPBuffer buf) +{ + if (buf->allocated == 0) { + return 0; + } + return buf->end - buf->curpos; +} + /*=========================================================================*/ diff --git a/openslp/common/slp_buffer.h b/openslp/common/slp_buffer.h index 314aba68..308bf155 100644 --- a/openslp/common/slp_buffer.h +++ b/openslp/common/slp_buffer.h @@ -30,6 +30,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *-------------------------------------------------------------------------*/ +/* Copyright (c) 2019 VMware, Inc. + * SPDX-License-Identifier: BSD-3-Clause + * This file is provided under the BSD-3-Clause license. + * See COPYING file for more details and other copyrights + * that may apply. + */ + /** Header file that defines SLP message buffer management routines. * * Includes structures, constants and functions that used to handle memory @@ -78,6 +85,8 @@ SLPBuffer SLPBufferListRemove(SLPBuffer * list, SLPBuffer buf); SLPBuffer SLPBufferListAdd(SLPBuffer * list, SLPBuffer buf); +size_t RemainingBufferSpace(SLPBuffer buf); + /*! @} */ #endif /* SLP_BUFFER_H_INCLUDED */ diff --git a/openslp/slpd/slpd_process.c b/openslp/slpd/slpd_process.c index 0698ab84..3c6b4693 100644 --- a/openslp/slpd/slpd_process.c +++ b/openslp/slpd/slpd_process.c @@ -30,6 +30,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *-------------------------------------------------------------------------*/ +/* Copyright (c) 2019 VMware, Inc. + * SPDX-License-Identifier: BSD-3-Clause + * This file is provided under the BSD-3-Clause license. + * See COPYING file for more details and other copyrights + * that may apply. + */ + /** Processes incoming SLP messages. * * @file slpd_process.c @@ -523,13 +530,26 @@ static int ProcessSrvRqst(SLPMessage * message, SLPBuffer * sendbuf, { for (i = 0; i < db->urlcount; i++) { - /* urlentry is the url from the db result */ urlentry = db->urlarray[i]; + if (urlentry->opaque != NULL) { + if (urlentry->opaquelen == 0 || (size > SIZE_MAX - urlentry->opaquelen)) + { + SLPDLog("Invalid opaquelen %zu or size of opaque url is too big, size=%zu\n", + urlentry->opaquelen, size); + errorcode = SLP_ERROR_PARSE_ERROR; + goto FINISHED; + } + size += urlentry->opaquelen; + } + else + { + /* urlentry is the url from the db result */ + size += urlentry->urllen + 6; /* 1 byte for reserved */ + /* 2 bytes for lifetime */ + /* 2 bytes for urllen */ + /* 1 byte for authcount */ + } - size += urlentry->urllen + 6; /* 1 byte for reserved */ - /* 2 bytes for lifetime */ - /* 2 bytes for urllen */ - /* 1 byte for authcount */ #ifdef ENABLE_SLPv2_SECURITY /* make room to include the authblock that was asked for */ if (G_SlpdProperty.securityEnabled @@ -603,7 +623,7 @@ static int ProcessSrvRqst(SLPMessage * message, SLPBuffer * sendbuf, urlentry = db->urlarray[i]; #ifdef ENABLE_SLPv1 - if (urlentry->opaque == 0) + if (urlentry->opaque == NULL) { /* url-entry reserved */ *result->curpos++ = 0; @@ -615,8 +635,18 @@ static int ProcessSrvRqst(SLPMessage * message, SLPBuffer * sendbuf, PutUINT16(&result->curpos, urlentry->urllen); /* url-entry url */ - memcpy(result->curpos, urlentry->url, urlentry->urllen); - result->curpos += urlentry->urllen; + if (RemainingBufferSpace(result) >= urlentry->urllen) + { + memcpy(result->curpos, urlentry->url, urlentry->urllen); + result->curpos = result->curpos + urlentry->urllen; + } + else + { + SLPDLog("Url too big (ask: %zu have %zu), failing request\n", + urlentry->opaquelen, RemainingBufferSpace(result)); + errorcode = SLP_ERROR_PARSE_ERROR; + goto FINISHED; + } /* url-entry auths */ *result->curpos++ = 0; @@ -628,7 +658,18 @@ static int ProcessSrvRqst(SLPMessage * message, SLPBuffer * sendbuf, /* TRICKY: Fix up the lifetime. */ TO_UINT16(urlentry->opaque + 1, urlentry->lifetime); - memcpy(result->curpos, urlentry->opaque, urlentry->opaquelen); + + if (RemainingBufferSpace(result) >= urlentry->opaquelen) + { + memcpy(result->curpos, urlentry->opaque, urlentry->opaquelen); + } + else + { + SLPDLog("Opaque Url too big (ask: %zu have %zu), failing request\n", + urlentry->opaquelen, RemainingBufferSpace(result)); + errorcode = SLP_ERROR_PARSE_ERROR; + goto FINISHED; + } /* TRICKY: Fix up the result authblock count. */ if (urlentry->authcount)