https://bugs.dpdk.org/show_bug.cgi?id=1996

            Bug ID: 1996
           Summary: CN20K inline inbound AES-GMAC key overflow
           Product: DPDK
           Version: unspecified
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: cryptodev
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---
             Group: security

Report date: 2026-03-11
Reported by: 侯朋朋 <[email protected]>

Hello DPDK maintainers,


I would like to report what appears to be a real current-head intra-object
overflow in the `cn20k` inline inbound IPsec path for `AES_GMAC`. I rechecked
current `main`  on 2026-03-10 before writing this report.


The relevant current-head path is:


```c
cn20k_eth_sec_session_create(...)
{
    ...
    rc = cnxk_ow_ipsec_inb_sa_fill(inb_sa_dptr, ipsec, crypto, 0);
    ...
}
```


and the update path reaches the same helper.


The `OW` helper has the same copy-first-then-validate pattern on the `AES_GMAC`
path:


```c
case RTE_CRYPTO_AUTH_AES_GMAC:
    w2->s.auth_type = ROC_IE_SA_AUTH_AES_GMAC;
    key = auth_xfrm->auth.key.data;
    length = auth_xfrm->auth.key.length;
    ...
    break;
...
if (key != NULL && length != 0) {
    memcpy(cipher_key, key, length);
}
...
switch (length) {
case 16:
case 24:
case 32:
    break;
default:
    return -EINVAL;
}
```


The destination object on this inbound `cn20k` path is:


```c
struct roc_ow_ipsec_inb_sa {
    ...
    uint8_t cipher_key[ROC_CTX_MAX_CKEY_LEN];
    union {
        struct {
            uint32_t rsvd8;
            uint8_t salt[4];
        } s;
        uint64_t u64;
    } w8;
    ...
};
```


with `ROC_CTX_MAX_CKEY_LEN == 32`.


So a `40`-byte `AES_GMAC` key overwrites the adjacent member before the
function reports invalid input:


- bytes `0..31` fill `cipher_key[32]`
- bytes `32..39` overwrite adjacent `w8`
- bytes `36..39` overwrite live `salt[4]`


Why I believe this should be accepted:


- the overwrite is in the real current-head `OW` helper used by inline inbound
session create/update
- the destination is a fixed in-object field followed by a live adjacent member
- the bug does not depend on a crash or sanitizer output
- later `-EINVAL` does not undo the earlier write


The local proof results for the narrow case are:


- `distance_cipher_key_to_w8=32`
- `distance_cipher_key_to_salt=36`
- `advertised_aes_gmac_key_max=32`
- `provided_key_len=40`
- `returned=-22`
- `overflow_bytes_into_w8=8`
- `overflow_bytes_into_salt=4`
- `w8_u64_hex=4242424242424242`
- `salt_prefix_hex=42424242`
- `guard_unchanged=1`


Suggested fix:


1. Enforce `AES_GMAC` key length before `cnxk_ow_ipsec_inb_sa_fill()` is called
on the inline path.
2. Add a direct `length <= sizeof(cipher_key)` guard before the `memcpy()`.
3. Reuse the same crypto-length verification logic across the inline and
non-inline `cnxk` IPsec implementations.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to