From 2c147f7f5e332011755c8715268c5de54cc4650d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Oct 2019 21:30:20 +0200 Subject: [PATCH] bpo-38282: Rewrite getsockaddrarg() helper function (GH-16698) Rewrite getsockaddrarg() helper function of socketmodule.c (_socket module) to prevent a false alarm when compiling codde using GCC with _FORTIFY_SOURCE=2. Pass a pointer of the sock_addr_t union, rather than passing a pointer to a sockaddr structure. Add "struct sockaddr_tipc tipc;" to the sock_addr_t union. (cherry picked from commit d565fb9828ee9c494bb7a80057a08e4738273e30) Co-authored-by: Victor Stinner --- Modules/socketmodule.c | 61 +++++++++++++++--------------------------- Modules/socketmodule.h | 3 +++ 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 594a0d6efad197..d4c016ce55a6ab 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1649,14 +1649,13 @@ idna_converter(PyObject *obj, struct maybe_idna *data) static int getsockaddrarg(PySocketSockObject *s, PyObject *args, - struct sockaddr *addr_ret, int *len_ret, const char *caller) + sock_addr_t *addrbuf, int *len_ret, const char *caller) { switch (s->sock_family) { #if defined(AF_UNIX) case AF_UNIX: { - struct sockaddr_un* addr; Py_buffer path; int retval = 0; @@ -1674,7 +1673,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } assert(path.len >= 0); - addr = (struct sockaddr_un*)addr_ret; + struct sockaddr_un* addr = &addrbuf->un; #ifdef __linux__ if (path.len > 0 && *(const char *)path.buf == 0) { /* Linux abstract namespace extension */ @@ -1709,9 +1708,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #if defined(AF_NETLINK) case AF_NETLINK: { - struct sockaddr_nl* addr; int pid, groups; - addr = (struct sockaddr_nl *)addr_ret; + struct sockaddr_nl* addr = &addrbuf->nl; if (!PyTuple_Check(args)) { PyErr_Format( PyExc_TypeError, @@ -1737,9 +1735,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #if defined(AF_QIPCRTR) case AF_QIPCRTR: { - struct sockaddr_qrtr* addr; unsigned int node, port; - addr = (struct sockaddr_qrtr *)addr_ret; + struct sockaddr_qrtr* addr = &addrbuf->sq; if (!PyTuple_Check(args)) { PyErr_Format( PyExc_TypeError, @@ -1761,9 +1758,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #if defined(AF_VSOCK) case AF_VSOCK: { - struct sockaddr_vm* addr; + struct sockaddr_vm* addr = &addrbuf->vm; int port, cid; - addr = (struct sockaddr_vm *)addr_ret; memset(addr, 0, sizeof(struct sockaddr_vm)); if (!PyTuple_Check(args)) { PyErr_Format( @@ -1791,7 +1787,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, case AF_INET: { - struct sockaddr_in* addr; struct maybe_idna host = {NULL, NULL}; int port, result; if (!PyTuple_Check(args)) { @@ -1813,7 +1808,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } return 0; } - addr=(struct sockaddr_in*)addr_ret; + struct sockaddr_in* addr = &addrbuf->in; result = setipaddr(host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET); idna_cleanup(&host); @@ -1834,7 +1829,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #ifdef ENABLE_IPV6 case AF_INET6: { - struct sockaddr_in6* addr; struct maybe_idna host = {NULL, NULL}; int port, result; unsigned int flowinfo, scope_id; @@ -1859,7 +1853,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } return 0; } - addr = (struct sockaddr_in6*)addr_ret; + struct sockaddr_in6* addr = &addrbuf->in6; result = setipaddr(host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET6); idna_cleanup(&host); @@ -1892,10 +1886,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, switch (s->sock_proto) { case BTPROTO_L2CAP: { - struct sockaddr_l2 *addr; const char *straddr; - addr = (struct sockaddr_l2 *)addr_ret; + struct sockaddr_l2 *addr = &addrbuf->bt_l2; memset(addr, 0, sizeof(struct sockaddr_l2)); _BT_L2_MEMB(addr, family) = AF_BLUETOOTH; if (!PyArg_ParseTuple(args, "si", &straddr, @@ -1912,10 +1905,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } case BTPROTO_RFCOMM: { - struct sockaddr_rc *addr; const char *straddr; - - addr = (struct sockaddr_rc *)addr_ret; + struct sockaddr_rc *addr = &addrbuf->bt_rc; _BT_RC_MEMB(addr, family) = AF_BLUETOOTH; if (!PyArg_ParseTuple(args, "si", &straddr, &_BT_RC_MEMB(addr, channel))) { @@ -1931,7 +1922,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } case BTPROTO_HCI: { - struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret; + struct sockaddr_hci *addr = &addrbuf->bt_hci; #if defined(__NetBSD__) || defined(__DragonFly__) const char *straddr; _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; @@ -1957,10 +1948,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #if !defined(__FreeBSD__) case BTPROTO_SCO: { - struct sockaddr_sco *addr; const char *straddr; - addr = (struct sockaddr_sco *)addr_ret; + struct sockaddr_sco *addr = &addrbuf->bt_sco; _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH; if (!PyBytes_Check(args)) { PyErr_Format(PyExc_OSError, @@ -1986,7 +1976,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFINDEX) case AF_PACKET: { - struct sockaddr_ll* addr; struct ifreq ifr; const char *interfaceName; int protoNumber; @@ -2037,7 +2026,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyBuffer_Release(&haddr); return 0; } - addr = (struct sockaddr_ll*)addr_ret; + struct sockaddr_ll* addr = &addrbuf->ll; addr->sll_family = AF_PACKET; addr->sll_protocol = htons((short)protoNumber); addr->sll_ifindex = ifr.ifr_ifindex; @@ -2060,7 +2049,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, { unsigned int atype, v1, v2, v3; unsigned int scope = TIPC_CLUSTER_SCOPE; - struct sockaddr_tipc *addr; if (!PyTuple_Check(args)) { PyErr_Format( @@ -2078,7 +2066,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } - addr = (struct sockaddr_tipc *) addr_ret; + struct sockaddr_tipc *addr = &addrbuf->tipc; memset(addr, 0, sizeof(struct sockaddr_tipc)); addr->family = AF_TIPC; @@ -2119,11 +2107,10 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #endif #if defined(CAN_RAW) || defined(CAN_BCM) { - struct sockaddr_can *addr; PyObject *interfaceName; struct ifreq ifr; Py_ssize_t len; - addr = (struct sockaddr_can *)addr_ret; + struct sockaddr_can *addr = &addrbuf->can; if (!PyTuple_Check(args)) { PyErr_Format(PyExc_TypeError, @@ -2170,13 +2157,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #ifdef CAN_ISOTP case CAN_ISOTP: { - struct sockaddr_can *addr; PyObject *interfaceName; struct ifreq ifr; Py_ssize_t len; unsigned long int rx_id, tx_id; - addr = (struct sockaddr_can *)addr_ret; + struct sockaddr_can *addr = &addrbuf->can; if (!PyArg_ParseTuple(args, "O&kk", PyUnicode_FSConverter, &interfaceName, @@ -2226,9 +2212,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #ifdef SYSPROTO_CONTROL case SYSPROTO_CONTROL: { - struct sockaddr_ctl *addr; - - addr = (struct sockaddr_ctl *)addr_ret; + struct sockaddr_ctl *addr = &addrbuf->ctl; addr->sc_family = AF_SYSTEM; addr->ss_sysaddr = AF_SYS_CONTROL; @@ -2280,10 +2264,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #ifdef HAVE_SOCKADDR_ALG case AF_ALG: { - struct sockaddr_alg *sa; const char *type; const char *name; - sa = (struct sockaddr_alg *)addr_ret; + struct sockaddr_alg *sa = &addrbuf->alg; memset(sa, 0, sizeof(*sa)); sa->salg_family = AF_ALG; @@ -3063,7 +3046,7 @@ sock_bind(PySocketSockObject *s, PyObject *addro) int addrlen; int res; - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "bind")) { + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "bind")) { return NULL; } @@ -3233,7 +3216,7 @@ sock_connect(PySocketSockObject *s, PyObject *addro) int addrlen; int res; - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "connect")) { + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect")) { return NULL; } @@ -3264,7 +3247,7 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro) int addrlen; int res; - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "connect_ex")) { + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect_ex")) { return NULL; } @@ -4269,7 +4252,7 @@ sock_sendto(PySocketSockObject *s, PyObject *args) return select_error(); } - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "sendto")) { + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "sendto")) { PyBuffer_Release(&pbuf); return NULL; } @@ -4404,7 +4387,7 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) /* Parse destination address. */ if (addr_arg != NULL && addr_arg != Py_None) { - if (!getsockaddrarg(s, addr_arg, SAS2SA(&addrbuf), &addrlen, + if (!getsockaddrarg(s, addr_arg, &addrbuf, &addrlen, "sendmsg")) { goto finally; diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index dff1f8f4e9ce4a..b668b33d16137c 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -218,6 +218,9 @@ typedef union sock_addr { #ifdef AF_VSOCK struct sockaddr_vm vm; #endif +#ifdef HAVE_LINUX_TIPC_H + struct sockaddr_tipc tipc; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information,