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.
This commit is contained in:
Victor Stinner 2019-10-10 21:30:20 +02:00 committed by GitHub
parent 1dbe537385
commit d565fb9828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 39 deletions

View File

@ -1688,14 +1688,13 @@ idna_converter(PyObject *obj, struct maybe_idna *data)
static int static int
getsockaddrarg(PySocketSockObject *s, PyObject *args, 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) { switch (s->sock_family) {
#if defined(AF_UNIX) #if defined(AF_UNIX)
case AF_UNIX: case AF_UNIX:
{ {
struct sockaddr_un* addr;
Py_buffer path; Py_buffer path;
int retval = 0; int retval = 0;
@ -1713,7 +1712,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
} }
assert(path.len >= 0); assert(path.len >= 0);
addr = (struct sockaddr_un*)addr_ret; struct sockaddr_un* addr = &addrbuf->un;
#ifdef __linux__ #ifdef __linux__
if (path.len > 0 && *(const char *)path.buf == 0) { if (path.len > 0 && *(const char *)path.buf == 0) {
/* Linux abstract namespace extension */ /* Linux abstract namespace extension */
@ -1748,9 +1747,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#if defined(AF_NETLINK) #if defined(AF_NETLINK)
case AF_NETLINK: case AF_NETLINK:
{ {
struct sockaddr_nl* addr;
int pid, groups; int pid, groups;
addr = (struct sockaddr_nl *)addr_ret; struct sockaddr_nl* addr = &addrbuf->nl;
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_Format( PyErr_Format(
PyExc_TypeError, PyExc_TypeError,
@ -1776,9 +1774,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#if defined(AF_QIPCRTR) #if defined(AF_QIPCRTR)
case AF_QIPCRTR: case AF_QIPCRTR:
{ {
struct sockaddr_qrtr* addr;
unsigned int node, port; unsigned int node, port;
addr = (struct sockaddr_qrtr *)addr_ret; struct sockaddr_qrtr* addr = &addrbuf->sq;
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_Format( PyErr_Format(
PyExc_TypeError, PyExc_TypeError,
@ -1800,9 +1797,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#if defined(AF_VSOCK) #if defined(AF_VSOCK)
case AF_VSOCK: case AF_VSOCK:
{ {
struct sockaddr_vm* addr; struct sockaddr_vm* addr = &addrbuf->vm;
int port, cid; int port, cid;
addr = (struct sockaddr_vm *)addr_ret;
memset(addr, 0, sizeof(struct sockaddr_vm)); memset(addr, 0, sizeof(struct sockaddr_vm));
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_Format( PyErr_Format(
@ -1830,7 +1826,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
case AF_INET: case AF_INET:
{ {
struct sockaddr_in* addr;
struct maybe_idna host = {NULL, NULL}; struct maybe_idna host = {NULL, NULL};
int port, result; int port, result;
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
@ -1852,7 +1847,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
} }
return 0; return 0;
} }
addr=(struct sockaddr_in*)addr_ret; struct sockaddr_in* addr = &addrbuf->in;
result = setipaddr(host.buf, (struct sockaddr *)addr, result = setipaddr(host.buf, (struct sockaddr *)addr,
sizeof(*addr), AF_INET); sizeof(*addr), AF_INET);
idna_cleanup(&host); idna_cleanup(&host);
@ -1873,7 +1868,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
case AF_INET6: case AF_INET6:
{ {
struct sockaddr_in6* addr;
struct maybe_idna host = {NULL, NULL}; struct maybe_idna host = {NULL, NULL};
int port, result; int port, result;
unsigned int flowinfo, scope_id; unsigned int flowinfo, scope_id;
@ -1898,7 +1892,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
} }
return 0; return 0;
} }
addr = (struct sockaddr_in6*)addr_ret; struct sockaddr_in6* addr = &addrbuf->in6;
result = setipaddr(host.buf, (struct sockaddr *)addr, result = setipaddr(host.buf, (struct sockaddr *)addr,
sizeof(*addr), AF_INET6); sizeof(*addr), AF_INET6);
idna_cleanup(&host); idna_cleanup(&host);
@ -1932,10 +1926,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef BTPROTO_L2CAP #ifdef BTPROTO_L2CAP
case BTPROTO_L2CAP: case BTPROTO_L2CAP:
{ {
struct sockaddr_l2 *addr;
const char *straddr; const char *straddr;
addr = (struct sockaddr_l2 *)addr_ret; struct sockaddr_l2 *addr = &addrbuf->bt_l2;
memset(addr, 0, sizeof(struct sockaddr_l2)); memset(addr, 0, sizeof(struct sockaddr_l2));
_BT_L2_MEMB(addr, family) = AF_BLUETOOTH; _BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyArg_ParseTuple(args, "si", &straddr, if (!PyArg_ParseTuple(args, "si", &straddr,
@ -1953,10 +1946,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#endif /* BTPROTO_L2CAP */ #endif /* BTPROTO_L2CAP */
case BTPROTO_RFCOMM: case BTPROTO_RFCOMM:
{ {
struct sockaddr_rc *addr;
const char *straddr; const char *straddr;
struct sockaddr_rc *addr = &addrbuf->bt_rc;
addr = (struct sockaddr_rc *)addr_ret;
_BT_RC_MEMB(addr, family) = AF_BLUETOOTH; _BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyArg_ParseTuple(args, "si", &straddr, if (!PyArg_ParseTuple(args, "si", &straddr,
&_BT_RC_MEMB(addr, channel))) { &_BT_RC_MEMB(addr, channel))) {
@ -1973,7 +1964,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef BTPROTO_HCI #ifdef BTPROTO_HCI
case 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__) #if defined(__NetBSD__) || defined(__DragonFly__)
const char *straddr; const char *straddr;
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
@ -1999,10 +1990,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#if !defined(__FreeBSD__) #if !defined(__FreeBSD__)
case BTPROTO_SCO: case BTPROTO_SCO:
{ {
struct sockaddr_sco *addr;
const char *straddr; const char *straddr;
addr = (struct sockaddr_sco *)addr_ret; struct sockaddr_sco *addr = &addrbuf->bt_sco;
_BT_SCO_MEMB(addr, family) = AF_BLUETOOTH; _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyBytes_Check(args)) { if (!PyBytes_Check(args)) {
PyErr_Format(PyExc_OSError, PyErr_Format(PyExc_OSError,
@ -2029,7 +2019,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFINDEX) #if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFINDEX)
case AF_PACKET: case AF_PACKET:
{ {
struct sockaddr_ll* addr;
struct ifreq ifr; struct ifreq ifr;
const char *interfaceName; const char *interfaceName;
int protoNumber; int protoNumber;
@ -2080,7 +2069,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
PyBuffer_Release(&haddr); PyBuffer_Release(&haddr);
return 0; return 0;
} }
addr = (struct sockaddr_ll*)addr_ret; struct sockaddr_ll* addr = &addrbuf->ll;
addr->sll_family = AF_PACKET; addr->sll_family = AF_PACKET;
addr->sll_protocol = htons((short)protoNumber); addr->sll_protocol = htons((short)protoNumber);
addr->sll_ifindex = ifr.ifr_ifindex; addr->sll_ifindex = ifr.ifr_ifindex;
@ -2103,7 +2092,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
{ {
unsigned int atype, v1, v2, v3; unsigned int atype, v1, v2, v3;
unsigned int scope = TIPC_CLUSTER_SCOPE; unsigned int scope = TIPC_CLUSTER_SCOPE;
struct sockaddr_tipc *addr;
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_Format( PyErr_Format(
@ -2121,7 +2109,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
return 0; return 0;
} }
addr = (struct sockaddr_tipc *) addr_ret; struct sockaddr_tipc *addr = &addrbuf->tipc;
memset(addr, 0, sizeof(struct sockaddr_tipc)); memset(addr, 0, sizeof(struct sockaddr_tipc));
addr->family = AF_TIPC; addr->family = AF_TIPC;
@ -2162,11 +2150,10 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#endif #endif
#if defined(CAN_RAW) || defined(CAN_BCM) #if defined(CAN_RAW) || defined(CAN_BCM)
{ {
struct sockaddr_can *addr;
PyObject *interfaceName; PyObject *interfaceName;
struct ifreq ifr; struct ifreq ifr;
Py_ssize_t len; Py_ssize_t len;
addr = (struct sockaddr_can *)addr_ret; struct sockaddr_can *addr = &addrbuf->can;
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
@ -2213,13 +2200,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef CAN_ISOTP #ifdef CAN_ISOTP
case CAN_ISOTP: case CAN_ISOTP:
{ {
struct sockaddr_can *addr;
PyObject *interfaceName; PyObject *interfaceName;
struct ifreq ifr; struct ifreq ifr;
Py_ssize_t len; Py_ssize_t len;
unsigned long int rx_id, tx_id; 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, if (!PyArg_ParseTuple(args, "O&kk", PyUnicode_FSConverter,
&interfaceName, &interfaceName,
@ -2269,9 +2255,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef SYSPROTO_CONTROL #ifdef SYSPROTO_CONTROL
case SYSPROTO_CONTROL: case SYSPROTO_CONTROL:
{ {
struct sockaddr_ctl *addr; struct sockaddr_ctl *addr = &addrbuf->ctl;
addr = (struct sockaddr_ctl *)addr_ret;
addr->sc_family = AF_SYSTEM; addr->sc_family = AF_SYSTEM;
addr->ss_sysaddr = AF_SYS_CONTROL; addr->ss_sysaddr = AF_SYS_CONTROL;
@ -2323,10 +2307,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef HAVE_SOCKADDR_ALG #ifdef HAVE_SOCKADDR_ALG
case AF_ALG: case AF_ALG:
{ {
struct sockaddr_alg *sa;
const char *type; const char *type;
const char *name; const char *name;
sa = (struct sockaddr_alg *)addr_ret; struct sockaddr_alg *sa = &addrbuf->alg;
memset(sa, 0, sizeof(*sa)); memset(sa, 0, sizeof(*sa));
sa->salg_family = AF_ALG; sa->salg_family = AF_ALG;
@ -3110,7 +3093,7 @@ sock_bind(PySocketSockObject *s, PyObject *addro)
int addrlen; int addrlen;
int res; int res;
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "bind")) { if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "bind")) {
return NULL; return NULL;
} }
@ -3280,7 +3263,7 @@ sock_connect(PySocketSockObject *s, PyObject *addro)
int addrlen; int addrlen;
int res; int res;
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "connect")) { if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect")) {
return NULL; return NULL;
} }
@ -3311,7 +3294,7 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
int addrlen; int addrlen;
int res; int res;
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "connect_ex")) { if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect_ex")) {
return NULL; return NULL;
} }
@ -4316,7 +4299,7 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
return select_error(); return select_error();
} }
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "sendto")) { if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "sendto")) {
PyBuffer_Release(&pbuf); PyBuffer_Release(&pbuf);
return NULL; return NULL;
} }
@ -4451,7 +4434,7 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args)
/* Parse destination address. */ /* Parse destination address. */
if (addr_arg != NULL && addr_arg != Py_None) { if (addr_arg != NULL && addr_arg != Py_None) {
if (!getsockaddrarg(s, addr_arg, SAS2SA(&addrbuf), &addrlen, if (!getsockaddrarg(s, addr_arg, &addrbuf, &addrlen,
"sendmsg")) "sendmsg"))
{ {
goto finally; goto finally;

View File

@ -261,6 +261,9 @@ typedef union sock_addr {
#ifdef AF_VSOCK #ifdef AF_VSOCK
struct sockaddr_vm vm; struct sockaddr_vm vm;
#endif #endif
#ifdef HAVE_LINUX_TIPC_H
struct sockaddr_tipc tipc;
#endif
} sock_addr_t; } sock_addr_t;
/* The object holding a socket. It holds some extra information, /* The object holding a socket. It holds some extra information,