Re: [PATCH v7 1/5] s390/zcrypt: Fix CPRB memory allocation in zcrypt misc code

Harald Freudenberger <[email protected]> Wed, 29 Jul 2026 15:56:03 +0200
Newsgroups dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-s390
Message-ID <[email protected]>
On 2026-07-29 12:15, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential
> issue(s) to consider:
> 
> New issues:
> - [Medium] Incomplete memory scrubbing in CPRB free functions leaves
> padding bytes unzeroed.
> 
> Pre-existing issues:
> - [High] Information leak of uninitialized kernel heap memory to AP
> hardware due to unpadded EP11 request lengths.
> - [High] Incomplete fix in EP11 CPRB memory allocation causes valid
> 4-byte padded hardware replies to be rejected with -EMSGSIZE.
> --
> 
> --- Patch [1]: [PATCH v7 1/5] s390/zcrypt: Fix CPRB memory allocation
> in zcrypt misc code ---
> commit cba05c09d2194f550fb91ddbd8234cd389b1848a
> Author: Harald Freudenberger <[email protected]>
> 
> s390/zcrypt: Fix CPRB memory allocation in zcrypt misc code
> 
> This commit rounds up the memory allocation for CPRB structures to a
> multiple of 4 bytes. It ensures the base CPRB and parameter block are
> aligned to a 4-byte boundary, which is required by the zcrypt layer.
> 
>> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c 
>> b/drivers/s390/crypto/zcrypt_ccamisc.c
>> index 84936a795b956..0aa72593ae2bd 100644
>> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
>> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
>> @@ -231,6 +232,10 @@ EXPORT_SYMBOL(cca_check_sececckeytoken);
>>   * block, reply CPRB and reply param block and fill in values
>>   * for the common fields. Returns 0 on success or errno value
>>   * on failure.
>> + * It is guaranteed that request and a possible param block
>> + * are aligned to a 4 byte boundary. Furthermore if a param
>> + * block is used, the memory allocated for this is rounded up to
>> + * the next multiple of 4 bytes.
>>   */
>>  static int alloc_and_prep_cprbmem(size_t paramblen,
>>  				  u8 **p_cprb_mem,
>> @@ -239,7 +244,8 @@ static int alloc_and_prep_cprbmem(size_t 
>> paramblen,
>>  				  u32 xflags)
>>  {
>>  	u8 *cprbmem = NULL;
>> -	size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen;
>> +	size_t cprbplusparamblen =
>> +		ALIGN(sizeof(struct CPRBX), 4) + ALIGN(paramblen, 4);
> 
> [Severity: Medium]
> If the allocation size is rounded up here, do the corresponding
> free_cprbmem() functions need to be updated to clear the padded size?
> 
> For example, in drivers/s390/crypto/zcrypt_ccamisc.c:free_cprbmem():
> 
>     memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen));
> 
> And in drivers/s390/crypto/zcrypt_ep11misc.c:free_cprbmem():
> 
>     memzero_explicit(mem, sizeof(struct ep11_cprb) + payload_len);
> 
> Currently they use the unpadded lengths. Can this leave the padding 
> bytes
> unzeroed when freed, potentially leaking sensitive hardware response 
> data
> that spills into the padding?

Valid and will be addressed with version 8 of this patch series.

> 
> [ ... ]
> 
>> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c 
>> b/drivers/s390/crypto/zcrypt_ep11misc.c
>> index 3dda9589f2b95..e604c100ccce2 100644
>> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
>> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
>> @@ -355,21 +356,24 @@ EXPORT_SYMBOL(ep11_check_aes_key);
>> 
>>  /*
>>   * Allocate and prepare ep11 cprb plus additional payload.
>> + * It is guaranteed that the memory is aligned to a 4 byte boundary.
>> + * Furthermore the memory allocation is rounded up to the next
>> + * multiple of 4 bytes (with taking the payload_len into account).
>>   */
>>  static void *alloc_cprbmem(size_t payload_len, u32 xflags)
>>  {
>> -	size_t len = sizeof(struct ep11_cprb) + payload_len;
>> +	size_t memlen = ALIGN(sizeof(struct ep11_cprb) + payload_len, 4);
>>  	struct ep11_cprb *cprb = NULL;
>> 
>>  	if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
>> -		if (len <= CPRB_MEMPOOL_ITEM_SIZE)
>> +		if (memlen <= CPRB_MEMPOOL_ITEM_SIZE)
>>  			cprb = mempool_alloc_preallocated(cprb_mempool);
>>  	} else {
>> -		cprb = kmalloc(len, GFP_KERNEL);
>> +		cprb = kmalloc(memlen, GFP_KERNEL);
>>  	}
>>  	if (!cprb)
>>  		return NULL;
>> -	memset(cprb, 0, len);
>> +	memset(cprb, 0, memlen);
> 
> [Severity: High]
> This is a pre-existing issue, but since we are aligning EP11 lengths, 
> does
> the AP message creation leak uninitialized kernel memory?
> 
> In 
> drivers/s390/crypto/zcrypt_msgtype6.c:xcrb_msg_to_type6_ep11cprb_msgx(),
> the message length is rounded up:
> 
>     ap_msg->len = sizeof(struct type6_hdr) + CEIL4(xcrb->req_len);
> 
> But only the unpadded length is copied into the buffer:
> 
>     if (z_copy_from_user(userspace, msg->userdata, (char __force
> __user *)xcrb->req, xcrb->req_len))
> 
> Since drivers/s390/crypto/ap_bus.c:ap_init_apmsg() allocates the buffer
> without __GFP_ZERO:
> 
>     ap_msg->msg = kmalloc(maxmsgsize, GFP_KERNEL);
> 
> Can the padding gap between xcrb->req_len and CEIL4(xcrb->req_len) leak 
> up
> to 3 bytes of uninitialized kernel heap memory to the AP hardware?
> 

Addressed with patch #5 of this series.

> 
> [Severity: High]
> This is a pre-existing issue, but does aligning the memory allocation
> resolve the EMSGSIZE failures if prep_urb() still uses the unpadded 
> length?
> 
> In drivers/s390/crypto/zcrypt_ep11misc.c:prep_urb(), the unpadded 
> length
> is passed:
> 
>     u->resp_len = rep_len;
> 
> When the hardware replies with a 4-byte padded length,
> convert_type86_ep11_xcrb() in drivers/s390/crypto/zcrypt_msgtype6.c
> checks it against the unpadded resp_len:
> 
>     if (xcrb->resp_len < msg->fmt2.count1) {
>         pr_debug("resp_len %u < required %u => EMSGSIZE\n",
>                  (unsigned int)xcrb->resp_len, msg->fmt2.count1);
>         return -EMSGSIZE;
>     }
> 
> Does this cause valid padded hardware replies to be rejected with
> -EMSGSIZE for unaligned requests?
> 
>> 
>>  	cprb->cprb_len = sizeof(struct ep11_cprb);
>>  	cprb->cprb_ver_id = 0x04;

This may be valid but will eventually be covered with another patch 
outside of this series.