Use sockaddr_storage instead of sockaddr to prevent stack smashing

This commit is contained in:
Yury Selivanov 2016-05-23 17:13:45 -04:00
parent 90214faa05
commit 2116189e70
4 changed files with 26 additions and 22 deletions

View File

@ -160,16 +160,17 @@ cdef __static_getaddrinfo_pyaddr(object host, object port,
int proto, int flags):
cdef:
system.sockaddr addr
system.sockaddr_storage addr
try:
(af, type, proto) = __static_getaddrinfo(host, port, family, type,
proto, &addr)
(af, type, proto) = __static_getaddrinfo(
host, port, family, type,
proto, <system.sockaddr*>&addr)
except LookupError:
return
try:
pyaddr = __convert_sockaddr_to_pyaddr(&addr)
pyaddr = __convert_sockaddr_to_pyaddr(<system.sockaddr*>&addr)
except:
return

View File

@ -4,12 +4,13 @@ cdef class UDPTransport(UVBaseTransport):
int _family
bint _address_set
system.sockaddr _address
system.sockaddr_storage _address
object _cached_py_address
cdef _init(self, Loop loop, unsigned int family)
cdef _set_remote_address(self, system.sockaddr address)
cdef _set_remote_address(self, system.sockaddr* addr,
size_t addr_len)
cdef _bind(self, system.sockaddr* addr, bint reuse_addr)
cdef _open(self, int family, int sockfd)

View File

@ -13,7 +13,7 @@ cdef class _UDPSendContext:
bint closed
system.sockaddr addr
system.sockaddr_storage addr
cdef close(self):
if self.closed:
@ -81,9 +81,10 @@ cdef class UDPTransport(UVBaseTransport):
self._finish_init()
cdef _set_remote_address(self, system.sockaddr address):
cdef _set_remote_address(self, system.sockaddr* addr,
size_t addr_len):
memcpy(&self._address, addr, addr_len)
self._address_set = 1
self._address = address
cdef _open(self, int family, int sockfd):
if family in (uv.AF_INET, uv.AF_INET6):
@ -199,7 +200,7 @@ cdef class UDPTransport(UVBaseTransport):
if self._address_set and addr is not None:
if self._cached_py_address is None:
self._cached_py_address = __convert_sockaddr_to_pyaddr(
&self._address)
<system.sockaddr*>&self._address)
if self._cached_py_address != addr:
raise ValueError('Invalid address: must be None or %s' %
@ -216,7 +217,8 @@ cdef class UDPTransport(UVBaseTransport):
raise RuntimeError(
'undable to perform send operation: no address')
else:
__convert_pyaddr_to_sockaddr(self._family, addr, &ctx.addr)
__convert_pyaddr_to_sockaddr(self._family, addr,
<system.sockaddr*>&ctx.addr)
except:
ctx.close()
raise
@ -225,7 +227,7 @@ cdef class UDPTransport(UVBaseTransport):
<uv.uv_udp_t*>self._handle,
&ctx.uv_buf,
1,
&ctx.addr,
<system.sockaddr*>&ctx.addr,
__uv_udp_on_send)
if err < 0:

View File

@ -14,7 +14,7 @@ from .includes.python cimport PyMem_Malloc, PyMem_Free, \
PyErr_SetInterrupt
from libc.stdint cimport uint64_t
from libc.string cimport memset, strerror
from libc.string cimport memset, strerror, memcpy
from libc cimport errno
from cpython cimport PyObject
@ -1307,9 +1307,9 @@ cdef class Loop:
system.addrinfo *lai_iter = NULL
system.addrinfo rai_static
system.sockaddr rai_addr_static
system.sockaddr_storage rai_addr_static
system.addrinfo lai_static
system.sockaddr lai_addr_static
system.sockaddr_storage lai_addr_static
object app_protocol
object protocol
@ -1340,7 +1340,7 @@ cdef class Loop:
try:
__static_getaddrinfo(
host, port, family, uv.SOCK_STREAM,
proto, &rai_addr_static)
proto, <system.sockaddr*>&rai_addr_static)
except LookupError:
f1 = self._getaddrinfo(
host, port, family,
@ -1349,7 +1349,7 @@ cdef class Loop:
fs.append(f1)
else:
rai_static.ai_addr = &rai_addr_static
rai_static.ai_addr = <system.sockaddr*>&rai_addr_static
rai_static.ai_next = NULL
rai = &rai_static
@ -1363,7 +1363,7 @@ cdef class Loop:
__static_getaddrinfo(
local_addr[0], local_addr[1],
family, uv.SOCK_STREAM,
proto, &lai_addr_static)
proto, <system.sockaddr*>&lai_addr_static)
except LookupError:
f2 = self._getaddrinfo(
local_addr[0], local_addr[1], family,
@ -1372,7 +1372,7 @@ cdef class Loop:
fs.append(f2)
else:
lai_static.ai_addr = &lai_addr_static
lai_static.ai_addr = <system.sockaddr*>&lai_addr_static
lai_static.ai_next = NULL
lai = &rai_static
@ -2209,7 +2209,7 @@ cdef class Loop:
udp = UDPTransport.__new__(UDPTransport)
rai = (<AddrInfo>rads).data
udp._init(self, rai.ai_family)
udp._set_remote_address(rai.ai_addr[0])
udp._set_remote_address(rai.ai_addr, rai.ai_addrlen)
else:
if family not in (uv.AF_INET, uv.AF_INET6):
raise ValueError('unexpected address family')
@ -2253,14 +2253,14 @@ cdef class Loop:
if rai.ai_protocol != lai.ai_protocol:
rai = rai.ai_next
continue
udp._set_remote_address(rai.ai_addr[0])
udp._set_remote_address(rai.ai_addr, rai.ai_addrlen)
break
else:
raise OSError(
'could not bind to remote_addr {}'.format(
remote_addr))
udp._set_remote_address(rai.ai_addr[0])
udp._set_remote_address(rai.ai_addr, rai.ai_addrlen)
if allow_broadcast:
udp._set_broadcast(1)