[v2,2/2] vhost: fix possible FD leaks on truncation

Message ID 20230127165540.37863-4-maxime.coquelin@redhat.com (mailing list archive)
State Not Applicable, archived
Delegated to: Maxime Coquelin
Headers
Series None |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS

Commit Message

Maxime Coquelin Jan. 27, 2023, 4:55 p.m. UTC
  This patch fixes possible FDs leaks when truncation happens
on either the message buffer or its control data. Indeed,
by returning early, it did not let a chance to retrieve the
FDs passed as ancillary data, and so caused a potential FDs
leak.

This patch fixes this by extracting the FDs from the
ancillary data as long as recvmsg() call succeeded. It also
improves the logs to differentiate between MSG_TRUNC and
MSG_CTRUNC.

Fixes: bf472259dde6 ("vhost: fix possible denial of service by leaking FDs")
Cc: stable@dpdk.org

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 lib/vhost/socket.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
  

Comments

Chenbo Xia Feb. 7, 2023, 5:38 a.m. UTC | #1
> -----Original Message-----
> From: Maxime Coquelin <maxime.coquelin@redhat.com>
> Sent: Saturday, January 28, 2023 12:56 AM
> To: dev@dpdk.org; david.marchand@redhat.com; Xia, Chenbo
> <chenbo.xia@intel.com>
> Cc: Coquelin, Maxime <maxime.coquelin@redhat.com>; stable@dpdk.org
> Subject: [PATCH v2 2/2] vhost: fix possible FD leaks on truncation
> 
> This patch fixes possible FDs leaks when truncation happens
> on either the message buffer or its control data. Indeed,
> by returning early, it did not let a chance to retrieve the
> FDs passed as ancillary data, and so caused a potential FDs
> leak.
> 
> This patch fixes this by extracting the FDs from the
> ancillary data as long as recvmsg() call succeeded. It also
> improves the logs to differentiate between MSG_TRUNC and
> MSG_CTRUNC.
> 
> Fixes: bf472259dde6 ("vhost: fix possible denial of service by leaking
> FDs")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>  lib/vhost/socket.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/vhost/socket.c b/lib/vhost/socket.c
> index 863a6f6d52..669c322e12 100644
> --- a/lib/vhost/socket.c
> +++ b/lib/vhost/socket.c
> @@ -129,10 +129,12 @@ read_fd_message(char *ifname, int sockfd, char *buf,
> int buflen, int *fds, int m
>  		return ret;
>  	}
> 
> -	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
> +	if (msgh.msg_flags & MSG_TRUNC)
>  		VHOST_LOG_CONFIG(ifname, ERR, "truncated msg (fd %d)\n",
> sockfd);
> -		return -1;
> -	}
> +
> +	/* MSG_CTRUNC may be caused by LSM misconfiguration */
> +	if (msgh.msg_flags & MSG_CTRUNC)
> +		VHOST_LOG_CONFIG(ifname, ERR, "truncated control data
> (fd %d)\n", sockfd);
> 
>  	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
>  		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
> --
> 2.39.1

Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
  

Patch

diff --git a/lib/vhost/socket.c b/lib/vhost/socket.c
index 863a6f6d52..669c322e12 100644
--- a/lib/vhost/socket.c
+++ b/lib/vhost/socket.c
@@ -129,10 +129,12 @@  read_fd_message(char *ifname, int sockfd, char *buf, int buflen, int *fds, int m
 		return ret;
 	}
 
-	if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) {
+	if (msgh.msg_flags & MSG_TRUNC)
 		VHOST_LOG_CONFIG(ifname, ERR, "truncated msg (fd %d)\n", sockfd);
-		return -1;
-	}
+
+	/* MSG_CTRUNC may be caused by LSM misconfiguration */
+	if (msgh.msg_flags & MSG_CTRUNC)
+		VHOST_LOG_CONFIG(ifname, ERR, "truncated control data (fd %d)\n", sockfd);
 
 	for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
 		cmsg = CMSG_NXTHDR(&msgh, cmsg)) {