Skip to content

Commit

Permalink
Improve rpm database path in RPM probes
Browse files Browse the repository at this point in the history
The assumption that /var/lib/rpm is always a symlink to
/usr/lib/sysimage/rpm was wrong. In bootc images, it isn't
the case. As a result, all rules were evaluated as notapplicable
when scanning a bootc image or container.

We will fix it the following way: We will first try if the "new"
location /usr/lib/sysimage/rpm exists, and use it only if it exists.  If
it doesn't exist, we will fall back to the "old" location /var/lib/rpm.

Fixes: https://issues.redhat.com/browse/RHEL-55251
Fixes: #2151
  • Loading branch information
jan-cerny committed Aug 22, 2024
1 parent da1d1bd commit 04c731a
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 46 deletions.
29 changes: 29 additions & 0 deletions src/OVAL/probes/unix/linux/rpm-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,32 @@ void rpmLibsPreload()
const char* rcfiles = "";
rpmReadConfigFiles(rcfiles, NULL);
}

void set_rpm_db_path()
{
/*
* Fedora >=36 changed the default dbpath in librpm from /var/lib/rpm to /usr/lib/sysimage/rpm.
* See: https://fedoraproject.org/wiki/Changes/RelocateRPMToUsr
*
* Therefore, when running openscap on a Fedora >=36 system scanning another systems (such as RHEL, SLES, Fedora<36)
* openscap's librpm will try to read the rpm db from /usr/lib/sysimage/rpm which doesn't exist and therefore won't work.
* On many systems, /var/lib/rpm is still a symlink to /usr/lib/sysimage/rpm, so using /var/lib/rpm can work there.
* However, on some systems, eg. bootc images, /var/lib/rpm isn't a symlink and doesn't contain the RPM database.
*
* We will first try if the "new" location /usr/lib/sysimage/rpm exists, and use it only if it exists.
* If it doesn't exist, we will fall back to the "old" location /var/lib/rpm.
*/

struct stat sb;
const char *dbpath;
const char *prefix = getenv("OSCAP_PROBE_ROOT");
char *path_with_prefix = oscap_path_join(prefix, "/usr/lib/sysimage/rpm");
if (stat(path_with_prefix, &sb) == 0) {
dbpath = "/usr/lib/sysimage/rpm";
} else {
dbpath = "/var/lib/rpm";
}
free(path_with_prefix);
dI("Using %s as rpm database.", dbpath);
rpmPushMacro(NULL, "_dbpath", NULL, dbpath, RMIL_CMDLINE);
}
3 changes: 3 additions & 0 deletions src/OVAL/probes/unix/linux/rpm-helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,7 @@ int rpmVerifyFile(const rpmts ts, const rpmfi fi,
*/
void rpmLibsPreload(void);

void set_rpm_db_path(void);


#endif
12 changes: 1 addition & 11 deletions src/OVAL/probes/unix/linux/rpminfo_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,17 +294,7 @@ void *rpminfo_probe_init(void)
return ((void *)g_rpm);
}

/*
* Fedora >=36 changed the default dbpath in librpm from /var/lib/rpm to /usr/lib/sysimage/rpm
* See: https://fedoraproject.org/wiki/Changes/RelocateRPMToUsr
* Therefore, when running openscap on a Fedora >=36 system scanning another systems (such as RHEL, SLES, Fedora<36)
* openscap's librpm will try to read the rpm db from /usr/lib/sysimage/rpm which doesn't exist and therefore won't work.
* In implementing this change, /var/lib/rpm is still a symlink to /usr/lib/sysimage/rpm
* so /var/lib/rpm still works. So /var/lib/rpm is a dbpath that will work on all systems.
* Therefore, set the dbpath to be /var/lib/rpm, allow openscap running on any system to scan any system.
*/
rpmPushMacro(NULL, "_dbpath", NULL, "/var/lib/rpm", RMIL_CMDLINE);

set_rpm_db_path();
g_rpm->rpmts = rpmtsCreate();
pthread_mutex_init (&(g_rpm->mutex), NULL);

Expand Down
11 changes: 1 addition & 10 deletions src/OVAL/probes/unix/linux/rpmverify_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,7 @@ void *rpmverify_probe_init(void)
return (NULL);
}

/*
* Fedora >=36 changed the default dbpath in librpm from /var/lib/rpm to /usr/lib/sysimage/rpm
* See: https://fedoraproject.org/wiki/Changes/RelocateRPMToUsr
* Therefore, when running openscap on a Fedora >=36 system scanning another systems (such as RHEL, SLES, Fedora<36)
* openscap's librpm will try to read the rpm db from /usr/lib/sysimage/rpm which doesn't exist and therefore won't work.
* In implementing this change, /var/lib/rpm is still a symlink to /usr/lib/sysimage/rpm
* so /var/lib/rpm still works. So /var/lib/rpm is a dbpath that will work on all systems.
* Therefore, set the dbpath to be /var/lib/rpm, allow openscap running on any system to scan any system.
*/
rpmPushMacro(NULL, "_dbpath", NULL, "/var/lib/rpm", RMIL_CMDLINE);
set_rpm_db_path();

struct rpm_probe_global *g_rpm = malloc(sizeof(struct rpm_probe_global));
g_rpm->rpmts = rpmtsCreate();
Expand Down
11 changes: 1 addition & 10 deletions src/OVAL/probes/unix/linux/rpmverifyfile_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,16 +358,7 @@ void *rpmverifyfile_probe_init(void)

struct rpm_probe_global *g_rpm = malloc(sizeof(struct rpm_probe_global));

/*
* Fedora >=36 changed the default dbpath in librpm from /var/lib/rpm to /usr/lib/sysimage/rpm
* See: https://fedoraproject.org/wiki/Changes/RelocateRPMToUsr
* Therefore, when running openscap on a Fedora >=36 system scanning another systems (such as RHEL, SLES, Fedora<36)
* openscap's librpm will try to read the rpm db from /usr/lib/sysimage/rpm which doesn't exist and therefore won't work.
* In implementing this change, /var/lib/rpm is still a symlink to /usr/lib/sysimage/rpm
* so /var/lib/rpm still works. So /var/lib/rpm is a dbpath that will work on all systems.
* Therefore, set the dbpath to be /var/lib/rpm, allow openscap running on any system to scan any system.
*/
rpmPushMacro(NULL, "_dbpath", NULL, "/var/lib/rpm", RMIL_CMDLINE);
set_rpm_db_path();

g_rpm->rpmts = rpmtsCreate();

Expand Down
13 changes: 3 additions & 10 deletions src/OVAL/probes/unix/linux/rpmverifypackage_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ void *rpmverifypackage_probe_init(void)
root = NULL;
}

// needs to be called before we chroot
set_rpm_db_path();

struct verifypackage_global *g_rpm = malloc(sizeof(struct verifypackage_global));
probe_chroot_init(&g_rpm->chr, root);

Expand All @@ -354,16 +357,6 @@ void *rpmverifypackage_probe_init(void)
return ((void *)g_rpm);
}

/*
* Fedora >=36 changed the default dbpath in librpm from /var/lib/rpm to /usr/lib/sysimage/rpm
* See: https://fedoraproject.org/wiki/Changes/RelocateRPMToUsr
* Therefore, when running openscap on a Fedora >=36 system scanning another systems (such as RHEL, SLES, Fedora<36)
* openscap's librpm will try to read the rpm db from /usr/lib/sysimage/rpm which doesn't exist and therefore won't work.
* In implementing this change, /var/lib/rpm is still a symlink to /usr/lib/sysimage/rpm
* so /var/lib/rpm still works. So /var/lib/rpm is a dbpath that will work on all systems.
* Therefore, set the dbpath to be /var/lib/rpm, allow openscap running on any system to scan any system.
*/
rpmPushMacro(NULL, "_dbpath", NULL, "/var/lib/rpm", RMIL_CMDLINE);

g_rpm->rpm.rpmts = rpmtsCreate();

Expand Down
5 changes: 1 addition & 4 deletions tests/probes/rpm/rpm_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ RPMBUILD="${RPMBASE}/build"

# Since Fedora 36 RPM database location changed, see
# https://fedoraproject.org/wiki/Changes/RelocateRPMToUsr
# However, /var/lib/rpm/ still works as it is a symlink to
# the new path, /usr/lib/sysimage/rpm/, in Fedora >= 36
# Therefore, always use /var/lib/rpm/ as it always works.
RPMDB_PATH="/var/lib/rpm/"
RPMDB_PATH="/usr/lib/sysimage/rpm/"

function rpm_build {
require "rpmbuild" || return 255
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function test_probes_rpmverifypackage {

rm -f $RF

$OSCAP oval eval --results $RF $DF
$OSCAP oval eval --verbose INFO --results $RF $DF

result=$RF

Expand Down

0 comments on commit 04c731a

Please sign in to comment.