From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C2D03CBE78 for ; Wed, 19 Aug 2026 05:58:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787119108; cv=none; b=T/As01gilseKm5g6qbjeKJ+MhRGbWl7mwq2YukdsQMApTA7+fzNCHvQQoBm/Soe0Y5Ayf703CBvql0mKEYZ7i3VKJTzPgMlqCqTwjnX/CSEbww4nq3oKrF9D5z2NYh5i/JEf23BBwwYhJl0SOpF/9cNm/yiQo423uazLq/2PWRA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787119108; c=relaxed/simple; bh=X7OAjoz45ruqsmKdUnSzuXYAV49gETzN7qtOUQui5+U=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=vGCaLrWl8ZD8bFvIUd1Iy9x/CaYL0zvE7GkQfg80o3fFOnBGr5YYDHeFuZbqNB857lFj+54777RwcF5gY9ECsOR6mfobXu+bhzhlFuiecxmGsyXsG1mhB5tmbQA6BkLPBZiZNOdV26JimutrxtR7mM8TpP1C8FEMTF0IugzvVgs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Q/N35m2a; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=orJ3nEzZ; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Q/N35m2a"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="orJ3nEzZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1787119104; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3wN405h1WvQQ42J9aP5itCeH3PDbeYvXDW/m8ee+hMM=; b=Q/N35m2ajlLhA4c8nyU1FtuJF/QRGgUmfgGrfGnI6q/mmfvBQwJ5KvsLcqZV0guDZn5FXk ZnGQzxz8YoMEfPlD/CCzUAXcFn5HrN+cINMJEFBbcXCuOHU2W49XFr0tNsz8MJFY8S1EnV MZNcSifIGL37+IoI1gS5FX2Ukx0qCO0= Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-663-xPongAcjPsu9KG2R8R0e0g-1; Wed, 19 Aug 2026 01:58:23 -0400 X-MC-Unique: xPongAcjPsu9KG2R8R0e0g-1 X-Mimecast-MFC-AGG-ID: xPongAcjPsu9KG2R8R0e0g_1787119102 Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2cd01a14e81so9460425ad.1 for ; Tue, 18 Aug 2026 22:58:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1787119102; x=1787723902; darn=vger.kernel.org; h=content-transfer-encoding:content-type:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:from:to:cc:subject:date:message-id:reply-to :content-type; bh=3wN405h1WvQQ42J9aP5itCeH3PDbeYvXDW/m8ee+hMM=; b=orJ3nEzZ90icAmCoX6Re9kp7tdvVxvtcV41IgJg7gA+ScJWzrGbxTWqy4tr3ybHfWr PVg8hyVM91IoAfCZBJ1pzCHCxQGo5MofTvKUh8/NEqjgLBDtXhbbopiUergPGuEL2zeN KfYLFhI3M684epYR2IPyDcP+ysnRZIzjeULVfZExumSoMq+UI1UKkU6IK1ez5JIhQ81Y vmMY/5jMy6RnD9IgMdux5rdvTFPAGNSt9+XRErrLhEiq2mmIYd6p9IuAVa76I8+OJeU+ 3XIG03CbS2BPoFSbbZIUb8A/Uwe9fRW0NTcjURnGvjGwOYuRxa4KZs+nugtwq0mwvS9g i5sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787119102; x=1787723902; h=content-transfer-encoding:content-type:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3wN405h1WvQQ42J9aP5itCeH3PDbeYvXDW/m8ee+hMM=; b=SlAKX+AO9sfuYjWw4X/HG/kOkgXT+KIZlfYQzg4TsyHAHp5pnDx2mP6j7wrTsDEz8n JNVQI+C8tB66dDUQQ4DGxcW8qDhdqiwBZbNI4xGHD7pP5JIqQYANrNXdvlvYDVWjy4oq 4rhJigotk/3gmJu2LFaMLfabsOxG4VztjViCREbjYb5q0s8pIBmXABNj5eSghcfhZxt8 MCanza4Ldi9ubvTfiPlxKj98SPK2FPP3dm7QEoncKN6lj7fX6khOotBqIR9cTVt5Rmig MKG3g7obX1vca8iHOBDchyxEBCUWNvQ1AGyOy8YhgEedWfiVWfdK0dDzMvTj79iKR076 TzHg== X-Forwarded-Encrypted: i=1; AHgh+RoJ9R5Dm65CSAx+T2dm+L+Cw8haVxzg+dRYbNYmvAVvejqpujraFs3WFg7pYzlBj2bNHJDTLpUw0bLLuaw=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+DGWjJwWQRuLscpMZMOaYsCC8EinCPw56+/kR4CX8R0quLlMb ncS/uFplX/4VZ5ZxQkgSuXFofZaT1SwGukXq60ej8XDtx/7L1E5nqLGi/V5WuQuTsOb9UmS4aBS xymEuzRmpOZMz2JX4aWRagoUEnR7xlFaSE2oLQ7S0dMdbATV0Y848MHXmR0EkTA92eg== X-Gm-Gg: AR+sD12wJXjVmm44xtuCb/sBEAMTV8nlNaKciY2NEt51tPK+i38YeN38tOiWfRjxy5+ sq+apwU6vJ3GhGSnOIzyZt/76MI8drZKt2NYkKjgQg+3/G46bsXudGegvkUJdZ0AC7k34/8SNs1 l0mnYVwdN02f1uHkhp7xQC8yk34K0fNqgRB2nf77enqhT26pB+erQ2tAqIA1xpe5M/FT75J8QI5 os9dduXwV6ppOB5inl9zCIi+An/mewjEnOkJIjS3C7Bh3mbnVmoAECq13FLz7aIHLz/v78zlfpX aeJd1tYppSAwY7VF9EjILBh7ccCKmzuQPq5fjZBUEnWZyRCzZ/e+Rc2BpQclPJ/neJTpzUZvQC8 Ej0Ef8qMK2IQ4V2nbE3VS X-Received: by 2002:a17:902:fd87:b0:2cb:ea0b:9164 with SMTP id d9443c01a7336-2d5fd6b0aebmr41699995ad.6.1787119101988; Tue, 18 Aug 2026 22:58:21 -0700 (PDT) X-Received: by 2002:a17:902:fd87:b0:2cb:ea0b:9164 with SMTP id d9443c01a7336-2d5fd6b0aebmr41699365ad.6.1787119101427; Tue, 18 Aug 2026 22:58:21 -0700 (PDT) Received: from [10.76.99.122] ([115.110.236.142]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d5c1e5506asm20846515ad.43.2026.08.18.22.58.14 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 18 Aug 2026 22:58:20 -0700 (PDT) Message-ID: <0d7acb43-2eb4-44ec-9bfb-b89440afc605@redhat.com> Date: Wed, 19 Aug 2026 11:28:10 +0530 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] kexec: return -ENOEXEC from image probe functions on mismatch To: Pratyush Yadav Cc: Catalin Marinas , Will Deacon , Mark Rutland , Huacai Chen , WANG Xuerui , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Andrew Morton , Baoquan He , Mike Rapoport , Pasha Tatashin , Tao Liu , Philipp Rudo , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, linux-riscv@lists.infradead.org, kexec@lists.infradead.org References: <20260813-mpilaniy-v1-1-777d4d0e30f7@redhat.com> <2vxzv79c23j6.fsf@kernel.org> <9cbe111c-ff63-4f24-b518-094ddd7cea30@redhat.com> <2vxzbjaz2269.fsf@kernel.org> Content-Language: en-US From: Mukesh Pilaniya In-Reply-To: <2vxzbjaz2269.fsf@kernel.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi Pratyush, On 18/08/26 3:14 pm, Pratyush Yadav wrote: > On Fri, Aug 14 2026, Mukesh Pilaniya wrote: > >> Hi Pratyush, >> On 14/08/26 7:43 pm, Pratyush Yadav wrote: >>> On Thu, Aug 13 2026, Mukesh Pilaniya wrote: >>> >>>> Several kexec_file_load() image probe functions return -EINVAL when >>>> they do not recognize the image format. A probe function that rejects >>>> an image should return -ENOEXEC to indicate that the image is not a >>>> recognized executable format. -EINVAL implies a problem with the >>>> syscall parameters, not with image recognition. >>>> >>>> kexec_image_probe_default() iterates through registered loaders and >>>> returns the last probe's error code to the caller. That error >>>> propagates as the kexec_file_load() return value to userspace. >>>> Returning -EINVAL from a probe when no loader matches is semantically >>>> incorrect and misleads userspace about the nature of the failure. >>>> >>>> Return -ENOEXEC from all probe functions and their helpers when the >>>> image format is not recognized. >>> >>> Sounds fine in principle but can you please also share what the real >>> problem you face is and how changing these return codes helps? These >>> error codes are uAPI and while we _can_ change them as long as we don't >>> break something, there should be a clear motivation for doing so. >>> >>> [...] >>> >> While debugging a misleading error on s390x where kexec -s reported >> "syscall kexec_file_load not available" instead of the actual EINVAL >> from a kernel command line that exceeded the architecture limit, we >> traced the problem to the kexec-tools userspace utility treating >> EINVAL the same as ENOSYS and ENOEXEC -- as a signal to silently fall >> back to kexec_load(). >> >> kexec-tools supports two syscalls: kexec_file_load() and the older >> kexec_load(). With -a (the default), it tries kexec_file_load() >> first and falls back to kexec_load() when the syscall is not >> implemented (ENOSYS) or the kernel does not have a loader for the >> image format. With -s, it uses kexec_file_load() only with no >> fallback. >> >> When the kernel returns -EINVAL it means something went wrong while >> loading the image, not that the syscall is missing or the image >> format is unrecognized. kexec-tools should not fall back to the >> older syscall in that case. However, some kernel probe functions >> currently return -EINVAL when the image header does not match, >> instead of returning -ENOEXEC. Keeping EINVAL in the fallback set >> to accommodate these probes has the side effect of also hiding >> genuine loading errors like an oversized command line. >> >> kexec-tools should only fall back when kexec_file_load() is not >> implemented or does not have a matching loader -- not when something >> goes wrong during load. >> >> The fix on the kexec-tools side is to remove EINVAL from the fallback >> set, but that requires the kernel to be clean first -- probe functions >> must return -ENOEXEC when they do not recognize an image format, not -EINVAL. > > Okay, the idea makes sense. Though I am curious if in practice there are > images that kexec_file_load() can't load but kexec-tools can. > > But then I went and looked at the code. The only caller of the probe > functions I can see is kexec_image_probe_default(). Looking at its code: > > int kexec_image_probe_default(struct kimage *image, void *buf, > unsigned long buf_len) > { > const struct kexec_file_ops * const *fops; > int ret = -ENOEXEC; > > for (fops = &kexec_file_loaders[0]; *fops && (*fops)->probe; ++fops) { > ret = (*fops)->probe(buf, buf_len); > if (!ret) { > image->fops = *fops; > return ret; > } > } > > return ret; > } > > It defaults ret to -ENOEXEC, which makes sense, but then lets it be > over-written by each loader. So in practice, it returns what the _last_ > loader returned. _This_ makes no sense. Why should the last loader be > any special? Right, the last loader overwriting ret, the commit message describes this as well. It makes no sense for the return value to depend on whichever loader happens to be last in the array. > > From reading the code, I think what the author of this wanted to do is > to try all loaders, and return -ENOEXEC if none succeeded. But the code > of course strays from that and ends up returning the last loader's > value.IMHO the function should only try the next loader when a probe returns -ENOEXEC, not for any other error like -ENOMEM, which is a real failure and should be propagated immediately, not silently discarded. > > So how about the below diff instead? (** only compile tested **) > > --- 8< --- > diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c > index 2bfbb2d144e6..cfb2b8cd5679 100644 > --- a/kernel/kexec_file.c > +++ b/kernel/kexec_file.c > @@ -67,17 +67,16 @@ int kexec_image_probe_default(struct kimage *image, void *buf, > unsigned long buf_len) > { > const struct kexec_file_ops * const *fops; > - int ret = -ENOEXEC; > > for (fops = &kexec_file_loaders[0]; *fops && (*fops)->probe; ++fops) { > - ret = (*fops)->probe(buf, buf_len); > - if (!ret) { > + if (!(*fops)->probe(buf, buf_len)) { > image->fops = *fops; > - return ret; > + return 0; > } > } > > - return ret; > + /* No loader found. */ > + return -ENOEXEC; > } Nice catch, Pratyush but this discards all non-zero return values from probe functions, which means real errors get swallowed. For example, kexec_elf_probe() can return -ENOMEM when kzalloc() fails in elf_read_phdrs(). With this diff, that -ENOMEM becomes -ENOEXEC, which tells userspace "no loader found" when the actual problem was a memory allocation failure. > > static void *kexec_image_load_default(struct kimage *image) > How about the following instead? It keeps the probe return value and distinguishes -ENOEXEC (format not recognized, try next loader) from any other error (real failure, propagate immediately):  diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 59fb9d71e9d8..ceb5c97cedac 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -68,17 +68,19 @@ int kexec_image_probe_default(struct kimage *image, void *buf, unsigned long buf_len) { const struct kexec_file_ops * const *fops; - int ret = -ENOEXEC; + int ret; for (fops = &kexec_file_loaders[0]; *fops && (*fops)->probe; ++fops) { ret = (*fops)->probe(buf, buf_len); - if (!ret) { + if (ret == 0) { image->fops = *fops; - return ret; + return 0; } + if (ret != -ENOEXEC) + return ret; } - return ret; + return -ENOEXEC; } static void *kexec_image_load_default(struct kimage *image) This requires probe functions to return -ENOEXEC from fixes in patch 1. I will add this as a separate patch on top in v2. Does this looks good to you ? -- Regards, Mukesh Pilaniya