Linux s390 Architecture development
 help / color / mirror / Atom feed
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


  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