drivers: modem: Fix reference to stack in modem_context_sprint_ip_addr

Changes the modem_context_sprint_ip addr to write into a provided
buffer. This approach fixes a referencing to a non existing stack
variable, without using a lot of stack space.
Tested using the by building all used modems and tested on HW using
IPv4.

Fixes: #38459

Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
This commit is contained in:
Sjors Hettinga 2021-09-14 09:57:54 +02:00 committed by Christopher Friedt
commit 7f9b4d807c
4 changed files with 58 additions and 13 deletions

View file

@ -20,23 +20,40 @@ LOG_MODULE_REGISTER(modem_context, CONFIG_MODEM_LOG_LEVEL);
static struct modem_context *contexts[CONFIG_MODEM_CONTEXT_MAX_NUM]; static struct modem_context *contexts[CONFIG_MODEM_CONTEXT_MAX_NUM];
char *modem_context_sprint_ip_addr(const struct sockaddr *addr) int modem_context_sprint_ip_addr(const struct sockaddr *addr, char *buf, size_t buf_size)
{ {
static char buf[NET_IPV6_ADDR_LEN]; static const char unknown_str[] = "unk";
if (addr->sa_family == AF_INET6) { if (addr->sa_family == AF_INET6) {
return net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr, if (buf_size < NET_IPV6_ADDR_LEN) {
buf, sizeof(buf)); return -ENOMEM;
}
if (net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr,
buf, buf_size) == NULL) {
return -ENOMEM;
}
return 0;
} }
if (addr->sa_family == AF_INET) { if (addr->sa_family == AF_INET) {
return net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr, if (buf_size < NET_IPV4_ADDR_LEN) {
buf, sizeof(buf)); return -ENOMEM;
}
if (net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr,
buf, buf_size) == NULL) {
return -ENOMEM;
}
return 0;
} }
LOG_ERR("Unknown IP address family:%d", addr->sa_family); LOG_ERR("Unknown IP address family:%d", addr->sa_family);
strcpy(buf, "unk");
return buf; if (buf_size < sizeof(unknown_str)) {
return -ENOMEM;
}
strcpy(buf, unknown_str);
return 0;
} }
int modem_context_get_addr_port(const struct sockaddr *addr, uint16_t *port) int modem_context_get_addr_port(const struct sockaddr *addr, uint16_t *port)

View file

@ -91,10 +91,12 @@ struct modem_context {
* @brief IP address to string * @brief IP address to string
* *
* @param addr: sockaddr to be converted * @param addr: sockaddr to be converted
* @param buf: Buffer to store IP in string form
* @param buf_size: buffer size
* *
* @retval Buffer with IP in string form * @retval 0 if ok, < 0 if error.
*/ */
char *modem_context_sprint_ip_addr(const struct sockaddr *addr); int modem_context_sprint_ip_addr(const struct sockaddr *addr, char *buf, size_t buf_size);
/** /**
* @brief Get port from IP address * @brief Get port from IP address

View file

@ -705,6 +705,7 @@ static int offload_connect(void *obj, const struct sockaddr *addr,
struct modem_cmd cmd[] = { MODEM_CMD("+QIOPEN: ", on_cmd_atcmdinfo_sockopen, 2U, ",") }; struct modem_cmd cmd[] = { MODEM_CMD("+QIOPEN: ", on_cmd_atcmdinfo_sockopen, 2U, ",") };
char buf[sizeof("AT+QIOPEN=#,##,###,####.####.####.####,######")] = {0}; char buf[sizeof("AT+QIOPEN=#,##,###,####.####.####.####,######")] = {0};
int ret; int ret;
char ip_str[NET_IPV6_ADDR_LEN];
if (sock->id < mdata.socket_config.base_socket_num - 1) { if (sock->id < mdata.socket_config.base_socket_num - 1) {
LOG_ERR("Invalid socket_id(%d) from fd:%d", LOG_ERR("Invalid socket_id(%d) from fd:%d",
@ -735,9 +736,18 @@ static int offload_connect(void *obj, const struct sockaddr *addr,
k_sem_reset(&mdata.sem_sock_conn); k_sem_reset(&mdata.sem_sock_conn);
ret = modem_context_sprint_ip_addr(addr, ip_str, sizeof(ip_str));
if (ret != 0) {
LOG_ERR("Error formatting IP string %d", ret);
LOG_ERR("Closing the socket!!!");
socket_close(sock);
errno = -ret;
return -1;
}
/* Formulate the complete string. */ /* Formulate the complete string. */
snprintk(buf, sizeof(buf), "AT+QIOPEN=%d,%d,\"%s\",\"%s\",%d,0,0", 1, sock->sock_fd, protocol, snprintk(buf, sizeof(buf), "AT+QIOPEN=%d,%d,\"%s\",\"%s\",%d,0,0", 1, sock->sock_fd, protocol,
modem_context_sprint_ip_addr(addr), dst_port); ip_str, dst_port);
/* Send out the command. */ /* Send out the command. */
ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,

View file

@ -358,10 +358,18 @@ static ssize_t send_socket_data(void *obj,
mdata.sock_written = 0; mdata.sock_written = 0;
if (sock->ip_proto == IPPROTO_UDP) { if (sock->ip_proto == IPPROTO_UDP) {
char ip_str[NET_IPV6_ADDR_LEN];
ret = modem_context_sprint_ip_addr(dst_addr, ip_str, sizeof(ip_str));
if (ret != 0) {
LOG_ERR("Error formatting IP string %d", ret);
goto exit;
}
ret = modem_context_get_addr_port(dst_addr, &dst_port); ret = modem_context_get_addr_port(dst_addr, &dst_port);
snprintk(send_buf, sizeof(send_buf), snprintk(send_buf, sizeof(send_buf),
"AT+USOST=%d,\"%s\",%u,%zu", sock->id, "AT+USOST=%d,\"%s\",%u,%zu", sock->id,
modem_context_sprint_ip_addr(dst_addr), ip_str,
dst_port, buf_len); dst_port, buf_len);
} else { } else {
snprintk(send_buf, sizeof(send_buf), "AT+USOWR=%d,%zu", snprintk(send_buf, sizeof(send_buf), "AT+USOWR=%d,%zu",
@ -1538,6 +1546,7 @@ static int offload_connect(void *obj, const struct sockaddr *addr,
int ret; int ret;
char buf[sizeof("AT+USOCO=#,!###.###.###.###!,#####,#\r")]; char buf[sizeof("AT+USOCO=#,!###.###.###.###!,#####,#\r")];
uint16_t dst_port = 0U; uint16_t dst_port = 0U;
char ip_str[NET_IPV6_ADDR_LEN];
if (!addr) { if (!addr) {
errno = EINVAL; errno = EINVAL;
@ -1574,8 +1583,15 @@ static int offload_connect(void *obj, const struct sockaddr *addr,
return 0; return 0;
} }
ret = modem_context_sprint_ip_addr(addr, ip_str, sizeof(ip_str));
if (ret != 0) {
errno = -ret;
LOG_ERR("Error formatting IP string %d", ret);
return -1;
}
snprintk(buf, sizeof(buf), "AT+USOCO=%d,\"%s\",%d", sock->id, snprintk(buf, sizeof(buf), "AT+USOCO=%d,\"%s\",%d", sock->id,
modem_context_sprint_ip_addr(addr), dst_port); ip_str, dst_port);
ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
NULL, 0U, buf, NULL, 0U, buf,
&mdata.sem_response, MDM_CMD_CONN_TIMEOUT); &mdata.sem_response, MDM_CMD_CONN_TIMEOUT);