determine_kernel() ran boot-entry discovery under a !arg_linux guard
only. With --initrd= but no --linux=, discovery overwrote arg_initrds
with the discovered entry's own initrds (leaking the user's strv) and
set arg_linux, so verify_arguments()'s "--initrd= needs --linux=" check,
which runs afterwards, never fired: the user's --initrd= was
silently discarded. Reject the combination before discovery. This also
keeps the discovery store leak-free.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
int r;
if (!arg_linux && arg_directory) {
- /* A kernel is required for directory type images so attempt to find one under /boot and /efi */
+ /* A kernel is required for directory type images so attempt to find one under /boot and /efi.
+ * Reject a user --initrd= first: discovery would overwrite (and leak) it, and the
+ * --initrd=/--linux= consistency check in verify_arguments() is bypassed once discovery
+ * sets arg_linux. */
+ if (!strv_isempty(arg_initrds))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "--initrd= cannot be used with --directory= unless --linux= is also specified.");
+
r = discover_boot_entry(arg_directory, &arg_linux, &arg_initrds);
if (r < 0)
return log_error_errno(r, "Failed to locate UKI in directory type image, please specify one with --linux=.");