Skip to content

Commit 5daf19d

Browse files
[3.12] gh-104432: Use memcpy() to avoid misaligned loads (GH-104433) (#107355)
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 f01e4ce) Co-authored-by: Christopher Chavez <[email protected]>
1 parent c580527 commit 5daf19d

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix potential unaligned memory access on C APIs involving returned sequences
2+
of `char *` pointers within the :mod:`grp` and :mod:`socket` modules. These
3+
were revealed using a ``-fsaniziter=alignment`` build on ARM macOS. Patch by
4+
Christopher Chavez.

Modules/grpmodule.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,14 @@ mkgrent(PyObject *module, struct group *p)
6565
Py_DECREF(v);
6666
return NULL;
6767
}
68-
for (member = p->gr_mem; *member != NULL; member++) {
69-
PyObject *x = PyUnicode_DecodeFSDefault(*member);
68+
for (member = p->gr_mem; ; member++) {
69+
char *group_member;
70+
// member can be misaligned
71+
memcpy(&group_member, member, sizeof(group_member));
72+
if (group_member == NULL) {
73+
break;
74+
}
75+
PyObject *x = PyUnicode_DecodeFSDefault(group_member);
7076
if (x == NULL || PyList_Append(w, x) != 0) {
7177
Py_XDECREF(x);
7278
Py_DECREF(w);

Modules/socketmodule.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5783,9 +5783,15 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
57835783

57845784
/* SF #1511317: h_aliases can be NULL */
57855785
if (h->h_aliases) {
5786-
for (pch = h->h_aliases; *pch != NULL; pch++) {
5786+
for (pch = h->h_aliases; ; pch++) {
57875787
int status;
5788-
tmp = PyUnicode_FromString(*pch);
5788+
char *host_alias;
5789+
// pch can be misaligned
5790+
memcpy(&host_alias, pch, sizeof(host_alias));
5791+
if (host_alias == NULL) {
5792+
break;
5793+
}
5794+
tmp = PyUnicode_FromString(host_alias);
57895795
if (tmp == NULL)
57905796
goto err;
57915797

@@ -5797,8 +5803,14 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
57975803
}
57985804
}
57995805

5800-
for (pch = h->h_addr_list; *pch != NULL; pch++) {
5806+
for (pch = h->h_addr_list; ; pch++) {
58015807
int status;
5808+
char *host_address;
5809+
// pch can be misaligned
5810+
memcpy(&host_address, pch, sizeof(host_address));
5811+
if (host_address == NULL) {
5812+
break;
5813+
}
58025814

58035815
switch (af) {
58045816

@@ -5810,7 +5822,7 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
58105822
#ifdef HAVE_SOCKADDR_SA_LEN
58115823
sin.sin_len = sizeof(sin);
58125824
#endif
5813-
memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr));
5825+
memcpy(&sin.sin_addr, host_address, sizeof(sin.sin_addr));
58145826
tmp = make_ipv4_addr(&sin);
58155827

58165828
if (pch == h->h_addr_list && alen >= sizeof(sin))
@@ -5827,7 +5839,7 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
58275839
#ifdef HAVE_SOCKADDR_SA_LEN
58285840
sin6.sin6_len = sizeof(sin6);
58295841
#endif
5830-
memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr));
5842+
memcpy(&sin6.sin6_addr, host_address, sizeof(sin6.sin6_addr));
58315843
tmp = make_ipv6_addr(&sin6);
58325844

58335845
if (pch == h->h_addr_list && alen >= sizeof(sin6))

0 commit comments

Comments
 (0)