[packages/openslp] Rel 7. Fixes CVE-2012-4428, CVE-2016-4912, CVE-2016-7567, CVE-2017-17833, CVE-2019-5544
arekm
arekm at pld-linux.org
Wed Oct 14 21:50:23 CEST 2026
commit 4476dc582fdded22b7ec810dc4eeab187b56bf59
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Wed Oct 14 21:49:42 2026 +0200
Rel 7. Fixes CVE-2012-4428, CVE-2016-4912, CVE-2016-7567, CVE-2017-17833, CVE-2019-5544
openslp-CVE-2012-4428.patch | 39 ++++++++
openslp-CVE-2016-4912.patch | 15 ++++
openslp-CVE-2016-7567.patch | 93 +++++++++++++++++++
openslp-CVE-2017-17833.patch | 22 +++++
openslp-CVE-2019-5544.patch | 169 +++++++++++++++++++++++++++++++++++
openslp-dhcp-overflow.patch | 15 ++++
openslp-knownda-type-confusion.patch | 14 +++
openslp-srvtype-oob.patch | 55 ++++++++++++
openslp.spec | 21 ++++-
9 files changed, 441 insertions(+), 2 deletions(-)
---
diff --git a/openslp.spec b/openslp.spec
index 0ed0231..3bcd904 100644
--- a/openslp.spec
+++ b/openslp.spec
@@ -7,16 +7,25 @@ Summary(pl.UTF-8): Otwarta implementacja Service Location Protocol V2
Summary(pt.UTF-8): Implementação 'open source' do protocolo Service Location Protocol V2
Name: openslp
Version: 2.0.0
-Release: 6
+Release: 7
License: BSD
Group: Libraries
-Source0: http://downloads.sourceforge.net/openslp/%{name}-%{version}.tar.gz
+Source0: https://downloads.sourceforge.net/openslp/%{name}-%{version}.tar.gz
# Source0-md5: 18cf7940bcc444e32592cf34e84f833f
Source1: %{name}.init
Patch0: %{name}-opt.patch
Patch1: %{name}-build.patch
Patch2: %{name}-symbol-clashes.patch
Patch3: openssl.patch
+# 2.0.0 is the last upstream release; security fixes from upstream git and Fedora
+Patch4: %{name}-CVE-2012-4428.patch
+Patch5: %{name}-CVE-2016-4912.patch
+Patch6: %{name}-CVE-2016-7567.patch
+Patch7: %{name}-CVE-2017-17833.patch
+Patch8: %{name}-CVE-2019-5544.patch
+Patch9: %{name}-srvtype-oob.patch
+Patch10: %{name}-dhcp-overflow.patch
+Patch11: %{name}-knownda-type-confusion.patch
URL: http://www.openslp.org/
BuildRequires: autoconf >= 2.59
BuildRequires: automake
@@ -136,6 +145,14 @@ Biblioteki statyczne OpenSLP.
%patch -P1 -p1
%patch -P2 -p1
%patch -P3 -p1
+%patch -P4 -p1
+%patch -P5 -p1
+%patch -P6 -p1
+%patch -P7 -p1
+%patch -P8 -p1
+%patch -P9 -p1
+%patch -P10 -p1
+%patch -P11 -p1
%build
%{__libtoolize}
diff --git a/openslp-CVE-2012-4428.patch b/openslp-CVE-2012-4428.patch
new file mode 100644
index 0000000..cadd424
--- /dev/null
+++ b/openslp-CVE-2012-4428.patch
@@ -0,0 +1,39 @@
+string-list scanning read before the list start on an empty item (CVE-2012-4428)
+https://github.com/openslp-org/openslp/commit/35d3d29
+
+diff --git a/common/slp_compare.c b/common/slp_compare.c
+index 989ffa0..a3e92b5 100644
+--- a/common/slp_compare.c
++++ b/common/slp_compare.c
+@@ -588,13 +588,10 @@ int SLPIntersectRemoveStringList(int list1len,
+ /* seek to the end of the next list item */
+ while(1)
+ {
+- if(itemend == listend || *itemend == ',')
+- {
+- if(*(itemend - 1) != '\\')
+- {
+- break;
+- }
+- }
++ if(itemend == listend)
++ break;
++ if(*itemend == ',' && *(itemend - 1) != '\\')
++ break;
+
+ itemend++;
+ }
+@@ -684,9 +681,10 @@ int SLPUnionStringList(size_t list1len, const char * list1, size_t list2len,
+ /* seek to the end of the next list item */
+ while (1)
+ {
+- if (itemend == listend || *itemend == ',')
+- if (*(itemend - 1) != '\\')
+- break;
++ if(itemend == listend)
++ break;
++ if(*itemend == ',' && *(itemend - 1) != '\\')
++ break;
+ itemend++;
+ }
+
diff --git a/openslp-CVE-2016-4912.patch b/openslp-CVE-2016-4912.patch
new file mode 100644
index 0000000..db4a4fb
--- /dev/null
+++ b/openslp-CVE-2016-4912.patch
@@ -0,0 +1,15 @@
+_xrealloc() copied into a NULL buffer when allocation failed (CVE-2016-4912)
+https://bugzilla.redhat.com/show_bug.cgi?id=1337402
+
+diff -up openslp-2.0.0/common/slp_xmalloc.c.orig openslp-2.0.0/common/slp_xmalloc.c
+--- openslp-2.0.0/common/slp_xmalloc.c.orig 2012-12-07 01:52:08.000000000 +0100
++++ openslp-2.0.0/common/slp_xmalloc.c 2016-05-23 12:58:57.953532979 +0200
+@@ -203,6 +203,8 @@ void * _xrealloc(const char * file, int
+ if (x->size != size)
+ {
+ newptr = _xmalloc(file, line, size);
++ if (newptr == 0)
++ return 0;
+ memcpy(newptr, ptr, x->size);
+ _xfree(file, line, x);
+ }
diff --git a/openslp-CVE-2016-7567.patch b/openslp-CVE-2016-7567.patch
new file mode 100644
index 0000000..4d301a3
--- /dev/null
+++ b/openslp-CVE-2016-7567.patch
@@ -0,0 +1,93 @@
+SLPFoldWhiteSpace() could write past the end of the string (CVE-2016-7567)
+backport of https://github.com/openslp-org/openslp/commit/97690d1
+
+diff -up openslp-2.0.0/common/slp_compare.c.orig openslp-2.0.0/common/slp_compare.c
+--- openslp-2.0.0/common/slp_compare.c.orig 2012-12-12 20:12:43.000000000 +0100
++++ openslp-2.0.0/common/slp_compare.c 2017-03-14 10:51:36.480675991 +0100
+@@ -194,7 +194,8 @@ static int SLPUnescapeInPlace(size_t len
+ * @return The new (shorter) length of @p str.
+ *
+ * @note This routine assumes that leading and trailing white space have
+- * already been removed from @p str.
++ * already been removed from @p str. It also assumes that @p str may
++ * not be null-terminated.
+ */
+ static int SLPFoldWhiteSpace(size_t len, char * str)
+ {
+@@ -203,11 +204,11 @@ static int SLPFoldWhiteSpace(size_t len,
+ {
+ if (isspace(*p))
+ {
+- char * ws2p = ++p; /* Point ws2p to the second ws char. */
+- while (isspace(*p)) /* Scan till we hit a non-ws char. */
++ char * ws2p = ++p; /* Point ws2p to the second ws char. */
++ while (p < ep && isspace(*p)) /* Scan till we hit a non-ws char. */
+ p++;
+- len -= p - ws2p; /* Reduce the length by extra ws. */
+- memmove(ws2p, p, ep - p); /* Overwrite the extra white space. */
++ len -= p - ws2p; /* Reduce the length by extra ws. */
++ memmove(ws2p, p, ep - p); /* Overwrite the extra white space. */
+ }
+ p++;
+ }
+@@ -821,6 +822,50 @@ int SLPCheckAttributeListSyntax(const ch
+
+ #ifdef SLP_COMPARE_TEST
+
++/* Test boundary conditions of SLPFoldWhiteSpace. */
++static int test_SLPFoldWhiteSpace(void)
++{
++ static char test_str0[] = " ";
++ static char test_str1[] = "Blah";
++ static char test_str3[] = "Blah blah";
++ static char test_str4[] = "Blah blah";
++ static char test_str5[] = "Blah blah blah";
++ static char test_str8[] = " Blah blah";
++ static char test_str9[] = " Blah blah";
++ static char test_strC[] = "Blah blah ";
++ static char test_strD[] = "Blah blah xxxx";
++
++ static char * test_strs[] =
++ {
++ test_str0, test_str0, test_str0, test_str1, test_strC,
++ test_str3, test_str4, test_str5, test_strC, test_strC,
++ test_str8, test_str9, test_strC, test_strD,
++ };
++
++ static int test_lens[] =
++ {
++ 0, 1, 2, 4, 9, 10, 11, 15, 10, 11, 10, 11, 11, 11,
++ };
++
++ static int test_fins[] =
++ {
++ 0, 1, 1, 4, 9, 9, 9, 14, 10, 10, 10, 10, 10, 10,
++ };
++
++#define MAX_BUFSZ 32
++
++ int i;
++ for (i = 0; i < sizeof(test_strs) / sizeof(*test_strs); ++i)
++ {
++ char test_buf[MAX_BUFSZ];
++ memmove(test_buf, test_strs[i], test_lens[i]);
++ int len = SLPFoldWhiteSpace(test_lens[i], test_buf);
++ if (len != test_fins[i])
++ return -1;
++ }
++ return 0;
++}
++
+ /* ---------------- Test main for the slp_compare.c module ----------------
+ *
+ * Compile with:
+@@ -840,6 +885,9 @@ int main(void)
+
+ int count;
+
++ if (test_SLPFoldWhiteSpace() != 0)
++ return -1;
++
+ /* *** SLPContainsStringList ***
+ */
+ count = SLPContainsStringList(sizeof lst1 - 1, lst1, sizeof str1 - 1, str1);
diff --git a/openslp-CVE-2017-17833.patch b/openslp-CVE-2017-17833.patch
new file mode 100644
index 0000000..a6cb31e
--- /dev/null
+++ b/openslp-CVE-2017-17833.patch
@@ -0,0 +1,22 @@
+slpd kept a stale sendbuf pointer after ProcessDASrvRqst() reallocated it (CVE-2017-17833)
+backport of https://github.com/openslp-org/openslp/commit/ab44cdc
+
+diff -up openslp-2.0.0/slpd/slpd_process.c.orig openslp-2.0.0/slpd/slpd_process.c
+--- openslp-2.0.0/slpd/slpd_process.c.orig 2018-05-09 13:08:06.185104375 +0200
++++ openslp-2.0.0/slpd/slpd_process.c 2018-05-09 13:07:21.017095089 +0200
+@@ -462,6 +462,15 @@ static int ProcessSrvRqst(SLPMessage * m
+ message->body.srvrqst.srvtype, 23, SLP_DA_SERVICE_TYPE) == 0)
+ {
+ errorcode = ProcessDASrvRqst(message, sendbuf, errorcode);
++
++ if (result != *sendbuf)
++ {
++ // The pointer stored at *sendbuf can be modified by a realloc
++ // operation in ProcessDASrvRqst(). Fix up the local copy of
++ // that pointer if necessary.
++ result = *sendbuf;
++ }
++
+ if (errorcode == 0)
+ {
+ /* Since we have an errorcode of 0, we were successful,
diff --git a/openslp-CVE-2019-5544.patch b/openslp-CVE-2019-5544.patch
new file mode 100644
index 0000000..b98ea89
--- /dev/null
+++ b/openslp-CVE-2019-5544.patch
@@ -0,0 +1,169 @@
+slpd copied stored URL entries into the reply buffer without checking their
+length against the space left, a remote heap overwrite (CVE-2019-5544)
+VMware fix, from Fedora openslp-2.0.0-cve-2019-5544.patch
+
+diff -up openslp-2.0.0/common/slp_buffer.c.orig openslp-2.0.0/common/slp_buffer.c
+--- openslp-2.0.0/common/slp_buffer.c.orig 2012-12-11 00:31:53.000000000 +0100
++++ openslp-2.0.0/common/slp_buffer.c 2019-12-09 10:39:16.422058793 +0100
+@@ -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 be freed.
++ */
++size_t
++RemainingBufferSpace(SLPBuffer buf)
++{
++ if (buf->allocated == 0) {
++ return 0;
++ }
++ return buf->end - buf->curpos;
++}
++
+ /*=========================================================================*/
+diff -up openslp-2.0.0/common/slp_buffer.h.orig openslp-2.0.0/common/slp_buffer.h
+--- openslp-2.0.0/common/slp_buffer.h.orig 2012-11-28 18:07:04.000000000 +0100
++++ openslp-2.0.0/common/slp_buffer.h 2019-12-09 10:39:16.422058793 +0100
+@@ -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
+
+ SLPBuffer SLPBufferListAdd(SLPBuffer * list, SLPBuffer buf);
+
++size_t RemainingBufferSpace(SLPBuffer buf);
++
+ /*! @} */
+
+ #endif /* SLP_BUFFER_H_INCLUDED */
+diff -up openslp-2.0.0/slpd/slpd_process.c.orig openslp-2.0.0/slpd/slpd_process.c
+--- openslp-2.0.0/slpd/slpd_process.c.orig 2019-12-09 10:39:16.420058789 +0100
++++ openslp-2.0.0/slpd/slpd_process.c 2019-12-09 10:39:16.422058793 +0100
+@@ -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,27 @@ RESPOND:
+ {
+ for (i = 0; i < db->urlcount; i++)
+ {
+- /* urlentry is the url from the db result */
+ urlentry = db->urlarray[i];
++ if (urlentry->opaque != NULL) {
++ const int64_t newsize = size + urlentry->opaquelen;
++ if (urlentry->opaquelen <= 0 || newsize > INT_MAX)
++ {
++ SLPDLog("Invalid opaquelen %d or sizeo of opaque url is too big, size=%d\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 +624,7 @@ RESPOND:
+ urlentry = db->urlarray[i];
+
+ #ifdef ENABLE_SLPv1
+- if (urlentry->opaque == 0)
++ if (urlentry->opaque == NULL)
+ {
+ /* url-entry reserved */
+ *result->curpos++ = 0;
+@@ -615,8 +636,18 @@ RESPOND:
+ 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: %d have %" PRId64 "), failing request\n",
++ urlentry->opaquelen, (int64_t) RemainingBufferSpace(result));
++ errorcode = SLP_ERROR_PARSE_ERROR;
++ goto FINISHED;
++ }
+
+ /* url-entry auths */
+ *result->curpos++ = 0;
+@@ -630,8 +661,18 @@ RESPOND:
+
+ /* TRICKY: Fix up the lifetime. */
+ TO_UINT16(urlentry->opaque + 1, urlentry->lifetime);
+- memcpy(result->curpos, urlentry->opaque, urlentry->opaquelen);
+- result->curpos += urlentry->opaquelen;
++ if (RemainingBufferSpace(result) >= urlentry->opaquelen)
++ {
++ memcpy(result->curpos, urlentry->opaque, urlentry->opaquelen);
++ result->curpos = result->curpos + urlentry->opaquelen;
++ }
++ else
++ {
++ SLPDLog("Opaque Url too big (ask: %d have %" PRId64 "), failing request\n",
++ urlentry->opaquelen, (int64_t) RemainingBufferSpace(result));
++ errorcode = SLP_ERROR_PARSE_ERROR;
++ goto FINISHED;
++ }
+ }
+ }
+ }
diff --git a/openslp-dhcp-overflow.patch b/openslp-dhcp-overflow.patch
new file mode 100644
index 0000000..a9c89c1
--- /dev/null
+++ b/openslp-dhcp-overflow.patch
@@ -0,0 +1,15 @@
+DHCPGetOptionInfo() did not check the reply covers the BOOTP header and read past rcvbuf
+from Fedora openslp-2.0.0-dhcp-integer-overflow.patch
+
+diff -up openslp-2.0.0/common/slp_dhcp.c.orig openslp-2.0.0/common/slp_dhcp.c
+--- openslp-2.0.0/common/slp_dhcp.c.orig 2012-12-07 01:52:08.000000000 +0100
++++ openslp-2.0.0/common/slp_dhcp.c 2026-09-23 13:42:53.313401159 +0200
+@@ -522,7 +522,7 @@ int DHCPGetOptionInfo(unsigned char * dh
+ tv.tv_usec %= USECS_PER_SEC;
+ }
+ closesocket(sockfd);
+- return rcvbufsz? dhcpProcessOptions(rcvbuf + 236, rcvbufsz - 236,
++ return (rcvbufsz >= 236)? dhcpProcessOptions(rcvbuf + 236, rcvbufsz - 236,
+ dhcpInfoCB, context): -1;
+ }
+
diff --git a/openslp-knownda-type-confusion.patch b/openslp-knownda-type-confusion.patch
new file mode 100644
index 0000000..60deb42
--- /dev/null
+++ b/openslp-knownda-type-confusion.patch
@@ -0,0 +1,14 @@
+KnownDABadDA() got a struct in_addr instead of a struct sockaddr, so failed DAs stayed cached
+from Fedora openslp-2.0.0-cwe-843-knownda-type-confusion.patch
+
+diff -up openslp-2.0.0/libslp/libslp_network.c.orig openslp-2.0.0/libslp/libslp_network.c
+--- openslp-2.0.0/libslp/libslp_network.c.orig 2026-09-29 09:24:31.198775361 +0200
++++ openslp-2.0.0/libslp/libslp_network.c 2026-09-29 09:24:31.201210907 +0200
+@@ -2178,7 +2178,7 @@ SLPError NetworkMultiUcastRqstRply(
+ if (pconn->state != CONN_COMPLETE)
+ {
+ /* this DA failed or timed out, so mark it as bad */
+- KnownDABadDA(&destaddr[i].sin_addr);
++ KnownDABadDA(&destaddr[i]);
+ }
+ }
diff --git a/openslp-srvtype-oob.patch b/openslp-srvtype-oob.patch
new file mode 100644
index 0000000..9d280cc
--- /dev/null
+++ b/openslp-srvtype-oob.patch
@@ -0,0 +1,55 @@
+SLPCompareSrvType() underflowed the length of a srvtype shorter than "service:",
+letting a remote request make slpd read out of bounds
+https://github.com/openslp-org/openslp/commit/d661027
+
+diff --git a/common/slp_compare.c b/common/slp_compare.c
+index e22c0d9..ddaaafe 100644
+--- a/common/slp_compare.c
++++ b/common/slp_compare.c
+@@ -169,10 +169,10 @@ static int hex2bin(int c)
+ static int SLPUnescapeInPlace(size_t len, char * str)
+ {
+ char * fp = str, * tp = str, * ep = str + len;
+- while (fp < ep - 2)
++ while (fp < ep)
+ {
+ char c = *fp++;
+- if (c == '\\' && *fp && ishex(fp[0]) && ishex(fp[1]))
++ if (fp <= (ep - 2) && c == '\\' && *fp && ishex(fp[0]) && ishex(fp[1]))
+ {
+ c = (char)(hex2bin(fp[0]) * 16 + hex2bin(fp[1]));
+ fp += 2;
+@@ -431,6 +431,9 @@ int SLPCompareNamingAuth(size_t srvtypelen, const char * srvtype,
+ return 1;
+ }
+
++#define SERVICE_TAG "service:"
++#define SERVICE_LEN (sizeof(SERVICE_TAG)-1)
++
+ /** Compare service types.
+ *
+ * Determine if two service type strings refer to the same service type.
+@@ -449,17 +452,15 @@ int SLPCompareSrvType(size_t lsrvtypelen, const char * lsrvtype,
+ char * colon;
+
+ /* Skip "service:" */
+- if (strncasecmp(lsrvtype, "service:", lsrvtypelen > 8?
+- 8: lsrvtypelen) == 0)
++ if (lsrvtypelen >= SERVICE_LEN && strncasecmp(lsrvtype, SERVICE_TAG, SERVICE_LEN) == 0)
+ {
+- lsrvtypelen = lsrvtypelen - 8;
+- lsrvtype = lsrvtype + 8;
++ lsrvtypelen = lsrvtypelen - SERVICE_LEN;
++ lsrvtype = lsrvtype + SERVICE_LEN;
+ }
+- if (strncasecmp(rsrvtype, "service:", rsrvtypelen > 8?
+- 8: rsrvtypelen) == 0)
++ if (rsrvtypelen >= SERVICE_LEN && strncasecmp(rsrvtype, SERVICE_TAG, SERVICE_LEN) == 0)
+ {
+- rsrvtypelen = rsrvtypelen - 8;
+- rsrvtype = rsrvtype + 8;
++ rsrvtypelen = rsrvtypelen - SERVICE_LEN;
++ rsrvtype = rsrvtype + SERVICE_LEN;
+ }
+ if (memchr(lsrvtype, ':', lsrvtypelen))
+ {
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/openslp.git/commitdiff/4476dc582fdded22b7ec810dc4eeab187b56bf59
More information about the pld-cvs-commit
mailing list