From a4d94b6e7a2559a09be11854084dca6b5aa6a71f Mon Sep 17 00:00:00 2001 From: Michal Domonkos Date: Thu, 21 Nov 2024 14:22:30 +0100 Subject: [PATCH] Don't run plugins on src.rpm unpacking (RhBug:2316785) Source packages aren't really "installed", just unpacked, and plugins operate on real transactions by design, so disable all hooks for those. This fixes, in particular, src.rpm installations done by a regular user (a fairly common case) on systems equipped with a plugin that needs root privileges (e.g. the ima plugin), which would otherwise cause a spurious warning or even failure (see RhBug:2316785). Do this by setting RPMTRANS_FLAG_NOPLUGINS for the duration of source unpacking. This ensures that ts->plugins, if not populated yet, will remain empty during rpmInstallSource() (rpmtsSetupTransactionPlugins() bails out if the flag is present). However, if any binary packages are among the rpmInstall() arguments, ts->plugins will have been populated by the time rpmInstallSource() is called, so we need to check for the flag in the hooks themselves, too, and prevent them from running if it's present. Reuse the plugin development test, we don't have anything better at the moment and it does the job well. --- lib/rpminstall.cc | 10 +++++++++- lib/rpmplugins.cc | 26 ++++++++++++++------------ tests/rpmdevel.at | 14 ++++++++++++-- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/rpminstall.cc b/lib/rpminstall.cc index c656380dc2..5af28511c7 100644 --- a/lib/rpminstall.cc +++ b/lib/rpminstall.cc @@ -420,6 +420,7 @@ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) struct rpmEIU * eiu = (struct rpmEIU *)xcalloc(1, sizeof(*eiu)); rpmRelocation * relocations; char * fileURL = NULL; + rpmtransFlags tsflags, otsflags; rpmVSFlags vsflags, ovsflags; rpmVSFlags ovfyflags; int rc; @@ -667,16 +668,23 @@ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) rpmcliProgressState = 0; rpmcliProgressTotal = 0; rpmcliProgressCurrent = 0; + + tsflags = rpmtsFlags(ts); + otsflags = rpmtsSetFlags(ts, (tsflags | RPMTRANS_FLAG_NOPLUGINS)); + rpmtsEmpty(ts); + for (i = 0; i < eiu->numSRPMS; i++) { if (eiu->sourceURL[i] != NULL) { rc = RPMRC_OK; - if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) + if (!(tsflags & RPMTRANS_FLAG_TEST)) rc = rpmInstallSource(ts, eiu->sourceURL[i], NULL, NULL); if (rc != 0) eiu->numFailed++; } } + + rpmtsSetFlags(ts, otsflags); } exit: diff --git a/lib/rpmplugins.cc b/lib/rpmplugins.cc index bd5e83d992..b75e3e877a 100644 --- a/lib/rpmplugins.cc +++ b/lib/rpmplugins.cc @@ -209,9 +209,11 @@ rpmPlugins rpmpluginsFree(rpmPlugins plugins) } /* Common define for all rpmpluginsCall* hook functions */ -#define RPMPLUGINS_SET_HOOK_FUNC(hook) \ +#define RPMPLUGINS_SET_HOOK_FUNC(ts, hook) \ rpmPluginHooks hooks = (plugin != NULL) ? plugin->hooks : NULL; \ hookFunc = (hooks != NULL) ? hooks->hook : NULL; \ + if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOPLUGINS) \ + hookFunc = NULL; \ if (hookFunc) { \ rpmlog(RPMLOG_DEBUG, "Plugin: calling hook %s in %s plugin\n", \ STR(hook), plugin->name); \ @@ -221,7 +223,7 @@ static rpmRC rpmpluginsCallInit(rpmPlugin plugin, rpmts ts) { rpmRC rc = RPMRC_OK; plugin_init_func hookFunc; - RPMPLUGINS_SET_HOOK_FUNC(init); + RPMPLUGINS_SET_HOOK_FUNC(ts, init); if (hookFunc) { rc = hookFunc(plugin, ts); if (rc != RPMRC_OK && rc != RPMRC_NOTFOUND) @@ -236,7 +238,7 @@ rpmRC rpmpluginsCallTsmPre(rpmPlugins plugins, rpmts ts) rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(tsm_pre); + RPMPLUGINS_SET_HOOK_FUNC(ts, tsm_pre); if (hookFunc && hookFunc(plugin, ts) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "Plugin %s: hook tsm_pre failed\n", plugin->name); rc = RPMRC_FAIL; @@ -252,7 +254,7 @@ rpmRC rpmpluginsCallTsmPost(rpmPlugins plugins, rpmts ts, int res) rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(tsm_post); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, tsm_post); if (hookFunc && hookFunc(plugin, ts, res) == RPMRC_FAIL) { rpmlog(RPMLOG_WARNING, "Plugin %s: hook tsm_post failed\n", plugin->name); } @@ -267,7 +269,7 @@ rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te) rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(psm_pre); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, psm_pre); if (hookFunc && hookFunc(plugin, te) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "Plugin %s: hook psm_pre failed\n", plugin->name); rc = RPMRC_FAIL; @@ -283,7 +285,7 @@ rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te, int res) rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(psm_post); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, psm_post); if (hookFunc && hookFunc(plugin, te, res) == RPMRC_FAIL) { rpmlog(RPMLOG_WARNING, "Plugin %s: hook psm_post failed\n", plugin->name); } @@ -298,7 +300,7 @@ rpmRC rpmpluginsCallScriptletPre(rpmPlugins plugins, const char *s_name, int typ rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(scriptlet_pre); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, scriptlet_pre); if (hookFunc && hookFunc(plugin, s_name, type) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "Plugin %s: hook scriplet_pre failed\n", plugin->name); rc = RPMRC_FAIL; @@ -314,7 +316,7 @@ rpmRC rpmpluginsCallScriptletForkPost(rpmPlugins plugins, const char *path, int rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(scriptlet_fork_post); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, scriptlet_fork_post); if (hookFunc && hookFunc(plugin, path, type) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "Plugin %s: hook scriplet_fork_post failed\n", plugin->name); rc = RPMRC_FAIL; @@ -330,7 +332,7 @@ rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int ty rpmRC rc = RPMRC_OK; for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(scriptlet_post); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, scriptlet_post); if (hookFunc && hookFunc(plugin, s_name, type, res) == RPMRC_FAIL) { rpmlog(RPMLOG_WARNING, "Plugin %s: hook scriplet_post failed\n", plugin->name); } @@ -355,7 +357,7 @@ rpmRC rpmpluginsCallFsmFilePre(rpmPlugins plugins, rpmfi fi, const char *path, char *apath = abspath(fi, path); for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(fsm_file_pre); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, fsm_file_pre); if (hookFunc && hookFunc(plugin, fi, apath, file_mode, op) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_pre failed\n", plugin->name); rc = RPMRC_FAIL; @@ -374,7 +376,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char *path, char *apath = abspath(fi, path); for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(fsm_file_post); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, fsm_file_post); if (hookFunc && hookFunc(plugin, fi, apath, file_mode, op, res) == RPMRC_FAIL) { rpmlog(RPMLOG_WARNING, "Plugin %s: hook fsm_file_post failed\n", plugin->name); } @@ -393,7 +395,7 @@ rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi, char *apath = abspath(fi, path); for (auto & plugin : plugins->plugins) { - RPMPLUGINS_SET_HOOK_FUNC(fsm_file_prepare); + RPMPLUGINS_SET_HOOK_FUNC(plugins->ts, fsm_file_prepare); if (hookFunc && hookFunc(plugin, fi, fd, apath, dest, file_mode, op) == RPMRC_FAIL) { rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_prepare failed\n", plugin->name); rc = RPMRC_FAIL; diff --git a/tests/rpmdevel.at b/tests/rpmdevel.at index 03908c88d6..91c7304bdf 100644 --- a/tests/rpmdevel.at +++ b/tests/rpmdevel.at @@ -43,12 +43,15 @@ runroot rpmbuild --quiet -bb \ /data/SPECS/simple.spec \ /data/SPECS/fakeshell.spec +runroot rpmbuild --quiet -bs \ + /data/SPECS/simple.spec + runroot rpm -U /build/RPMS/noarch/fakeshell-1.0-1.noarch.rpm cmake /data/debugplugin && make && make install DESTDIR=${RPMTEST} RPMTEST_CHECK([ -runroot rpm -U /build/RPMS/noarch/simple-1.0-1.noarch.rpm +runroot rpm -U /build/RPMS/noarch/simple-1.0-1.noarch.rpm /build/SRPMS/simple-1.0-1.src.rpm ], [0], [], @@ -70,5 +73,12 @@ debug_psm_post: simple-1.0-1.noarch:0 debug_tsm_post: 0 debug_cleanup ]) -RPMTEST_CLEANUP +RPMTEST_CHECK([ +runroot rpm -i /build/SRPMS/simple-1.0-1.src.rpm +], +[0], +[], +[]) + +RPMTEST_CLEANUP