ena_com_set_hash_function() inverts the device-support check β RSS hash function is never programmed on compliant devices
Summary
The check returns ENA_COM_UNSUPPORTED exactly when the function IS supported (Linux reference has the negation). On every compliant ENA device the SET_FEATURE hash-function command is never sent; the RSS init tolerates the EOPNOTSUPP, so RSS hashing silently stays in device-default mode. Missing '!' fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3936 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.9 KB | β raw | |
| VERDICT.md | β | 2.1 KB | β raw | |
| fix.diff | β | 477 B | view raw | |
| env.txt | β | 984 B | view raw | |
| manifest.json | β | 775 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-3936 β ena_com_set_hash_function() inverts the hash-function support check
Finding
sys/dev/virtual/amazon/ena/ena-com/ena_com.c:2238-2242
if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func)) {
ena_trc_err("Func hash %d isn't supported by device, abort\n",
rss->hash_func);
return ENA_COM_UNSUPPORTED;
}
The condition aborts exactly when the device DOES support the selected hash
function. Every reference implementation (Linux ena_com.c) uses
if (!(get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func))).
Note 1 << rss->hash_func uses enum positions (TOEPLITZ=1 β bit 1,
CRC32=2 β bit 2) consistent with the spec's funcs bitmask.
Impact
On any compliant ENA device, ena_com_set_hash_function() always fails with
ENA_COM_UNSUPPORTED == EOPNOTSUPP (ena_plat.h:175).
ena_com_fill_hash_function() (ena_com.c:2323-2329) then takes its
restore path, and the caller ena_rss_init_default (ena.c:3081-3087)
treats EOPNOTSUPP as tolerable β so RSS hash-function configuration
(including the driver-chosen CRC32 init value 0xFFFFFFFF) is silently never
programmed. Result: receive-side steering stays in whatever mode the device
had (default), degrading the multi-queue RSS contract the driver advertises
(netisr steering assumes RSS hashing); no memory-safety impact. Confusion
vector (hypervisor boundary): a malicious device cannot exploit the
inversion for memory corruption β it is a pure functional/logic defect
(CWE-628/606-style inverted check).
Trigger
Attach any ENA device that advertises RSS hash function support; observe
"Func hash %d isn't supported by device, abort" in the trace although the
function IS supported, and ena_com_fill_hash_function returning EOPNOTSUPP.
Why inconclusive on this guest
The audit guest has no Amazon ENA PCI function (vendor 0x1d0f absent, env.txt); the path requires the AWS Nitro hypervisor device.
DF-3936 β VERDICT
Status: inconclusive (hardware-gated) β source-level certainty: certain. Impact: logic defect on the hypervisor boundary (RSS hash function never programmed); no memory corruption.
Proof from source
sys/dev/virtual/amazon/ena/ena-com/ena_com.c:2238:if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func))immediately followed by the "isn't supported" error +return ENA_COM_UNSUPPORTED(:2239-2242). The success path (executing the SET_FEATURE at:2244-2267) is only reachable when the device does NOT support the function β i.e. the command is only ever sent for functions the device rejects (and then fails server-side), or never sent at all for the one that matters.- Upstream reference (Linux drivers/net/ethernet/amazon/ena) has the negated
form; the FreeBSD/DragonFly port dropped the
!. - Chain:
ena_rss_init_default(sys/dev/virtual/amazon/ena/ena.c:3081-3087) callsena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL, ENA_HASH_KEY_SIZE, 0xFFFFFFFF)βena_com_set_hash_function()β inverted check fires (device supports CRC32) β EOPNOTSUPP β caller tolerates it (rc != EOPNOTSUPPguard atena.c:3082) β the hash function/init value are never programmed, andena_com_get_hash_function(NULL,NULL)runs as "restore" (ena_com.c:2326-2328).
Why not reproduced
Requires an ENA PCI function (Amazon EC2 Nitro); the audit QEMU guest's
pciconf -l (env.txt) shows only Intel PIIX4 + virtio devices β vendor
0x1d0f absent. Classified inconclusive per batch convention.
Fix
fix.diff adds the missing ! (one character), matching Linux.
fix_status
not_testable β no ENA hardware on the guest; the diff is a 1-token logic
correction against the exact cited line.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableFix not validated on the guest: requires an ENA PCI function (Amazon Nitro), absent from the audit guest (env.txt). fix.diff is the one-token logic correction (missing '!') at ena_com.c:2238, matching the Linux reference driver.
findings/poc/DF-3936/fix.diff + VERDICT.md
Confirmed kernel references
Detail
Evidence (decisive lines)
findings/poc/DF-3936/VERDICT.md + fix.diff (1-token diff) + env.txt
PoC changes
No seed PoC; hardware-gated.
Verified recommended fix
Negate the support check at ena_com.c:2238 (see fix.diff).
Verdict
ena_com_set_hash_function inverts its device-support check (ena_com.c:2238): it returns ENA_COM_UNSUPPORTED exactly when the device DOES support the selected hash function (Linux has the negated form). On any compliant ENA device the RSS hash function (driver selects CRC32 with init 0xFFFFFFFF via ena.c:3081) is therefore never programmed; ena_rss_init_default tolerates the EOPNOTSUPP (ena.c:3082) so the failure is silent and receive-side steering degrades to whatever the device default is. Pure logic defect on the hypervisor boundary - no memory-safety impact. Hardware-gated (no vendor-0x1d0f function on the guest) => inconclusive, source-certain.
No comments yet.