Skip to content

Commit

Permalink
Don't run plugins on src.rpm unpacking (RhBug:2316785)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dmnks committed Dec 9, 2024
1 parent 26bc703 commit 4723d40
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 15 deletions.
10 changes: 9 additions & 1 deletion lib/rpminstall.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
26 changes: 14 additions & 12 deletions lib/rpmplugins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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;
Expand Down
14 changes: 12 additions & 2 deletions tests/rpmdevel.at
Original file line number Diff line number Diff line change
Expand Up @@ -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],
[],
Expand All @@ -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

0 comments on commit 4723d40

Please sign in to comment.