netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Bug in ulogd2 when destroying a stack that failed to start (with fix attached)
@ 2023-12-14 17:10 Gérald Colangelo
  2025-03-12  8:49 ` Florian Westphal
  0 siblings, 1 reply; 2+ messages in thread
From: Gérald Colangelo @ 2023-12-14 17:10 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

Hello everyone,

While working on a ulogd2 deployment, i built a stack that consists in:
  - A "home-made" INPUT plugin that launchs a pcap capture upon
start() and passes a fd to ulogd2.
  - Some regular ulogd2 filters
  - JSON output plugin that writes to a Unix socket.

Everything works fine, except if unix socket is not available.
In that case, when the stack is started at launch, the JSON output
start() function returns -1 and  ulogd.c consider that it fails
starting the stack and then destroy it.
Unfortunately, ulogd.c only free() the stack context without calling
stop() functions on plugins that were correctly start()-ed.
In my case, it results in my pcap input triggering the stack even if
it was destroyed.
This ends with a segmentation fault for the ulogd process.

I think we should consider calling stop() functions before destroying the stack.
A patch implementing this is attached (for version 2.0.7, but this
part of the code didn't changed on latest).

Best regards,

-- 
Gerald Colangelo

[-- Attachment #2: ulogd2_stop_plugins_before_destroying_stack.patch --]
[-- Type: text/x-patch, Size: 972 bytes --]

--- ulogd2-2.0.7/src/ulogd.c	2018-04-27 01:10:42.316872034 +0200
+++ ulogd2-2.0.7-patched/src/ulogd.c	2023-12-14 18:04:06.994661722 +0100
@@ -931,7 +931,7 @@
 static int create_stack_start_instances(struct ulogd_pluginstance_stack *stack)
 {
 	int ret;
-	struct ulogd_pluginstance *pi;
+	struct ulogd_pluginstance *pi, *stop;
 
 	/* start from input to output plugin */
 	llist_for_each_entry(pi, &stack->list, list) {
@@ -945,11 +945,27 @@
 				ulogd_log(ULOGD_ERROR, 
 					  "error starting `%s'\n",
 					  pi->id);
-				return ret;
+				goto cleanup_fail;
 			}
 		}
 	}
 	return 0;
+cleanup_fail:
+	stop = pi;
+	llist_for_each_entry(pi, &stack->list, list) {
+		if (pi == stop)
+			/* the one that failed, stops the cleanup here */
+			break;
+		if (!pi->plugin->stop) 
+			continue;
+		ret = pi->plugin->stop(pi);
+		if (ret < 0) {
+			ulogd_log(ULOGD_ERROR,
+			"error stopping `%s'\n",
+			pi->id);
+		}
+	}
+	return -1;
 }
 
 /* create a new stack of plugins */

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

* Re: Bug in ulogd2 when destroying a stack that failed to start (with fix attached)
  2023-12-14 17:10 Bug in ulogd2 when destroying a stack that failed to start (with fix attached) Gérald Colangelo
@ 2025-03-12  8:49 ` Florian Westphal
  0 siblings, 0 replies; 2+ messages in thread
From: Florian Westphal @ 2025-03-12  8:49 UTC (permalink / raw)
  To: Gérald Colangelo; +Cc: netfilter-devel

Gérald Colangelo <gerald.colangelo@weblib.eu> wrote:
> +cleanup_fail:
> +	stop = pi;
> +	llist_for_each_entry(pi, &stack->list, list) {
> +		if (pi == stop)
> +			/* the one that failed, stops the cleanup here */
> +			break;
> +		if (!pi->plugin->stop) 
> +			continue;
> +		ret = pi->plugin->stop(pi);
> +		if (ret < 0) {
> +			ulogd_log(ULOGD_ERROR,
> +			"error stopping `%s'\n",
> +			pi->id);
> +		}
> +	}
> +	return -1;

Looks good, but I think you also need to add a second loop to free()
the stack elements, as done in stop_pluginstances().


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

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

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-14 17:10 Bug in ulogd2 when destroying a stack that failed to start (with fix attached) Gérald Colangelo
2025-03-12  8:49 ` Florian Westphal

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 NNTP newsgroup(s).