From a0fefaea96f1815374938c880a9a5d87ff048bd8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 1 Apr 2025 16:40:00 +0200 Subject: [PATCH] [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 (cherry picked from commit 8cd29c2b533e5a1a262238695d05f2a7c44d6455) --- ...-03-28-11-26-31.gh-issue-131668.tcS4xS.rst | 1 + Modules/socketmodule.c | 60 +++++++++++++++---- 2 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-03-28-11-26-31.gh-issue-131668.tcS4xS.rst 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; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy