https://github.com/python/cpython/commit/c318a03b17c3e58e9c46beb84ab7070b7baa303b
commit: c318a03b17c3e58e9c46beb84ab7070b7baa303b
branch: 3.13
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2025-04-01T14:40:00Z
summary:
[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 8cd29c2b533e5a1a262238695d05f2a7c44d6455)
files:
A Misc/NEWS.d/next/Library/2025-03-28-11-26-31.gh-issue-131668.tcS4xS.rst
M Modules/socketmodule.c
diff --git
a/Misc/NEWS.d/next/Library/2025-03-28-11-26-31.gh-issue-131668.tcS4xS.rst
b/Misc/NEWS.d/next/Library/2025-03-28-11-26-31.gh-issue-131668.tcS4xS.rst
new file mode 100644
index 00000000000000..ec04cdd30a2f28
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-03-28-11-26-31.gh-issue-131668.tcS4xS.rst
@@ -0,0 +1 @@
+:mod:`socket`: Fix code parsing AF_BLUETOOTH socket addresses.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 1c0bc796732120..b8a503c9883a1d 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1485,11 +1485,15 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr,
size_t addrlen, int proto)
struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
#if defined(__NetBSD__) || defined(__DragonFly__)
return makebdaddr(&_BT_HCI_MEMB(a, bdaddr));
-#else /* __NetBSD__ || __DragonFly__ */
+#elif defined(__FreeBSD__)
+ char *node = _BT_HCI_MEMB(a, node);
+ size_t len = strnlen(node, sizeof(_BT_HCI_MEMB(a, node)));
+ return PyBytes_FromStringAndSize(node, (Py_ssize_t)len);
+#else
PyObject *ret = NULL;
ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev));
return ret;
-#endif /* !(__NetBSD__ || __DragonFly__) */
+#endif
}
#if !defined(__FreeBSD__)
@@ -2005,12 +2009,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
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,
- &_BT_L2_MEMB(addr, psm))) {
+ unsigned short psm;
+ if (!PyArg_ParseTuple(args, "sH", &straddr, &psm)) {
PyErr_Format(PyExc_OSError,
"%s(): wrong format", caller);
return 0;
}
+ _BT_L2_MEMB(addr, psm) = psm;
+
if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
return 0;
@@ -2023,12 +2029,21 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
const char *straddr;
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))) {
- PyErr_Format(PyExc_OSError,
- "%s(): wrong format", caller);
+#ifdef MS_WINDOWS
+ unsigned long channel;
+# define FORMAT_CHANNEL "k"
+#else
+ unsigned char channel;
+# define FORMAT_CHANNEL "B"
+#endif
+ if (!PyArg_ParseTuple(args, "s" FORMAT_CHANNEL,
+ &straddr, &channel)) {
+ PyErr_Format(PyExc_OSError, "%s(): wrong format", caller);
return 0;
}
+#undef FORMAT_CHANNEL
+ _BT_RC_MEMB(addr, channel) = channel;
+
if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
return 0;
@@ -2050,14 +2065,37 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
straddr = PyBytes_AS_STRING(args);
if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0)
return 0;
-#else /* __NetBSD__ || __DragonFly__ */
+#elif defined(__FreeBSD__)
+ _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
+ if (!PyBytes_Check(args)) {
+ PyErr_Format(PyExc_OSError, "%s: "
+ "wrong node format", caller);
+ return 0;
+ }
+ const char *straddr = PyBytes_AS_STRING(args);
+ size_t len = PyBytes_GET_SIZE(args);
+ if (strlen(straddr) != len) {
+ PyErr_Format(PyExc_ValueError, "%s: "
+ "node contains embedded null character", caller);
+ return 0;
+ }
+ if (len > sizeof(_BT_HCI_MEMB(addr, node))) {
+ PyErr_Format(PyExc_ValueError, "%s: "
+ "node too long", caller);
+ return 0;
+ }
+ strncpy(_BT_HCI_MEMB(addr, node), straddr,
+ sizeof(_BT_HCI_MEMB(addr, node)));
+#else
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
- if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) {
+ unsigned short dev = _BT_HCI_MEMB(addr, dev);
+ if (!PyArg_ParseTuple(args, "H", &dev)) {
PyErr_Format(PyExc_OSError,
"%s(): wrong format", caller);
return 0;
}
-#endif /* !(__NetBSD__ || __DragonFly__) */
+ _BT_HCI_MEMB(addr, dev) = dev;
+#endif
*len_ret = sizeof *addr;
return 1;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]