https://github.com/python/cpython/commit/afb3f33256c2f74c560c70ac00514722f177a1db
commit: afb3f33256c2f74c560c70ac00514722f177a1db
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: vstinner <vstin...@python.org>
date: 2025-04-01T14:56:56Z
summary:

[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 c318a03b17c3e58e9c46beb84ab7070b7baa303b)

Co-authored-by: Victor Stinner <vstin...@python.org>
(cherry picked from commit 8cd29c2b533e5a1a262238695d05f2a7c44d6455)

Co-authored-by: Victor Stinner <vstin...@python.org>

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 7f2ebba9884f98..f8943a942d4c8f 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1491,11 +1491,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__)
@@ -2014,12 +2018,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;
 
@@ -2032,12 +2038,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;
 
@@ -2059,14 +2074,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 -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to