Panu Matilainen 0ae9b3
From bb4aaaa2e8e4bdfc02f9d98ab2982074051c4eb2 Mon Sep 17 00:00:00 2001
Panu Matilainen 0ae9b3
Message-ID: <bb4aaaa2e8e4bdfc02f9d98ab2982074051c4eb2.1702642817.git.pmatilai@redhat.com>
Panu Matilainen 0ae9b3
From: Panu Matilainen <pmatilai@redhat.com>
Panu Matilainen 0ae9b3
Date: Fri, 15 Dec 2023 13:15:29 +0200
Panu Matilainen 0ae9b3
Subject: [PATCH] Fix regression in Lua scriptlet runaway child detection
Panu Matilainen 0ae9b3
Panu Matilainen 0ae9b3
Commit a8107659ef3dd4855729bf65aa4d70f784cb5a5f moved the detection
Panu Matilainen 0ae9b3
to parent using waitpid(), but this causes it to complain on any
Panu Matilainen 0ae9b3
process in the same process group. In the usual rpm context we don't
Panu Matilainen 0ae9b3
have any, but we can't very well tell API users not to have any
Panu Matilainen 0ae9b3
children. And then failed to detect a runaway Lua child in one of
Panu Matilainen 0ae9b3
our own tests. Uff.
Panu Matilainen 0ae9b3
Panu Matilainen 0ae9b3
rpmlog() in the child has the issues mentioned in the originating
Panu Matilainen 0ae9b3
commit, but that's a problem that needs to be solved elsewhere.
Panu Matilainen 0ae9b3
Revert back to issuing a warning when we actually *are* in the child
Panu Matilainen 0ae9b3
process, so there are no false positive possible. Use EXIT_FAILURE
Panu Matilainen 0ae9b3
like in the original version, dunno why I'd changed that.
Panu Matilainen 0ae9b3
Panu Matilainen 0ae9b3
Update the rpmlua test to expect the deserved warning, and use
Panu Matilainen 0ae9b3
stdio for printing its "normal" output, the catch there is that we
Panu Matilainen 0ae9b3
need to flush the io in the child.
Panu Matilainen 0ae9b3
Panu Matilainen 0ae9b3
Reported at https://bugzilla.redhat.com/show_bug.cgi?id=2254463
Panu Matilainen 0ae9b3
---
Panu Matilainen 0ae9b3
 rpmio/rpmlua.c    | 10 +++-------
Panu Matilainen 0ae9b3
 tests/rpmmacro.at |  9 ++++-----
Panu Matilainen 0ae9b3
 2 files changed, 7 insertions(+), 12 deletions(-)
Panu Matilainen 0ae9b3
Panu Matilainen 0ae9b3
diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c
Panu Matilainen 0ae9b3
index 8ef90e779..854fd469d 100644
Panu Matilainen 0ae9b3
--- a/rpmio/rpmlua.c
Panu Matilainen 0ae9b3
+++ b/rpmio/rpmlua.c
Panu Matilainen 0ae9b3
@@ -239,17 +239,13 @@ static int luaopt(int c, const char *oarg, int oint, void *data)
Panu Matilainen 0ae9b3
 static int rpm_pcall(lua_State *L, int nargs, int nresults, int errfunc)
Panu Matilainen 0ae9b3
 {
Panu Matilainen 0ae9b3
     pid_t pid = getpid();
Panu Matilainen 0ae9b3
-    int status;
Panu Matilainen 0ae9b3
 
Panu Matilainen 0ae9b3
     int rc = lua_pcall(L, nargs, nresults, errfunc);
Panu Matilainen 0ae9b3
 
Panu Matilainen 0ae9b3
     /* Terminate unhandled fork from Lua script */
Panu Matilainen 0ae9b3
-    if (pid != getpid())
Panu Matilainen 0ae9b3
-	_exit(1);
Panu Matilainen 0ae9b3
-
Panu Matilainen 0ae9b3
-    if (waitpid(0, &status, WNOHANG) == 0) {
Panu Matilainen 0ae9b3
-	rpmlog(RPMLOG_WARNING,
Panu Matilainen 0ae9b3
-		_("runaway fork() in Lua script\n"));
Panu Matilainen 0ae9b3
+    if (pid != getpid()) {
Panu Matilainen 0ae9b3
+	rpmlog(RPMLOG_WARNING, _("runaway fork() in Lua script\n"));
Panu Matilainen 0ae9b3
+	_exit(EXIT_FAILURE);
Panu Matilainen 0ae9b3
     }
Panu Matilainen 0ae9b3
 
Panu Matilainen 0ae9b3
     return rc;
Panu Matilainen 0ae9b3
diff --git a/tests/rpmmacro.at b/tests/rpmmacro.at
Panu Matilainen 0ae9b3
index 0ebcc050c..47a13ef2b 100644
Panu Matilainen 0ae9b3
--- a/tests/rpmmacro.at
Panu Matilainen 0ae9b3
+++ b/tests/rpmmacro.at
Panu Matilainen 0ae9b3
@@ -1322,13 +1322,12 @@ nil	No such file or directory	2.0
Panu Matilainen 0ae9b3
 ],
Panu Matilainen 0ae9b3
 [])
Panu Matilainen 0ae9b3
 
Panu Matilainen 0ae9b3
-# This uses io.stderr:write() because the grue from the previous test 
Panu Matilainen 0ae9b3
-# appears to have eaten stdout of the forked child, or something.
Panu Matilainen 0ae9b3
 RPMTEST_CHECK([
Panu Matilainen 0ae9b3
-runroot_other rpmlua -e 'pid = posix.fork(); if pid == 0 then a,b,c=rpm.redirect2null(-1); io.stderr:write(string.format("%s\t%s\t%s\n", a,b,c)) else posix.wait(pid) end'
Panu Matilainen 0ae9b3
+runroot_other rpmlua -e 'pid = posix.fork(); if pid == 0 then a,b,c=rpm.redirect2null(-1); print(string.format("%s\t%s\t%s", a,b,c)); io.flush() else posix.wait(pid) end'
Panu Matilainen 0ae9b3
 ],
Panu Matilainen 0ae9b3
 [0],
Panu Matilainen 0ae9b3
-[],
Panu Matilainen 0ae9b3
 [nil	Bad file descriptor	9.0
Panu Matilainen 0ae9b3
-])
Panu Matilainen 0ae9b3
+],
Panu Matilainen 0ae9b3
+[warning: runaway fork() in Lua script]
Panu Matilainen 0ae9b3
+)
Panu Matilainen 0ae9b3
 RPMTEST_CLEANUP
Panu Matilainen 0ae9b3
-- 
Panu Matilainen 0ae9b3
2.43.0
Panu Matilainen 0ae9b3