Skip to content

Commit c318a03

Browse files
authored
[3.13] gh-111178: Fix getsockaddrarg() undefined behavior (#131668) (#131977)
gh-111178: Fix getsockaddrarg() undefined behavior (#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 8cd29c2)
1 parent 05e7fa2 commit c318a03

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
@@ -1485,11 +1485,15 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
14851485
struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
14861486
#if defined(__NetBSD__) || defined(__DragonFly__)
14871487
return makebdaddr(&_BT_HCI_MEMB(a, bdaddr));
1488-
#else /* __NetBSD__ || __DragonFly__ */
1488+
#elif defined(__FreeBSD__)
1489+
char *node = _BT_HCI_MEMB(a, node);
1490+
size_t len = strnlen(node, sizeof(_BT_HCI_MEMB(a, node)));
1491+
return PyBytes_FromStringAndSize(node, (Py_ssize_t)len);
1492+
#else
14891493
PyObject *ret = NULL;
14901494
ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev));
14911495
return ret;
1492-
#endif /* !(__NetBSD__ || __DragonFly__) */
1496+
#endif
14931497
}
14941498

14951499
#if !defined(__FreeBSD__)
@@ -2005,12 +2009,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
20052009
struct sockaddr_l2 *addr = &addrbuf->bt_l2;
20062010
memset(addr, 0, sizeof(struct sockaddr_l2));
20072011
_BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
2008-
if (!PyArg_ParseTuple(args, "si", &straddr,
2009-
&_BT_L2_MEMB(addr, psm))) {
2012+
unsigned short psm;
2013+
if (!PyArg_ParseTuple(args, "sH", &straddr, &psm)) {
20102014
PyErr_Format(PyExc_OSError,
20112015
"%s(): wrong format", caller);
20122016
return 0;
20132017
}
2018+
_BT_L2_MEMB(addr, psm) = psm;
2019+
20142020
if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
20152021
return 0;
20162022

@@ -2023,12 +2029,21 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
20232029
const char *straddr;
20242030
struct sockaddr_rc *addr = &addrbuf->bt_rc;
20252031
_BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
2026-
if (!PyArg_ParseTuple(args, "si", &straddr,
2027-
&_BT_RC_MEMB(addr, channel))) {
2028-
PyErr_Format(PyExc_OSError,
2029-
"%s(): wrong format", caller);
2032+
#ifdef MS_WINDOWS
2033+
unsigned long channel;
2034+
# define FORMAT_CHANNEL "k"
2035+
#else
2036+
unsigned char channel;
2037+
# define FORMAT_CHANNEL "B"
2038+
#endif
2039+
if (!PyArg_ParseTuple(args, "s" FORMAT_CHANNEL,
2040+
&straddr, &channel)) {
2041+
PyErr_Format(PyExc_OSError, "%s(): wrong format", caller);
20302042
return 0;
20312043
}
2044+
#undef FORMAT_CHANNEL
2045+
_BT_RC_MEMB(addr, channel) = channel;
2046+
20322047
if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
20332048
return 0;
20342049

@@ -2050,14 +2065,37 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
20502065
straddr = PyBytes_AS_STRING(args);
20512066
if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0)
20522067
return 0;
2053-
#else /* __NetBSD__ || __DragonFly__ */
2068+
#elif defined(__FreeBSD__)
2069+
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
2070+
if (!PyBytes_Check(args)) {
2071+
PyErr_Format(PyExc_OSError, "%s: "
2072+
"wrong node format", caller);
2073+
return 0;
2074+
}
2075+
const char *straddr = PyBytes_AS_STRING(args);
2076+
size_t len = PyBytes_GET_SIZE(args);
2077+
if (strlen(straddr) != len) {
2078+
PyErr_Format(PyExc_ValueError, "%s: "
2079+
"node contains embedded null character", caller);
2080+
return 0;
2081+
}
2082+
if (len > sizeof(_BT_HCI_MEMB(addr, node))) {
2083+
PyErr_Format(PyExc_ValueError, "%s: "
2084+
"node too long", caller);
2085+
return 0;
2086+
}
2087+
strncpy(_BT_HCI_MEMB(addr, node), straddr,
2088+
sizeof(_BT_HCI_MEMB(addr, node)));
2089+
#else
20542090
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
2055-
if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) {
2091+
unsigned short dev = _BT_HCI_MEMB(addr, dev);
2092+
if (!PyArg_ParseTuple(args, "H", &dev)) {
20562093
PyErr_Format(PyExc_OSError,
20572094
"%s(): wrong format", caller);
20582095
return 0;
20592096
}
2060-
#endif /* !(__NetBSD__ || __DragonFly__) */
2097+
_BT_HCI_MEMB(addr, dev) = dev;
2098+
#endif
20612099
*len_ret = sizeof *addr;
20622100
return 1;
20632101
}

0 commit comments

Comments
 (0)