libiio icon indicating copy to clipboard operation
libiio copied to clipboard

recv() should not pass NULL buffer

Open egranata opened this issue 6 years ago • 5 comments

Calling recv() with a NULL value of the buffer argument is not correct, and - while it happens to work for TCP sockets - raises a EFAULT error for other kinds of sockets.

egranata avatar Jun 10 '19 21:06 egranata

Is it enough to pass a uninitialized pointer to something to avoid the EFAULT?

pcercuei avatar Jun 11 '19 21:06 pcercuei

Are you more concerned about iiod or in network.c?

iiod/ops.c:256:				ret = recv(pdata->fd_in, dest, len, MSG_NOSIGNAL);
iiod/ops.c:1315:			ret = recv(pdata->fd_in, buf, len,
iiod/ops.c:1331:			ret = recv(pdata->fd_in, NULL, to_trunc,
network.c:480:		ret = recv(io_ctx->fd, data, (int) len, flags);

From what I can tell - calling recv with a null buffer is undefined behavior and anything could happen, even on TCP.

rgetz avatar Jul 19 '19 22:07 rgetz

Are you more concerned about iiod or in network.c?

iiod/ops.c:256:				ret = recv(pdata->fd_in, dest, len, MSG_NOSIGNAL);
iiod/ops.c:1315:			ret = recv(pdata->fd_in, buf, len,
iiod/ops.c:1331:			ret = recv(pdata->fd_in, NULL, to_trunc,
network.c:480:		ret = recv(io_ctx->fd, data, (int) len, flags);

From what I can tell - calling recv with a null buffer is undefined behavior and anything could happen, even on TCP.

Both are problematic. And - to answer @pcercuei 's comment - no, it looks like the pointer has to be valid and initialized.

egranata avatar Jul 30 '19 23:07 egranata

Passing a NULL buffer is correct as long as no data is written - which is the case since we use MSG_TRUNC. It only works for TCP, but the upstream code only handles TCP.

If the code is modified to handle other types of sockets, I think the way forward would be to have a fallback slow path without MSG_PEEK/MSG_TRUNC that's taken if the regular one fails.

pcercuei avatar Jul 31 '19 16:07 pcercuei

Passing a NULL buffer is correct as long as no data is written - which is the case since we use MSG_TRUNC. It only works for TCP, but the upstream code only handles TCP.

If the code is modified to handle other types of sockets, I think the way forward would be to have a fallback slow path without MSG_PEEK/MSG_TRUNC that's taken if the regular one fails.

Adding @gwendalcr since he is also interested in this

egranata avatar Jul 31 '19 18:07 egranata