Skip to content

Commit 9f2189a

Browse files
committed
lib: nrf_modem: Clear the address structure on recvfrom
Always zero the sender address structure before passing it to `nrf_recvfrom()` and only use it when the function is successful. This fixes a bug where the offloading code would peek into a uninitialized structure and perform an out of bounds memory copy, which could have happened when the application was compiled without IPv6 support and: - the socket protocol did not provide a sender address (DTLS) or - the recvfrom() call failed, leaving the structure untouched Signed-off-by: Robert Lubos <[email protected]> Signed-off-by: Emanuele Di Santo <[email protected]> Signed-off-by: Divya Pillai <[email protected]>
1 parent eb9dcef commit 9f2189a

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

doc/nrf/releases/release-notes-changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ Libraries for networking
211211
Modem libraries
212212
---------------
213213

214+
* :ref:`nrf_modem_lib_readme` library:
215+
216+
* Fixed a bug in the socket offloading component, where the :c:func:`recvfrom` wrapper could do an out-of-bounds copy of the sender's address, when the application is compiled without IPv6 support. In some cases, the out of bounds copy could indefinitely block the :c:func:`send` and other socket API calls.
217+
214218
* :ref:`at_monitor_readme` library:
215219

216220
* Introduced AT_MONITOR_ISR macro to monitor AT notifications in an interrupt service routine.

lib/nrf_modem_lib/nrf91_sockets.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,16 @@ static ssize_t nrf91_socket_offload_recvfrom(void *obj, void *buf, size_t len,
850850
NULL, NULL);
851851
} else {
852852
/* Allocate space for maximum of IPv4 and IPv6 family type. */
853-
struct nrf_sockaddr_in6 cliaddr_storage;
853+
struct nrf_sockaddr_in6 cliaddr_storage = { 0 };
854854
nrf_socklen_t sock_len = sizeof(struct nrf_sockaddr_in6);
855855
struct nrf_sockaddr *cliaddr = (struct nrf_sockaddr *)&cliaddr_storage;
856856

857857
retval = nrf_recvfrom(ctx->nrf_fd, buf, len, z_to_nrf_flags(flags),
858858
cliaddr, &sock_len);
859+
if (retval < 0) {
860+
goto exit;
861+
}
862+
859863
if (cliaddr->sa_family == NRF_AF_INET) {
860864
nrf_to_z_ipv4(from, (struct nrf_sockaddr_in *)cliaddr);
861865
*fromlen = sizeof(struct sockaddr_in);
@@ -866,6 +870,7 @@ static ssize_t nrf91_socket_offload_recvfrom(void *obj, void *buf, size_t len,
866870
}
867871
}
868872

873+
exit:
869874
k_mutex_lock(ctx->lock, K_FOREVER);
870875

871876
return retval;

0 commit comments

Comments
 (0)