From: sashiko-bot@kernel.org
To: "Jörg Rödel" <joro@8bytes.org>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 33/60] KVM: Implement KVM_CREATE_VCPU ioctl for planes
Date: Mon, 08 Jun 2026 18:13:19 +0000 [thread overview]
Message-ID: <20260608181319.C7C231F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260608144252.351443-34-joro@8bytes.org>
Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
- [Critical] Error cleanup paths for secondary plane vCPUs erroneously destroy the shared `vcpu->common` struct, leading to a Use-After-Free.
- [High] Moving the vCPU ID uniqueness check outside kvm->lock introduces TOCTOU races allowing duplicate IDs and Use-After-Free during lockless iteration.
- [High] The global `max_vcpus` check incorrectly blocks the creation of secondary plane vCPUs.
- [High] Invoking `kvm_vcpu_finish_common` for secondary plane vCPUs inflates `online_vcpus`, corrupting `vcpu_idx` tracking.
- [High] `kvm_wait_for_vcpu_online` prematurely bypasses serialization for secondary plane vCPUs due to shared `vcpu_idx`.
- [High] Secondary plane vCPUs are permanently leaked upon VM destruction.
- [Medium] Compat (32-bit) userspace can bypass plane restrictions to execute KVM_SET_SIGNAL_MASK on secondary plane vCPUs.
- [Low] Incorrect argument ordering in snprintf results in confusing debugfs directory names for secondary plane vCPUs.
--
commit 37dfbdb6cd414eb1fae3e8d12818fac2b59a5e31
Author: Joerg Roedel <joerg.roedel@amd.com>
Implement the KVM_CREATE_VCPU ioctl per plane.
This commit implements the KVM_CREATE_VCPU ioctl on a per-plane basis and
introduces an empty IOCTL path for plane-vcpus. It also introduces
architecture-specific callbacks to check if an ioctl is a vcpu plane ioctl.
[ ... ]
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 385e1ee8fd3a..b8c3f8f11cb4 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -1126,7 +1126,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
> #define kvm_for_each_vcpu(idx, vcpup, kvm) \
> plane_for_each_vcpu(idx, vcpup, kvm->planes[0])
[Severity: High]
Does this macro definition permanently leak secondary plane vCPUs upon VM
destruction?
Since kvm_destroy_vcpus() relies on kvm_for_each_vcpu() to iterate and free
all vCPUs, it seems it will now silently skip all vCPUs created on secondary
planes (where plane->level > 0), leaking their struct kvm_vcpu and
architectural state.
[ ... ]
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 2d0d5f4fd356..8839f91fd15e 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
[ ... ]
> @@ -4327,13 +4328,17 @@ DEFINE_SIMPLE_ATTRIBUTE(vcpu_get_pid_fops, vcpu_get_pid, NULL, "%llu\n");
>
> static void kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
> {
> + char dir_name[10 + (2 * ITOA_MAX_LEN) + 1];
> struct dentry *debugfs_dentry;
> - char dir_name[ITOA_MAX_LEN * 2];
>
> if (!debugfs_initialized())
> return;
>
> - snprintf(dir_name, sizeof(dir_name), "vcpu%d", vcpu->vcpu_id);
> + if (vcpu->plane_level == 0)
> + snprintf(dir_name, sizeof(dir_name), "vcpu%d", vcpu->vcpu_id);
> + else
> + snprintf(dir_name, sizeof(dir_name), "vcpu%d-plane%d", vcpu->plane_level, vcpu->vcpu_id);
[Severity: Low]
Are the arguments to snprintf() reversed here?
The format string is "vcpu%d-plane%d", but the arguments are
vcpu->plane_level followed by vcpu->vcpu_id. Will this result in confusing
directory names like "vcpu1-plane5" instead of "vcpu5-plane1"?
> +
> debugfs_dentry = debugfs_create_dir(dir_name,
> vcpu->kvm->debugfs_dentry);
> debugfs_create_file("pid", 0444, debugfs_dentry, vcpu,
> @@ -4346,10 +4351,11 @@ static void kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
> /*
> * Creates some virtual cpus. Good luck creating more than one.
> */
> -static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, unsigned long id)
> +static int kvm_plane_ioctl_create_vcpu(struct kvm_plane *plane, unsigned long id)
> {
> - int r = -EINVAL;
> + struct kvm *kvm = plane->kvm;
> struct kvm_vcpu *vcpu;
> + int r;
>
> mutex_lock(&kvm->lock);
> if (kvm->created_vcpus >= kvm->max_vcpus) {
[Severity: High]
Does this global kvm->max_vcpus check incorrectly block the creation of
secondary plane vCPUs?
Since kvm->created_vcpus is only incremented inside kvm_vcpu_init_common()
(which is only called for plane 0), it reflects the number of plane 0 vCPUs.
If a VM fully populates plane 0, won't this check permanently reject the
creation of any secondary plane vCPUs by returning -EINVAL?
> @@ -4366,11 +4372,28 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, unsigned long id)
> if (!vcpu)
> return -ENOMEM;
>
> - r = kvm_vcpu_init_common(vcpu, kvm, id);
> - if (r)
> + r = -EEXIST;
> + if (plane_get_vcpu_by_id(plane, id))
> goto vcpu_free;
[Severity: High]
Does moving the vCPU ID uniqueness check outside kvm->lock introduce a TOCTOU
race?
If two threads concurrently create a vCPU with the same ID, both could see NULL
from plane_get_vcpu_by_id(), complete creation, and insert duplicate vCPUs into
plane->vcpu_array. Can this lead to Use-After-Free during lockless iteration of
the xarray?
>
> + if (plane->level > 0) {
> + struct kvm_vcpu *vcpu_plane0 = kvm_get_vcpu_by_id(kvm, id);
> +
> + /* Plane0 VCPU must exist before creating non-plane0 VCPUs */
> + r = -EINVAL;
> + if (vcpu_plane0 == NULL)
> + goto vcpu_free;
> +
> + vcpu->common = vcpu_plane0->common;
> + } else {
> + r = kvm_vcpu_init_common(vcpu, kvm, id);
> + if (r)
> + goto vcpu_free;
> + }
> +
[Severity: Critical]
Could the error path in kvm_plane_ioctl_create_vcpu() cause a use-after-free
for the plane 0 vCPU?
For plane->level > 0, vcpu->common is an alias to vcpu_plane0->common. If an
initialization step fails and the code jumps to the vcpu_free_common label,
it will call kvm_vcpu_common_destroy(vcpu). Won't this free the run pages and
other state that is actively being used by the already-running plane 0 vCPU?
[Severity: High]
Does invoking kvm_vcpu_finish_common() for secondary plane vCPUs corrupt
vcpu_idx tracking?
kvm_vcpu_finish_common() unconditionally increments kvm->online_vcpus for all
created vCPUs. However, vcpu_idx is derived strictly from online_vcpus inside
kvm_vcpu_init_common(), which is only executed for plane 0. Creating secondary
plane vCPUs will inflate online_vcpus, causing the next plane 0 vCPU to receive
an unexpectedly high, non-contiguous vcpu_idx. Will this sparse vcpu_idx array
trigger out-of-bounds accesses or premature KVM_MAX_VCPUS limit hits?
[ ... ]
> @@ -4550,7 +4568,7 @@ static int kvm_wait_for_vcpu_online(struct kvm_vcpu *vcpu)
>
> /*
> * Acquire and release the vCPU's mutex to wait for vCPU creation to
> - * complete (kvm_vm_ioctl_create_vcpu() holds the mutex until the vCPU
> + * complete (kvm_plane_ioctl_create_vcpu() holds the mutex until the vCPU
> * is fully online).
> */
> if (mutex_lock_killable(kvm_vcpu_mutex(vcpu)))
[Severity: High]
Does this serialization check evaluate to true prematurely for secondary plane
vCPUs?
kvm_wait_for_vcpu_online() bypasses its lock if:
vcpu->vcpu_idx < atomic_read(&kvm->online_vcpus)
For a secondary plane vCPU, vcpu->vcpu_idx is inherited from the already-online
plane 0 vCPU, so kvm->online_vcpus is already greater than this vcpu_idx. Will
concurrent threads bypass this lock and interact with partially initialized
vCPU state?
[ ... ]
> @@ -4858,6 +4895,21 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,
> }
> #endif
>
> +static long __kvm_plane_ioctl(struct kvm_plane *plane, unsigned int ioctl, unsigned long arg)
[Severity: Medium]
Does the compat ioctl handler bypass the new plane restrictions?
The check for kvm_is_vcpu_plane_ioctl() was added to kvm_vcpu_ioctl(), but not
to kvm_vcpu_compat_ioctl(). Can a 32-bit task execute ioctls like
KVM_SET_SIGNAL_MASK on secondary plane vCPUs by bypassing this allowlist?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260608144252.351443-1-joro@8bytes.org?part=33
next prev parent reply other threads:[~2026-06-08 18:13 UTC|newest]
Thread overview: 174+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 14:41 [PATCH 00/60] KVM Planes + SEV-SNP Support Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 14:41 ` [PATCH 01/60] x86/sev: Define the #HV doorbell page structure Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 14:41 ` [PATCH 02/60] KVM: SVM: Add support for the SEV-SNP #HV doorbell page NAE event Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 15:09 ` sashiko-bot
2026-06-08 14:41 ` [PATCH 03/60] KVM: SVM: Inject #HV when Restricted Injection is active Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 15:12 ` sashiko-bot
2026-06-08 14:41 ` [PATCH 04/60] KVM: SVM: Inject NMIs " Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 15:15 ` sashiko-bot
2026-06-08 14:41 ` [PATCH 05/60] KVM: SVM: Inject MCEs " Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 15:28 ` sashiko-bot
2026-06-08 14:41 ` [PATCH 06/60] KVM: SVM: Enable Restricted Injection for an SEV-SNP guest Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 15:38 ` sashiko-bot
2026-06-08 14:41 ` [PATCH 07/60] KVM: SVM: Add support for the SEV-SNP #HV IPI NAE event Jörg Rödel
2026-06-08 14:41 ` Jörg Rödel
2026-06-08 15:24 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 08/60] Documentation: kvm: introduce "VM plane" concept Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 15:29 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 09/60] kvm: Introduce struct kvm_plane Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 10/60] kvm: Move vcpu_array to " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 11/60] kvm: Introduce struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 12/60] kvm: Move vcpu accounting to " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 15:52 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 13/60] kvm: Add read accessors for kvm_vcpu scheduling state Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 15:56 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 14/60] kvm: Make kvm_running_vcpus point to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 15:51 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 15/60] kvm: Move VCPU scheduling state " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:07 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 16/60] kvm: Add accessors for kvm_vcpu->mutex Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 17/60] kvm: Move VCPU locking to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:12 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 18/60] kvm: Move kvm_vcpu->rcuwait " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:26 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 19/60] kvm: Introduce accessors for kvm_vcpu->mode Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:16 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 20/60] kvm: Move kvm_vcpu mode and requests field to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:37 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 21/60] kvm: Introduce per-plane VCPU requests Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:33 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 22/60] kvm: Move kvm_vcpu pid members to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 23/60] kvm: Move kvm_vcpu sigset " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:49 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 24/60] kvm: Move kvm_vcpu spinloop " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:50 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 25/60] kvm: Move kvm_vcpu->dirty_ring " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 17:01 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 26/60] kvm: Introduce arch-specific plane state Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 27/60] kvm: Introduce arch-specific part of struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 28/60] kvm: Implement KVM_CAP_PLANES Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 17:29 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 29/60] kvm: Implement KVM_CREATE_PLANE ioctl Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 17:13 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 30/60] kvm: Add KVM_EXIT_PLANE_EVENT Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 17:36 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 31/60] kvm: Allocate struct kvm_plane in architecture code Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 32/60] kvm: Allocate struct kvm_run only for struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 17:53 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 33/60] KVM: Implement KVM_CREATE_VCPU ioctl for planes Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 18:13 ` sashiko-bot [this message]
2026-06-08 14:42 ` [PATCH 34/60] kvm: Keep track of plane VCPUs in struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 18:24 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 35/60] kvm: Add VCPU plane-scheduling state and helpers Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 16:47 ` Paolo Bonzini
2026-06-08 16:47 ` Paolo Bonzini
2026-06-08 17:52 ` Jörg Rödel
2026-06-08 17:52 ` Jörg Rödel
2026-06-08 17:58 ` Paolo Bonzini
2026-06-08 17:58 ` Paolo Bonzini
2026-06-08 18:35 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 36/60] kvm: Add plane_level to kvm_kernel_irq_routing_entry Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 37/60] kvm: Pass plane_level to kvm_set_routing_entry() Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 18:58 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 38/60] kvm: Make KVM_SIGNAL_MSI per plane Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 19:13 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 39/60] kvm: Make KVM_SET_GSI_ROUTING " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 19:23 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 40/60] kvm: x86: Handle IOAPIC EOIs " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 19:37 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 41/60] kvm: x86: Make apic_map " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 19:49 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 42/60] kvm: x86: Make local APIC code aware of planes Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 20:03 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 43/60] kvm: x86: Move CPUID state to struct kvm_vcpu_arch_common Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 20:17 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 44/60] kvm: x86: Move cpu_caps " Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 20:35 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 45/60] kvm: x86: Update state for all plane VCPUs after CPUID update Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 20:48 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 46/60] kvm: x86: Share MTRR state across planes Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 47/60] kvm: x86: Select a plane to run Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 21:14 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 48/60] kvm: x86: Make event injection VCPU requests per-plane Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 21:22 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 49/60] kvm: x86: Allow hardware backend to overwrite struct kvm_plane allocation Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 50/60] kvm: x86: Make KVM_REQ_UPDATE_PROTECTED_GUEST_STATE per plane Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 21:44 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 51/60] kvm: x86: Share pio_data across planes Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 52/60] kvm: x86: Switch to plane0 if it has events Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 22:10 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 53/60] kvm: x86: Introduce max_planes x86-op Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 14:42 ` [PATCH 54/60] kvm: x86: Restrict KVM planes support to KVM_IRQCHIP_SPLIT Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 22:32 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 55/60] kvm: svm: Track vmsa_features per plane Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 22:45 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 56/60] kvm: svm: Implement GET_AP_APIC_IDS NAE event Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 22:57 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 57/60] kvm: sev: Allow for VMPL level specification in AP create Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 23:08 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 58/60] kvm: svm: Invoke a specified VMPL level VMSA for the vCPU Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 23:21 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 59/60] kvm: svm: Implement max_planes x86 operation Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 23:33 ` sashiko-bot
2026-06-08 14:42 ` [PATCH 60/60] kvm: svm: Advertise full multi-VMPL support to the SNP guest Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel
2026-06-08 23:40 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260608181319.C7C231F00893@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.