Re: [PATCH v4 1/1] s390/zcrypt: Fix buffer over-read in cca_cipher2protkey
Harald Freudenberger <[email protected]> Wed, 29 Jul 2026 15:49:37 +0200
| Newsgroups | dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-s390 |
|---|---|
| Message-ID | <[email protected]> |
On 2026-07-29 14:06, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 3 potential > issue(s) to consider: > > Pre-existing issues: > - [Critical] Unbounded token length allows heap buffer overflow in > `cca_cipher2protkey` and `cca_ecc2protkey` when building CPRB > requests. > - [High] Unvalidated firmware-provided length in `cca_gencipherkey` > can lead to a massive out-of-bounds read and memory leak to > user-space. > - [High] Unbounded `t->len` in `_ip_cprb_helper` can cause a heap > buffer overflow when copying a response from the crypto card. > -- > > --- Patch [1]: [PATCH v4 1/1] s390/zcrypt: Fix buffer over-read in > cca_cipher2protkey --- > commit df110319f8dcc4a61962c0699f5ad1038f1b9085 > Author: Harald Freudenberger <[email protected]> > > s390/zcrypt: Fix buffer over-read in cca_cipher2protkey > > This commit adds validation of the actual key buffer size and token > length > fields in the cca_check_sec*token functions. It prevents buffer > over-reads > and under-runs that could lead to kernel crashes or memory exposure. > >> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c >> b/drivers/s390/crypto/zcrypt_ccamisc.c >> --- a/drivers/s390/crypto/zcrypt_ccamisc.c >> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c > [ ... ] >> @@ -936,23 +975,28 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 >> keybitsize, u32 keygenflags, >> } >> >> /* and some checks on the generated key */ >> + t = (struct cipherkeytoken *)prepparm->kb.tlv1.gen_key; >> + if (prepparm->kb.tlv1.len < 2 * sizeof(uint16_t) + sizeof(*t)) { >> + rc = -EIO; >> + goto out; >> + } >> + keybuflen = prepparm->kb.tlv1.len - 2 * sizeof(uint16_t); >> rc = cca_check_secaescipherkey(zcrypt_dbf_info, DBF_ERR, >> prepparm->kb.tlv1.gen_key, >> - keybitsize, 1); >> + keybuflen, keybitsize, 1); >> if (rc) { >> rc = -EIO; >> goto out; >> } >> >> /* copy the generated vlsc key token */ >> - t = (struct cipherkeytoken *)prepparm->kb.tlv1.gen_key; >> if (keybuf) { >> - if (*keybufsize >= t->len) >> - memcpy(keybuf, t, t->len); >> + if (*keybufsize >= keybuflen) >> + memcpy(keybuf, t, keybuflen); > > [Severity: High] > This isn't a bug introduced by this patch, but can an unvalidated > firmware > response lead to an out-of-bounds read here? > > The hardware returns a response containing a tlv1.len field which is > used to calculate keybuflen. If a compromised or buggy crypto card > firmware > sets an abnormally large tlv1.len, does this memcpy read past the > 512-byte > parameter block into adjacent kernel heap memory and leak it to > userspace? > > Could we add a bounds check against the 512-byte allocation limit > before > performing the memcpy? > >> else >> rc = -EINVAL; >> } >> - *keybufsize = t->len; >> + *keybufsize = keybuflen; >> >> out: > > [Severity: Critical] > This is a pre-existing issue, but I noticed a potential regression > involving > buffer overflows in cca_cipher2protkey and cca_ecc2protkey when > building > request blocks. > > In cca_cipher2protkey, if a user issues an ioctl providing a malicious > token > with a large len field, does this overwrite the 512-byte buffer? > > drivers/s390/crypto/zcrypt_ccamisc.c:cca_cipher2protkey() { > ... > preqparm->kb.len = keytoklen + 3 * sizeof(uint16_t); > preqparm->kb.cca_key_token_len = keytoklen + 2 * sizeof(uint16_t); > memcpy(preqparm->kb.cca_key_token, ckey, keytoklen); > ... > } > > The cca_check_secaescipherkey function ensures t->len is less than or > equal > to keysize, where keysize is the user-provided size that can be up to > 8192 bytes. If keytoklen is larger than the 512-byte limit, could this > memcpy > overwrite the allocation? > > A similar pattern exists in cca_ecc2protkey: > > drivers/s390/crypto/zcrypt_ccamisc.c:cca_ecc2protkey() { > ... > preqparm->kb.len = keylen + 3 * sizeof(uint16_t); > preqparm->kb.cca_key_token_len = keylen + 2 * sizeof(uint16_t); > memcpy(preqparm->kb.cca_key_token, key, keylen); > ... > } > > [Severity: High] > This is also a pre-existing issue, but I observed a similar unbounded > length > usage in _ip_cprb_helper that might cause an out-of-bounds read and > write. > > When copying a response from the crypto card, the t->len field is > trusted > directly from the hardware: > > drivers/s390/crypto/zcrypt_ccamisc.c:_ip_cprb_helper() { > ... > t = (struct cipherkeytoken *)prepparm->kb.tlv1.key_token; > memcpy(key_token, t, t->len); > *key_token_size = t->len; > ... > } > > If the hardware provides a malformed response with a large t->len, does > this > memcpy read out-of-bounds from the 512-byte parameter block? > > Additionally, if this corrupted length is returned to > cca_clr2cipherkey, > could it be used to write back into a new 512-byte request block and > cause > another overflow? These issues are valid but are already addressed with another patch series.