summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2013-02-24 16:46:19 +0000
committerDavid Mitchell <davem@iabyn.com>2013-02-24 20:27:17 +0000
commite5086424505dcbfc5e26aeb984b769ecf5ffed01 (patch)
tree73f2d799d21fc90042fd92c31e888d7d690d718c
parent7f5f08b152bb9d0c88efd1dd0f70d45e427efe1c (diff)
downloadperl-e5086424505dcbfc5e26aeb984b769ecf5ffed01.tar.gz
Socket::unpack_sockaddr_un heap-buffer-overflow
[perl #111594] A (fairly harmless) read buffer overflow can occur when copying sockaddr buffers. Cherry-pick the fix from Socket 2.009 to keep ASAN happy.
-rw-r--r--ext/Socket/Socket.xs18
1 files changed, 11 insertions, 7 deletions
diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs
index 9214fc15bb..e5abb71912 100644
--- a/ext/Socket/Socket.xs
+++ b/ext/Socket/Socket.xs
@@ -557,18 +557,22 @@ unpack_sockaddr_un(sun_sv)
STRLEN sockaddrlen;
char * sun_ad = SvPVbyte(sun_sv,sockaddrlen);
int addr_len;
-# ifndef __linux__
+# ifdef __linux__
/* On Linux sockaddrlen on sockets returned by accept, recvfrom,
getpeername and getsockname is not equal to sizeof(addr). */
- if (sockaddrlen != sizeof(addr)) {
- croak("Bad arg length for %s, length is %d, should be %d",
- "Socket::unpack_sockaddr_un",
- sockaddrlen, sizeof(addr));
+ if (sockaddrlen < sizeof(addr)) {
+ Copy(sun_ad, &addr, sockaddrlen, char);
+ Zero(((char*)&addr) + sockaddrlen, sizeof(addr) - sockaddrlen, char);
+ } else {
+ Copy(sun_ad, &addr, sizeof(addr), char);
}
+# else
+ if (sockaddrlen != sizeof(addr))
+ croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
+ "Socket::unpack_sockaddr_un", (UV)sockaddrlen, (UV)sizeof(addr));
+ Copy(sun_ad, &addr, sizeof(addr), char);
# endif
- Copy( sun_ad, &addr, sizeof addr, char );
-
if ( addr.sun_family != AF_UNIX ) {
croak("Bad address family for %s, got %d, should be %d",
"Socket::unpack_sockaddr_un",