Skip to content

Commit

Permalink
core: Ignore subdirectories of /usr/lib/modules without a kernel
Browse files Browse the repository at this point in the history
There's a valid use case of installing a 3rd party RPM which has
pre-built kmods for *multiple* kernel versions.  What we care about
here is that there aren't actually multiple kernel binaries aka
`vmlinuz`.

Closes: #3965
  • Loading branch information
cgwalters committed Aug 25, 2022
1 parent 476ad62 commit 80bb67c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
23 changes: 14 additions & 9 deletions src/libpriv/rpmostree-kernel.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ find_kernel_and_initramfs_in_bootdir (int rootfs_dfd, const char *bootdir, char
return TRUE;
}

/* Given a directory @subpath, find the first child that is a directory,
* returning it in @out_subdir. If there are multiple directories,
/* Given a directory @subpath, find the first child that is a directory
* and contains a `vmlinuz` file, returning it in @out_subdir. If there are multiple directories,
* return an error.
*/
static gboolean
find_ensure_one_subdirectory (int rootfs_dfd, const char *subpath, char **out_subdir,
GCancellable *cancellable, GError **error)
find_dir_with_vmlinuz (int rootfs_dfd, const char *subpath, char **out_subdir,
GCancellable *cancellable, GError **error)
{
g_autofree char *ret_subdir = NULL;
g_auto (GLnxDirFdIterator) dfd_iter = {
Expand All @@ -132,11 +132,18 @@ find_ensure_one_subdirectory (int rootfs_dfd, const char *subpath, char **out_su

if (dent->d_type != DT_DIR)
continue;
// Ignore directories without vmlinuz
struct stat stbuf;
g_autofree char *vmlinuz_path = g_strdup_printf ("%s/vmlinuz", dent->d_name);
if (!glnx_fstatat_allow_noent (dfd_iter.fd, vmlinuz_path, &stbuf, AT_SYMLINK_NOFOLLOW, error))
return FALSE;
if (errno == ENOENT)
continue;

if (ret_subdir)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Multiple subdirectories found in: %s: %s %s", subpath,
"Multiple kernels (vmlinuz) found in: %s: %s %s", subpath,
glnx_basename (ret_subdir), dent->d_name);
return FALSE;
}
Expand Down Expand Up @@ -179,8 +186,7 @@ gboolean
rpmostree_kernel_remove (int rootfs_dfd, GCancellable *cancellable, GError **error)
{
g_autofree char *modversion_dir = NULL;
if (!find_ensure_one_subdirectory (rootfs_dfd, "usr/lib/modules", &modversion_dir, cancellable,
error))
if (!find_dir_with_vmlinuz (rootfs_dfd, "usr/lib/modules", &modversion_dir, cancellable, error))
return FALSE;
if (modversion_dir)
{
Expand Down Expand Up @@ -231,8 +237,7 @@ rpmostree_find_kernel (int rootfs_dfd, GCancellable *cancellable, GError **error
{
/* Fetch the kver from /usr/lib/modules */
g_autofree char *modversion_dir = NULL;
if (!find_ensure_one_subdirectory (rootfs_dfd, "usr/lib/modules", &modversion_dir, cancellable,
error))
if (!find_dir_with_vmlinuz (rootfs_dfd, "usr/lib/modules", &modversion_dir, cancellable, error))
return NULL;

if (!modversion_dir)
Expand Down
8 changes: 7 additions & 1 deletion tests/compose/test-misc-tweaks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ build_rpm foobar-rec
build_rpm quuz
build_rpm corge version 1.0
build_rpm corge version 2.0
build_rpm thirdpartymodules version 2.3 \
files "/usr/lib/modules/4.7.8-10.x86_64/foo.ko
/usr/lib/modules/4.9.3-2.x86_64/foo.ko
/usr/lib/modules/5.8.1-11.x86_64/foo.ko
" \
install "for v in 4.7.8-10.x86_64 4.9.3-2.x86_64 5.8.1-11.x86_64; do d=%{buildroot}/usr/lib/modules/\$v; mkdir -p \$d && echo kmod\$v > \$d/foo.ko; done"
# test `remove-from-packages` (files shared with other pkgs should not be removed)
build_rpm barbar \
files "/etc/sharedfile
Expand All @@ -26,7 +32,7 @@ build_rpm barbaz \
echo gpgcheck=0 >> yumrepo.repo
ln "$PWD/yumrepo.repo" config/yumrepo.repo
# the top-level manifest doesn't have any packages, so just set it
treefile_append "packages" $'["\'foobar >= 0.5\' quuz \'corge < 2.0\' barbar barbaz"]'
treefile_append "packages" $'["\'foobar >= 0.5\' quuz \'corge < 2.0\' barbar barbaz thirdpartymodules"]'

# With docs and recommends, also test multi includes
cat > config/documentation.yaml <<'EOF'
Expand Down
3 changes: 3 additions & 0 deletions tests/kolainst/destructive/container-image
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ ADD baz-2.0-1.x86_64.rpm /run/rpm-ostree/staged-rpms/${baz_chksum}.rpm
RUN rpm-ostree ex rebuild
RUN echo some config file > /etc/someconfig.conf
RUN echo somedata > /usr/share/somenewdata
# Verify we're ignoring subdirectories that don't contain vmlinuz https://github.com/coreos/rpm-ostree/issues/3965
RUN mkdir -p /usr/lib/modules/blah && touch /usr/lib/modules/blah/foo
RUN rpm-ostree cleanup -m
EOF
# Older podman found in RHEL8 blows up without /etc/resolv.conf
# which happens in our qemu path.
Expand Down

0 comments on commit 80bb67c

Please sign in to comment.