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/