Skip to content

Commit

Permalink
net: sockets: Update msg_controllen in recvmsg properly
Browse files Browse the repository at this point in the history
According to recvmsg man page, msg_controllen should be set to the sum
of the length of all control messages in the buffer.
This is missing from the current recvmsg implementation.
This commit aims to fix this by updating msg_controllen each time control
data are added to the buffer.
This commit also fixes cases where the msg_controllen is not cleared
correctly.

Fixes zephyrproject-rtos#77303

Signed-off-by: Axel Le Bourhis <axel.lebourhis@nxp.com>
  • Loading branch information
axelnxp committed Aug 22, 2024
1 parent 67b7c99 commit 8be4ab7
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions subsys/net/lib/sockets/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -1322,12 +1322,14 @@ static int insert_pktinfo(struct msghdr *msg, int level, int type,
void *pktinfo, size_t pktinfo_len)
{
struct cmsghdr *cmsg;
size_t cmsg_space = 0;

if (msg->msg_controllen < pktinfo_len) {
return -EINVAL;
}

for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
cmsg_space += cmsg->cmsg_len;
if (cmsg->cmsg_len == 0) {
break;
}
Expand All @@ -1343,6 +1345,11 @@ static int insert_pktinfo(struct msghdr *msg, int level, int type,

memcpy(CMSG_DATA(cmsg), pktinfo, pktinfo_len);

/* msg_controllen should be set to the sum of the length of all control messages in the buffer
* so updating this field each time control data is inserted */
cmsg_space += cmsg->cmsg_len;
msg->msg_controllen = cmsg_space;

return 0;
}

Expand Down Expand Up @@ -1572,24 +1579,30 @@ static inline ssize_t zsock_recv_dgram(struct net_context *ctx,
if (msg != NULL) {
if (msg->msg_control != NULL) {
if (msg->msg_controllen > 0) {
bool clear_controllen = true;
bool clear_controllen = false;

if (IS_ENABLED(CONFIG_NET_CONTEXT_TIMESTAMPING)) {
clear_controllen = false;
if (add_timestamping(ctx, pkt, msg) < 0) {
msg->msg_flags |= ZSOCK_MSG_CTRUNC;
} else {
clear_controllen = false;
}
} else {
clear_controllen = true;
}

if (IS_ENABLED(CONFIG_NET_CONTEXT_RECV_PKTINFO) &&
net_context_is_recv_pktinfo_set(ctx)) {
clear_controllen = false;
if (add_pktinfo(ctx, pkt, msg) < 0) {
msg->msg_flags |= ZSOCK_MSG_CTRUNC;
} else {
clear_controllen = false;
}
} else {
clear_controllen = true;
}

if (clear_controllen) {
if(clear_controllen) {
msg->msg_controllen = 0;
}
}
Expand Down

0 comments on commit 8be4ab7

Please sign in to comment.