From 540016756f8307c1b048007dedd145eca56603a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= Date: Thu, 22 Aug 2024 11:31:16 +0200 Subject: [PATCH] Improve rpm database path in RPM probes 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: https://github.com/OpenSCAP/openscap/issues/2151 --- src/OVAL/probes/unix/linux/rpm-helper.c | 29 +++++++++++++++++++ src/OVAL/probes/unix/linux/rpm-helper.h | 3 ++ src/OVAL/probes/unix/linux/rpminfo_probe.c | 12 +------- src/OVAL/probes/unix/linux/rpmverify_probe.c | 11 +------ .../probes/unix/linux/rpmverifyfile_probe.c | 11 +------ .../unix/linux/rpmverifypackage_probe.c | 11 +------ tests/probes/rpm/rpm_common.sh | 5 +--- .../rpmverifypackage_common.sh | 2 +- 8 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/OVAL/probes/unix/linux/rpm-helper.c b/src/OVAL/probes/unix/linux/rpm-helper.c index f7e29cc3d2..e31b2b2e0d 100644 --- a/src/OVAL/probes/unix/linux/rpm-helper.c +++ b/src/OVAL/probes/unix/linux/rpm-helper.c @@ -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); +} diff --git a/src/OVAL/probes/unix/linux/rpm-helper.h b/src/OVAL/probes/unix/linux/rpm-helper.h index de7b5fe351..d58f6ccaf5 100644 --- a/src/OVAL/probes/unix/linux/rpm-helper.h +++ b/src/OVAL/probes/unix/linux/rpm-helper.h @@ -99,4 +99,7 @@ int rpmVerifyFile(const rpmts ts, const rpmfi fi, */ void rpmLibsPreload(void); +void set_rpm_db_path(void); + + #endif diff --git a/src/OVAL/probes/unix/linux/rpminfo_probe.c b/src/OVAL/probes/unix/linux/rpminfo_probe.c index 46ad1d9719..53f97bd4b4 100644 --- a/src/OVAL/probes/unix/linux/rpminfo_probe.c +++ b/src/OVAL/probes/unix/linux/rpminfo_probe.c @@ -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); diff --git a/src/OVAL/probes/unix/linux/rpmverify_probe.c b/src/OVAL/probes/unix/linux/rpmverify_probe.c index 6a8f4b4992..bf310ea7d7 100644 --- a/src/OVAL/probes/unix/linux/rpmverify_probe.c +++ b/src/OVAL/probes/unix/linux/rpmverify_probe.c @@ -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(); diff --git a/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c b/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c index 12145c411f..8da310e51b 100644 --- a/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c +++ b/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c @@ -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(); diff --git a/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c b/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c index 90d053aaae..55aae69744 100644 --- a/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c +++ b/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c @@ -354,16 +354,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(); @@ -377,6 +367,7 @@ void *rpmverifypackage_probe_init(void) rpmtsSetRootDir(g_rpm->rpm.rpmts, CHROOT_PATH()); } + set_rpm_db_path(); pthread_mutex_init(&(g_rpm->rpm.mutex), NULL); return ((void *)g_rpm); } diff --git a/tests/probes/rpm/rpm_common.sh b/tests/probes/rpm/rpm_common.sh index c8b4661f87..eb96f76d80 100755 --- a/tests/probes/rpm/rpm_common.sh +++ b/tests/probes/rpm/rpm_common.sh @@ -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 diff --git a/tests/probes/rpm/rpmverifypackage/rpmverifypackage_common.sh b/tests/probes/rpm/rpmverifypackage/rpmverifypackage_common.sh index c03bd2e169..0ae994ccbc 100755 --- a/tests/probes/rpm/rpmverifypackage/rpmverifypackage_common.sh +++ b/tests/probes/rpm/rpmverifypackage/rpmverifypackage_common.sh @@ -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