aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Imai <imaipi@google.com>2016-01-08 13:20:54 +0900
committerCasey Dahlin <sadmac@google.com>2017-03-09 14:29:25 -0800
commit5e33e384dc5d19f8aa63ecd4a157e7acbaed579f (patch)
tree5811fe04a3ddca6c77f6e57fbfa036f879226ed1
parent918d4611096dbb72ea44f46c2d72ce2e36f38e3b (diff)
downloadmdnsresponder-5e33e384dc5d19f8aa63ecd4a157e7acbaed579f.tar.gz
Fix buffer overflow and null pointer dereference in mDNSResponder (CVE-2015-7988).
BUG: 25852056 Test: None (cherry-picked from 5cb016d58af2cdc40c20fa435b8143a72ddf01a2) Change-Id: I67a8262caf48b42ccb2f41adae63c22f7f4ee4c8
-rwxr-xr-xmDNSCore/mDNSEmbeddedAPI.h5
-rw-r--r--mDNSPosix/mDNSPosix.c8
-rw-r--r--mDNSShared/uds_daemon.c18
3 files changed, 24 insertions, 7 deletions
diff --git a/mDNSCore/mDNSEmbeddedAPI.h b/mDNSCore/mDNSEmbeddedAPI.h
index 3d6c12a..5c3115c 100755
--- a/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSCore/mDNSEmbeddedAPI.h
@@ -2548,8 +2548,9 @@ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, mDNSIPPort dst
extern void mDNSPlatformLock (const mDNS *const m);
extern void mDNSPlatformUnlock (const mDNS *const m);
-extern void mDNSPlatformStrCopy ( void *dst, const void *src);
-extern mDNSu32 mDNSPlatformStrLen ( const void *src);
+mDNSexport void mDNSPlatformStrCopy( void *dst, const void *src);
+mDNSexport mDNSu32 mDNSPlatformStrLCopy( void *dst, const void *src, mDNSu32 dstlen);
+mDNSexport mDNSu32 mDNSPlatformStrLen ( const void *src);
extern void mDNSPlatformMemCopy ( void *dst, const void *src, mDNSu32 len);
extern mDNSBool mDNSPlatformMemSame (const void *dst, const void *src, mDNSu32 len);
extern void mDNSPlatformMemZero ( void *dst, mDNSu32 len);
diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c
index 8a46c6f..a8ac88a 100644
--- a/mDNSPosix/mDNSPosix.c
+++ b/mDNSPosix/mDNSPosix.c
@@ -1357,6 +1357,14 @@ mDNSexport void mDNSPlatformStrCopy(void *dst, const void *src)
strcpy((char *)dst, (char *)src);
}
+// mDNS core calls this routine to copy C strings while taking the destination
+// buffer size into account.
+// On the Posix platform this maps directly to the ANSI C strncpy.
+mDNSexport mDNSu32 mDNSPlatformStrLCopy(void *dst, const void *src, mDNSu32 dstlen)
+ {
+ return (strlcpy((char *)dst, (const char *)src, dstlen));
+ }
+
// mDNS core calls this routine to get the length of a C string.
// On the Posix platform this maps directly to the ANSI C strlen.
mDNSexport mDNSu32 mDNSPlatformStrLen (const void *src)
diff --git a/mDNSShared/uds_daemon.c b/mDNSShared/uds_daemon.c
index ad5f943..e269be6 100644
--- a/mDNSShared/uds_daemon.c
+++ b/mDNSShared/uds_daemon.c
@@ -21,6 +21,7 @@
#else
#include <fcntl.h>
#include <errno.h>
+#include <cutils/log.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
@@ -1594,6 +1595,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
domainname d, srv;
mStatus err;
+ const char *msgTXTData;
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
@@ -1612,7 +1614,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
request->u.servicereg.instances = NULL;
request->u.servicereg.txtlen = 0;
request->u.servicereg.txtdata = NULL;
- mDNSPlatformStrCopy(request->u.servicereg.type_as_string, type_as_string);
+ mDNSPlatformStrLCopy(request->u.servicereg.type_as_string, type_as_string, sizeof(request->u.servicereg.type_as_string));
if (request->msgptr + 2 > request->msgend) request->msgptr = NULL;
else
@@ -1622,15 +1624,21 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
}
request->u.servicereg.txtlen = get_uint16(&request->msgptr, request->msgend);
+ msgTXTData = get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen);
+ if (!request->msgptr)
+ {
+ LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd);
+ android_errorWriteWithInfoLog(0x534e4554, "25852056", -1, NULL, 0);
+ return(mStatus_BadParamErr);
+ }
+
if (request->u.servicereg.txtlen)
{
request->u.servicereg.txtdata = mallocL("service_info txtdata", request->u.servicereg.txtlen);
if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_regservice_request - malloc");
- mDNSPlatformMemCopy(request->u.servicereg.txtdata, get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen), request->u.servicereg.txtlen);
+ mDNSPlatformMemCopy(request->u.servicereg.txtdata, msgTXTData, request->u.servicereg.txtlen);
}
- if (!request->msgptr) { LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
-
// Check for sub-types after the service type
request->u.servicereg.num_subtypes = ChopSubTypes(request->u.servicereg.type_as_string); // Note: Modifies regtype string to remove trailing subtypes
if (request->u.servicereg.num_subtypes < 0)
@@ -2169,7 +2177,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
if (!MakeDomainNameFromDNSNameString(&temp, regtype)) return(mStatus_BadParamErr);
// For over-long service types, we only allow domain "local"
- if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrCopy(domain, "local.");
+ if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrLCopy(domain, "local.", sizeof(domain));
// Set up browser info
request->u.browser.ForceMCast = (flags & kDNSServiceFlagsForceMulticast) != 0;