lpfc: unbounded QFPA response length in lpfc_cmpl_els_qfpa()
From: Maoyi Xie
Date: Mon Jun 22 2026 - 12:40:46 EST
Hi all,
I think lpfc_cmpl_els_qfpa() in drivers/scsi/lpfc/lpfc_els.c can overflow the
qfpa_res buffer when the fabric returns a large length in the QFPA response.
I would appreciate it if you could take a look.
The completion handler allocates qfpa_res to a fixed size, then copies the
response using a length taken straight from the response payload.
if (!vport->qfpa_res) {
max_desc = FCELSSIZE / sizeof(*vport->qfpa_res);
vport->qfpa_res = kzalloc_objs(*vport->qfpa_res, max_desc);
...
}
len = *((u32 *)(pcmd + 4));
len = be32_to_cpu(len);
memcpy(vport->qfpa_res, pcmd, len + 8);
pcmd is the QFPA ELS response from the fabric. len is a 32 bit field read
out of it with no validation. The memcpy then copies len + 8 bytes into
qfpa_res, which was sized for FCELSSIZE. Nothing checks that len + 8 stays
within that. A fabric or target that returns a large len overflows the
qfpa_res heap buffer. The loop just below also walks vmid_range for len
iterations with no clamp against MAX_PRIORITY_DESC.
This runs when the VMID feature is negotiated. The attacker is a malicious
or compromised fabric switch or target answering the QFPA request.
I reproduced the overflow on 7.1-rc7. I ran the same copy with a 1020 byte
qfpa_res buffer and a len that makes len + 8 larger than it. The copy runs
past the buffer and faults.
BUG: unable to handle page fault ... in memcpy_orig
A check that len + 8 stays within the qfpa_res allocation, and that the
descriptor count stays within MAX_PRIORITY_DESC, would close it.
Does this look like a real bug to you, and is bounding len the right
approach? If so I am happy to send a proper patch with a Fixes tag and Cc
stable.
Kaixuan Li and I found this together.
Thanks,
Maoyi
https://maoyixie.com/