[PATCH 4/4] samples/cgroup: don't let dirname() clobber the monitored path
From: Song Hu
Date: Mon Nov 02 2026 - 07:36:15 EST
dirname(3) is allowed to modify its argument in place, and the libc
implementations do: after building event_control_path, argv[1] has
been truncated to the parent directory. Every subsequent "crossed"
event line therefore reports the cgroup directory instead of the
monitored file, and the two-listener setup taught by
Documentation/admin-guide/cgroup-v1/memory.rst (usage_in_bytes plus
memsw.usage_in_bytes) produces indistinguishable output lines.
Work on a strdup() copy so event reports keep naming the monitored
file.
Fixes: 60433a9d038d ("samples: introduce new samples subdir for cgroup")
Signed-off-by: Song Hu <husong@xxxxxxxxxx>
---
samples/cgroup/cgroup_event_listener.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/samples/cgroup/cgroup_event_listener.c b/samples/cgroup/cgroup_event_listener.c
index 3d70dc831a76..308cacec80a8 100644
--- a/samples/cgroup/cgroup_event_listener.c
+++ b/samples/cgroup/cgroup_event_listener.c
@@ -26,17 +26,27 @@ int main(int argc, char **argv)
int event_control = -1;
char event_control_path[PATH_MAX];
char line[LINE_MAX];
+ char *path;
int ret;
if (argc != 3)
errx(1, "%s", USAGE_STR);
- cfd = open(argv[1], O_RDONLY);
+ /*
+ * dirname(3) may modify its argument in place; work on a copy so
+ * argv[1] still refers to the monitored file when events are
+ * reported.
+ */
+ path = strdup(argv[1]);
+ if (!path)
+ err(1, "Cannot duplicate %s", argv[1]);
+
+ cfd = open(path, O_RDONLY);
if (cfd == -1)
- err(1, "Cannot open %s", argv[1]);
+ err(1, "Cannot open %s", path);
ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control",
- dirname(argv[1]));
+ dirname(path));
if (ret >= PATH_MAX)
errx(1, "Path to cgroup.event_control is too long");
@@ -76,7 +86,7 @@ int main(int argc, char **argv)
if (ret == -1)
err(1, "cgroup.event_control is not accessible any more");
- printf("%s %s: crossed\n", argv[1], argv[2]);
+ printf("%s %s: crossed\n", path, argv[2]);
}
return 0;
--
2.53.0