From: Holger Dengler <dengler@linux.ibm.com>
To: freude@linux.ibm.com
Cc: fcallies@linux.ibm.com, ifranzki@linux.ibm.com,
linux-s390@vger.kernel.org, Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>
Subject: Re: [PATCH v10 2/5] s390/zcrypt: Improve CCA CPRB length and overflow checks
Date: Mon, 3 Aug 2026 10:01:32 +0200 [thread overview]
Message-ID: <07a1fd51-1ebc-4d7a-b8cb-9159107f9e22@linux.ibm.com> (raw)
In-Reply-To: <3c799af0f50b5047ce31bc03606656a0@linux.ibm.com>
On 8/3/26 09:55, Harald Freudenberger wrote:
> On 2026-07-31 12:35, Holger Dengler wrote:
>> On 7/30/26 16:15, Harald Freudenberger wrote:
>>> The xcrb_msg_to_type6cprb_msgx() function lacks proper input
>>> validation, creating security vulnerabilities:
>>> 1. Integer overflow after CEIL4 alignment: Signed int variables could
>>> overflow during 4-byte boundary alignment, causing undersized
>>> buffer allocations or incorrect bounds checking.
>>> 2. Missing minimum size validation: The CPRBX structure is copied from
>>> userspace without verifying sufficient buffer length. Undersized
>>> buffers cause uninitialized memory access when reading structure
>>> fields like cprbx.cprb_len and cprbx.domain.
>>> 3. Arithmetic overflow in sum calculations: Adding control block and
>>> data block sizes could overflow, bypassing size checks and enabling
>>> buffer overflows.
>>>
>>> Fix by using size_t for length calculations, adding U32_MAX boundary
>>> checks after alignment, validating minimum control block size before
>>> copying from userspace, and detecting sum calculation overflows.
>>>
>>> Fixes: e2c6d91eb8b1 ("s390/zcrypt: Rework domain processing within
>>> zcrypt device driver")
>>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>>> Cc: stable@vger.kernel.org # 7.1+
>>> ---
>>> drivers/s390/crypto/zcrypt_msgtype6.c | 78 +++++++++++++--------------
>>> 1 file changed, 36 insertions(+), 42 deletions(-)
>>>
>>> diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/
>>> crypto/zcrypt_msgtype6.c
>>> index 40f72cdf284d..fb37e28c8242 100644
>>> --- a/drivers/s390/crypto/zcrypt_msgtype6.c
>>> +++ b/drivers/s390/crypto/zcrypt_msgtype6.c
>>> @@ -342,49 +342,40 @@ static int xcrb_msg_to_type6cprb_msgx(bool
>>> userspace, struct ap_message *ap_msg,
>>> };
>>> } __packed * msg = ap_msg->msg;
>>>
>>> - int rcblen = CEIL4(xcrb->request_control_blk_length);
>>> - int req_sumlen, resp_sumlen;
>>> - char *req_data = ap_msg->msg + sizeof(struct type6_hdr) + rcblen;
>>> - char *function_code;
>>> + size_t req_cblen, rep_cblen, req_sumlen, rep_sumlen;
>>> + char *function_code, *req_data;
>>>
>>> - if (CEIL4(xcrb->request_control_blk_length) <
>>> - xcrb->request_control_blk_length)
>>> - return -EINVAL; /* overflow after alignment*/
>>> -
>>> - /* length checks */
>>> + /* request length and overflow checks */
>>> + if (xcrb->request_control_blk_length < sizeof(struct CPRBX))
>>> + return -EINVAL;
>>> + req_cblen = CEIL4((size_t)xcrb->request_control_blk_length);
>>> + if (req_cblen > U32_MAX)
>>> + return -EINVAL;
>>> ap_msg->len = sizeof(struct type6_hdr) +
>>> - CEIL4(xcrb->request_control_blk_length) +
>>> - xcrb->request_data_length;
>>> + req_cblen + xcrb->request_data_length;
>>> if (ap_msg->len > ap_msg->bufsize)
>>> return -EINVAL;
>>> -
>>> - /*
>>> - * Overflow check
>>> - * sum must be greater (or equal) than the largest operand
>>> - */
>>> - req_sumlen = CEIL4(xcrb->request_control_blk_length) +
>>> - xcrb->request_data_length;
>>> - if ((CEIL4(xcrb->request_control_blk_length) <=
>>> - xcrb->request_data_length) ?
>>> + req_sumlen = req_cblen + xcrb->request_data_length;
>>
>> The req_sumlen is also used for the calculation of ap_msg->len, right?
>> Why not moving the req_sumlen calculation and checks up and use it there?
>>
>> req_sumlen = req_cblen + xcrb->request_data_length;
>> if (req_sumlen > U32_MAX)
>> [...]
>> ap_msg->len = sizeof(struct type6_hdr) + req_sumlen;
>> if (ap_msg->len > ap_msg->bufsize)
>> [...]
>>
>
> Done
>
>> And another question about the aligned buffer lengths:
>> We have the request-control-block, followed by the request-data. Is only
>> the request-control-block required to be 4-byte aligned or also the
>> request-data, or only both together (request-control-block and -data)?
>>
>> Lets assume, request-control-block and -data length are both not 4-byte
>> alligned. Do we need the padding between the cprb and the data or at the
>> end of both blocks or only after data?
>>
>> Example:
>> req-ctrl-blk: length 5
>> req-data: length 5
>>
>> With only cprb padded (--> req_sumlen: 13)
>> | req-ctrl-blk[5] | pad[3] | req-data[5] |
>>
>>
>> With both padded separately (--> req_sumlen: 16)
>> | req-ctrl-blk[5] | pad[3] | req-data[5] | pad[3] |
>>
>> With both padded together (--> req_sumlen: 12)
>> | req-ctrl-blk[5] | req-data[5] | pad[2] |
>>
>>
>
> I can only deduce this from the existing code.
> But my suggestion is:
> for a control block only:
> ctrl-block | pad
> control + data block:
> ctrl-block | pad | data-block | pad
> in a way that the start of each block is aligned to a 4 byte
> boundary AND can be processed in hunks of 4 bytes (double word).
> So we should make sure that the memory backing up an
> ap message is allocated with respect to the padding.
Ok.
>
>>> + if (req_sumlen > U32_MAX)
>>> + return -EINVAL;
>>> + if (req_cblen <= xcrb->request_data_length ?
>>> req_sumlen < xcrb->request_data_length :
>>> - req_sumlen < CEIL4(xcrb->request_control_blk_length)) {
>>> + req_sumlen < req_cblen) {
>>> return -EINVAL;
>>> }
>>>
>>> - if (CEIL4(xcrb->reply_control_blk_length) <
>>> - xcrb->reply_control_blk_length)
>>> - return -EINVAL; /* overflow after alignment*/
>>> -
>>> - /*
>>> - * Overflow check
>>> - * sum must be greater (or equal) than the largest operand
>>> - */
>>> - resp_sumlen = CEIL4(xcrb->reply_control_blk_length) +
>>> - xcrb->reply_data_length;
>>> - if ((CEIL4(xcrb->reply_control_blk_length) <=
>>> - xcrb->reply_data_length) ?
>>> - resp_sumlen < xcrb->reply_data_length :
>>> - resp_sumlen < CEIL4(xcrb->reply_control_blk_length)) {
>>> + /* reply length and overflow checks */
>>> + if (xcrb->reply_control_blk_length < sizeof(struct CPRBX))
>>> + return -EINVAL;
>>> + rep_cblen = CEIL4((size_t)xcrb->reply_control_blk_length);
>>> + if (rep_cblen > U32_MAX)
>>> + return -EINVAL;
>>> + rep_sumlen = rep_cblen + xcrb->reply_data_length;
>> [...]
>>
>> Before this change, resp_sumlen was 4-bate aligned, now only rep_cblen
>> is aligned. Is thsi change intended? (the question is similar to the one
>> above)
>
> There is no difference in the way how the reply sizes and limits are
> calculated to the way how the request sizes and limits are computed.
> And there should not be any difference.
Ok, than you can add my R-b to this patch.
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>>
>> The rest looks good to me.
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
next prev parent reply other threads:[~2026-08-03 8:01 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 14:15 [PATCH v10 0/5] Improve code in zcrypt msg type 6 handling Harald Freudenberger
2026-07-30 14:15 ` [PATCH v10 1/5] s390/zcrypt: Fix CPRB memory allocation in zcrypt misc code Harald Freudenberger
2026-07-30 14:25 ` sashiko-bot
2026-07-31 8:16 ` Holger Dengler
2026-07-30 14:15 ` [PATCH v10 2/5] s390/zcrypt: Improve CCA CPRB length and overflow checks Harald Freudenberger
2026-07-30 14:48 ` sashiko-bot
2026-07-31 9:49 ` Holger Dengler
2026-07-31 10:35 ` Holger Dengler
2026-08-03 7:55 ` Harald Freudenberger
2026-08-03 8:01 ` Holger Dengler [this message]
2026-07-30 14:15 ` [PATCH v10 3/5] s390/zcrypt: Improve EP11 " Harald Freudenberger
2026-07-30 14:35 ` sashiko-bot
2026-07-30 14:15 ` [PATCH v10 4/5] s390/zcrypt: Improve EP11 CPRB domain handling with ASN.1 parsing Harald Freudenberger
2026-07-30 14:29 ` sashiko-bot
2026-07-30 14:43 ` Harald Freudenberger
2026-07-30 14:15 ` [PATCH v10 5/5] s390/zcrypt: Pad trailing CCA or EP11 message with zeros Harald Freudenberger
2026-07-30 14:29 ` sashiko-bot
2026-07-31 9:15 ` Holger Dengler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=07a1fd51-1ebc-4d7a-b8cb-9159107f9e22@linux.ibm.com \
--to=dengler@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=fcallies@linux.ibm.com \
--cc=freude@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=ifranzki@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox