public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
* [PATCH] flow: fix podman issue #26073
@ 2025-05-07 12:36 Laurent Vivier
  2025-05-12  8:53 ` Laurent Vivier
  0 siblings, 1 reply; 2+ messages in thread
From: Laurent Vivier @ 2025-05-07 12:36 UTC (permalink / raw)
  To: passt-dev; +Cc: Laurent Vivier

While running pasta, we trigger the following assert:

  ASSERTION FAILED in udp_at_sidx (udp_flow.c:35): flow->f.type == FLOW_UDP

in udp_at_sidx() in the following path:

 902 void udp_sock_handler(const struct ctx *c, union epoll_ref ref,
 903                       uint32_t events, const struct timespec *now)
 904 {
 905         struct udp_flow *uflow = udp_at_sidx(ref.flowside);

The invalid sidx is comming from the epoll_ref provided by epoll_wait().

This assert follows the following error:

  Couldn't connect flow socket: Permission denied

It appears that an error happens in udp_flow_sock() and the recently
created fd is not removed from the epoll_ctl() pool:

 71 static int udp_flow_sock(const struct ctx *c,
 72                          struct udp_flow *uflow, unsigned sidei)
 73 {
...
 82         s = flowside_sock_l4(c, EPOLL_TYPE_UDP, pif, side, fref.data);
 83         if (s < 0) {
 84                 flow_dbg_perror(uflow, "Couldn't open flow specific socket");
 85                 return s;
 86         }
 87
 88         if (flowside_connect(c, s, pif, side) < 0) {
 89                 int rc = -errno;
 90                 flow_dbg_perror(uflow, "Couldn't connect flow socket");
 91                 return rc;
 92         }
...

flowside_sock_l4() calls sock_l4_sa() that adds 's' to the epoll_ctl()
pool.

So to cleanly manage the error of flowside_connect() we need to remove
's' from the epoll_ctl() pool using epoll_del().

Link: https://github.com/containers/podman/issues/26073
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 udp_flow.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/udp_flow.c b/udp_flow.c
index fea1cf3c7a41..b3a13b7993d5 100644
--- a/udp_flow.c
+++ b/udp_flow.c
@@ -87,6 +87,10 @@ static int udp_flow_sock(const struct ctx *c,
 
 	if (flowside_connect(c, s, pif, side) < 0) {
 		int rc = -errno;
+
+		if (pif == PIF_HOST)
+			epoll_del(c, s);
+
 		flow_dbg_perror(uflow, "Couldn't connect flow socket");
 		return rc;
 	}
-- 
@@ -87,6 +87,10 @@ static int udp_flow_sock(const struct ctx *c,
 
 	if (flowside_connect(c, s, pif, side) < 0) {
 		int rc = -errno;
+
+		if (pif == PIF_HOST)
+			epoll_del(c, s);
+
 		flow_dbg_perror(uflow, "Couldn't connect flow socket");
 		return rc;
 	}
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] flow: fix podman issue #26073
  2025-05-07 12:36 [PATCH] flow: fix podman issue #26073 Laurent Vivier
@ 2025-05-12  8:53 ` Laurent Vivier
  0 siblings, 0 replies; 2+ messages in thread
From: Laurent Vivier @ 2025-05-12  8:53 UTC (permalink / raw)
  To: passt-dev

On 07/05/2025 14:36, Laurent Vivier wrote:
> While running pasta, we trigger the following assert:
> 
>    ASSERTION FAILED in udp_at_sidx (udp_flow.c:35): flow->f.type == FLOW_UDP
> 
> in udp_at_sidx() in the following path:
> 
>   902 void udp_sock_handler(const struct ctx *c, union epoll_ref ref,
>   903                       uint32_t events, const struct timespec *now)
>   904 {
>   905         struct udp_flow *uflow = udp_at_sidx(ref.flowside);
> 
> The invalid sidx is comming from the epoll_ref provided by epoll_wait().
> 
> This assert follows the following error:
> 
>    Couldn't connect flow socket: Permission denied
> 
> It appears that an error happens in udp_flow_sock() and the recently
> created fd is not removed from the epoll_ctl() pool:
> 
>   71 static int udp_flow_sock(const struct ctx *c,
>   72                          struct udp_flow *uflow, unsigned sidei)
>   73 {
> ...
>   82         s = flowside_sock_l4(c, EPOLL_TYPE_UDP, pif, side, fref.data);
>   83         if (s < 0) {
>   84                 flow_dbg_perror(uflow, "Couldn't open flow specific socket");
>   85                 return s;
>   86         }
>   87
>   88         if (flowside_connect(c, s, pif, side) < 0) {
>   89                 int rc = -errno;
>   90                 flow_dbg_perror(uflow, "Couldn't connect flow socket");
>   91                 return rc;
>   92         }
> ...
> 
> flowside_sock_l4() calls sock_l4_sa() that adds 's' to the epoll_ctl()
> pool.
> 
> So to cleanly manage the error of flowside_connect() we need to remove
> 's' from the epoll_ctl() pool using epoll_del().
> 
> Link: https://github.com/containers/podman/issues/26073
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>   udp_flow.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/udp_flow.c b/udp_flow.c
> index fea1cf3c7a41..b3a13b7993d5 100644
> --- a/udp_flow.c
> +++ b/udp_flow.c
> @@ -87,6 +87,10 @@ static int udp_flow_sock(const struct ctx *c,
>   
>   	if (flowside_connect(c, s, pif, side) < 0) {
>   		int rc = -errno;
> +
> +		if (pif == PIF_HOST)
> +			epoll_del(c, s);
> +
>   		flow_dbg_perror(uflow, "Couldn't connect flow socket");
>   		return rc;
>   	}

After re-reading the code, I think we need also a "close(s)" and not the "(pif == 
PIF_HOST)" as flowside_sock_l4() also calls flowside_sock_splice() which call sock_l4_sa() 
too (but in a namespace).

Laurent


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-05-12  8:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-07 12:36 [PATCH] flow: fix podman issue #26073 Laurent Vivier
2025-05-12  8:53 ` Laurent Vivier

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).