From d565fb9828ee9c494bb7a80057a08e4738273e30 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. --- 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 c649fa3c982..d42fa7ce182 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1688,14 +1688,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; @@ -1713,7 +1712,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 */ @@ -1748,9 +1747,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, @@ -1776,9 +1774,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, @@ -1800,9 +1797,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( @@ -1830,7 +1826,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)) { @@ -1852,7 +1847,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); @@ -1873,7 +1868,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; @@ -1898,7 +1892,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); @@ -1932,10 +1926,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #ifdef BTPROTO_L2CAP 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, @@ -1953,10 +1946,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #endif /* BTPROTO_L2CAP */ 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))) { @@ -1973,7 +1964,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #ifdef BTPROTO_HCI 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; @@ -1999,10 +1990,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, @@ -2029,7 +2019,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; @@ -2080,7 +2069,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; @@ -2103,7 +2092,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( @@ -2121,7 +2109,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; @@ -2162,11 +2150,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, @@ -2213,13 +2200,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, @@ -2269,9 +2255,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; @@ -2323,10 +2307,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; @@ -3110,7 +3093,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; } @@ -3280,7 +3263,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; } @@ -3311,7 +3294,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; } @@ -4316,7 +4299,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; } @@ -4451,7 +4434,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 3d95fe709ac..e06e4c38882 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -261,6 +261,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,