]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-104432: Use `memcpy()` to avoid misaligned loads (GH-104433) (#107356)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 28 Jul 2023 06:36:45 +0000 (23:36 -0700)
committerGitHub <noreply@github.com>
Fri, 28 Jul 2023 06:36:45 +0000 (06:36 +0000)
gh-104432: Use `memcpy()` to avoid misaligned loads (GH-104433)

Fix potential unaligned memory access on C APIs involving returned sequences
of `char *` pointers within the :mod:`grp` and :mod:`socket` modules. These
were revealed using a ``-fsaniziter=alignment`` build on ARM macOS.
(cherry picked from commit f01e4cedba1a17d321664834bb255d9d04ad16ce)

Co-authored-by: Christopher Chavez <chrischavez@gmx.us>
Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-47-29.gh-issue-104432.oGHF-z.rst [new file with mode: 0644]
Modules/grpmodule.c
Modules/socketmodule.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-47-29.gh-issue-104432.oGHF-z.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-47-29.gh-issue-104432.oGHF-z.rst
new file mode 100644 (file)
index 0000000..a9ab5cd
--- /dev/null
@@ -0,0 +1,4 @@
+Fix potential unaligned memory access on C APIs involving returned sequences
+of ``char *`` pointers within the :mod:`grp` and :mod:`socket` modules. These
+were revealed using a ``-fsaniziter=alignment`` build on ARM macOS. Patch by
+Christopher Chavez.
index f6298ca0ee84c135d03de2b0b582fac7f9387a0f..738076c9d1730ba160585853acc27c4e9fb5635a 100644 (file)
@@ -65,8 +65,14 @@ mkgrent(PyObject *module, struct group *p)
         Py_DECREF(v);
         return NULL;
     }
-    for (member = p->gr_mem; *member != NULL; member++) {
-        PyObject *x = PyUnicode_DecodeFSDefault(*member);
+    for (member = p->gr_mem; ; member++) {
+        char *group_member;
+        // member can be misaligned
+        memcpy(&group_member, member, sizeof(group_member));
+        if (group_member == NULL) {
+            break;
+        }
+        PyObject *x = PyUnicode_DecodeFSDefault(group_member);
         if (x == NULL || PyList_Append(w, x) != 0) {
             Py_XDECREF(x);
             Py_DECREF(w);
index 65d0e10fd253aaf2a996c27c65a759d781268187..e6d983afa7da85622c0f0e2032e0cb41adc337a2 100644 (file)
@@ -5657,9 +5657,15 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
 
     /* SF #1511317: h_aliases can be NULL */
     if (h->h_aliases) {
-        for (pch = h->h_aliases; *pch != NULL; pch++) {
+        for (pch = h->h_aliases; ; pch++) {
             int status;
-            tmp = PyUnicode_FromString(*pch);
+            char *host_alias;
+            // pch can be misaligned
+            memcpy(&host_alias, pch, sizeof(host_alias));
+            if (host_alias == NULL) {
+                break;
+            }
+            tmp = PyUnicode_FromString(host_alias);
             if (tmp == NULL)
                 goto err;
 
@@ -5671,8 +5677,14 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
         }
     }
 
-    for (pch = h->h_addr_list; *pch != NULL; pch++) {
+    for (pch = h->h_addr_list; ; pch++) {
         int status;
+        char *host_address;
+        // pch can be misaligned
+        memcpy(&host_address, pch, sizeof(host_address));
+        if (host_address == NULL) {
+            break;
+        }
 
         switch (af) {
 
@@ -5684,7 +5696,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
 #ifdef HAVE_SOCKADDR_SA_LEN
             sin.sin_len = sizeof(sin);
 #endif
-            memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr));
+            memcpy(&sin.sin_addr, host_address, sizeof(sin.sin_addr));
             tmp = make_ipv4_addr(&sin);
 
             if (pch == h->h_addr_list && alen >= sizeof(sin))
@@ -5701,7 +5713,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
 #ifdef HAVE_SOCKADDR_SA_LEN
             sin6.sin6_len = sizeof(sin6);
 #endif
-            memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr));
+            memcpy(&sin6.sin6_addr, host_address, sizeof(sin6.sin6_addr));
             tmp = make_ipv6_addr(&sin6);
 
             if (pch == h->h_addr_list && alen >= sizeof(sin6))