Skip to content

Commit afb3f33

Browse files
[3.12] gh-111178: Fix getsockaddrarg() undefined behavior (GH-131668) (GH-131977) (#131979)
[3.13] gh-111178: Fix getsockaddrarg() undefined behavior (GH-131668) (GH-131977) gh-111178: Fix getsockaddrarg() undefined behavior (GH-131668) Don't pass direct references to sockaddr members since their type may not match PyArg_ParseTuple() types. Instead, use temporary 'int' and 'unsigned char' variables, and update sockaddr members afterwards. On FreeBSD, treat BTPROTO_HCI node name as a bytes string, not as an integer. (cherry picked from commit c318a03) Co-authored-by: Victor Stinner <[email protected]> (cherry picked from commit 8cd29c2) Co-authored-by: Victor Stinner <[email protected]>
1 parent 756676f commit afb3f33

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:mod:`socket`: Fix code parsing AF_BLUETOOTH socket addresses.

Modules/socketmodule.c

+49-11
Original file line numberDiff line numberDiff line change
@@ -1491,11 +1491,15 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
14911491
struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
14921492
#if defined(__NetBSD__) || defined(__DragonFly__)
14931493
return makebdaddr(&_BT_HCI_MEMB(a, bdaddr));
1494-
#else /* __NetBSD__ || __DragonFly__ */
1494+
#elif defined(__FreeBSD__)
1495+
char *node = _BT_HCI_MEMB(a, node);
1496+
size_t len = strnlen(node, sizeof(_BT_HCI_MEMB(a, node)));
1497+
return PyBytes_FromStringAndSize(node, (Py_ssize_t)len);
1498+
#else
14951499
PyObject *ret = NULL;
14961500
ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev));
14971501
return ret;
1498-
#endif /* !(__NetBSD__ || __DragonFly__) */
1502+
#endif
14991503
}
15001504

15011505
#if !defined(__FreeBSD__)
@@ -2014,12 +2018,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
20142018
struct sockaddr_l2 *addr = &addrbuf->bt_l2;
20152019
memset(addr, 0, sizeof(struct sockaddr_l2));
20162020
_BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
2017-
if (!PyArg_ParseTuple(args, "si", &straddr,
2018-
&_BT_L2_MEMB(addr, psm))) {
2021+
unsigned short psm;
2022+
if (!PyArg_ParseTuple(args, "sH", &straddr, &psm)) {
20192023
PyErr_Format(PyExc_OSError,
20202024
"%s(): wrong format", caller);
20212025
return 0;
20222026
}
2027+
_BT_L2_MEMB(addr, psm) = psm;
2028+
20232029
if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
20242030
return 0;
20252031

@@ -2032,12 +2038,21 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
20322038
const char *straddr;
20332039
struct sockaddr_rc *addr = &addrbuf->bt_rc;
20342040
_BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
2035-
if (!PyArg_ParseTuple(args, "si", &straddr,
2036-
&_BT_RC_MEMB(addr, channel))) {
2037-
PyErr_Format(PyExc_OSError,
2038-
"%s(): wrong format", caller);
2041+
#ifdef MS_WINDOWS
2042+
unsigned long channel;
2043+
# define FORMAT_CHANNEL "k"
2044+
#else
2045+
unsigned char channel;
2046+
# define FORMAT_CHANNEL "B"
2047+
#endif
2048+
if (!PyArg_ParseTuple(args, "s" FORMAT_CHANNEL,
2049+
&straddr, &channel)) {
2050+
PyErr_Format(PyExc_OSError, "%s(): wrong format", caller);
20392051
return 0;
20402052
}
2053+
#undef FORMAT_CHANNEL
2054+
_BT_RC_MEMB(addr, channel) = channel;
2055+
20412056
if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
20422057
return 0;
20432058

@@ -2059,14 +2074,37 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
20592074
straddr = PyBytes_AS_STRING(args);
20602075
if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0)
20612076
return 0;
2062-
#else /* __NetBSD__ || __DragonFly__ */
2077+
#elif defined(__FreeBSD__)
2078+
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
2079+
if (!PyBytes_Check(args)) {
2080+
PyErr_Format(PyExc_OSError, "%s: "
2081+
"wrong node format", caller);
2082+
return 0;
2083+
}
2084+
const char *straddr = PyBytes_AS_STRING(args);
2085+
size_t len = PyBytes_GET_SIZE(args);
2086+
if (strlen(straddr) != len) {
2087+
PyErr_Format(PyExc_ValueError, "%s: "
2088+
"node contains embedded null character", caller);
2089+
return 0;
2090+
}
2091+
if (len > sizeof(_BT_HCI_MEMB(addr, node))) {
2092+
PyErr_Format(PyExc_ValueError, "%s: "
2093+
"node too long", caller);
2094+
return 0;
2095+
}
2096+
strncpy(_BT_HCI_MEMB(addr, node), straddr,
2097+
sizeof(_BT_HCI_MEMB(addr, node)));
2098+
#else
20632099
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
2064-
if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) {
2100+
unsigned short dev = _BT_HCI_MEMB(addr, dev);
2101+
if (!PyArg_ParseTuple(args, "H", &dev)) {
20652102
PyErr_Format(PyExc_OSError,
20662103
"%s(): wrong format", caller);
20672104
return 0;
20682105
}
2069-
#endif /* !(__NetBSD__ || __DragonFly__) */
2106+
_BT_HCI_MEMB(addr, dev) = dev;
2107+
#endif
20702108
*len_ret = sizeof *addr;
20712109
return 1;
20722110
}

0 commit comments

Comments
 (0)