Re: [PATCH v2] s390/zcrypt: fix reply buffer calculations for CCA replies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 14/07/2023 16:36, Harald Freudenberger wrote:
> The length information for available buffer space for CCA
> replies is covered with two fields in the T6 header prepended
> on each CCA reply: fromcardlen1 and fromcardlen2. The sum of
> these both values must not exceed the AP bus limit for this
> card (24KB for CEX8, 12KB CEX7 and older) minus the always
> present headers.
> 
> The current code adjusted the fromcardlen2 value in case
> of exceeding the AP bus limit when there was a non-zero
> value given from userspace. Some tests now showed that this
> was the wrong assumption. Instead the userspace value given for
> this field should always be trusted and if the sum of the
> wo fields exceeds the AP bus limit for this card the first

typo: two

> field fromcardlen1 should be adjusted instead.
> 
> So now the calculation is done with this new insight in mind.
> Also some additional checks for overflow have been introduced
> and some comments to provide some documentation for future
> maintainers of this complicated calculation code.
> 
> Furthermore the 128 bytes of fix overhead which is used
> in the current code is not correct. Investications showed

typo: Investigations

> that for a reply always the same two header structs are
> prepended before a possible payload. So this is also fixed
> with this patch.
> 
> Signed-off-by: Harald Freudenberger <freude@xxxxxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx

With the typos fixed and the changes below
Reviewed-by: Holger Dengler <dengler@xxxxxxxxxxxxx>

> ---
>  drivers/s390/crypto/zcrypt_msgtype6.c | 45 ++++++++++++++++++++-------
>  1 file changed, 33 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
> index 247f0ad38362..5ac110669327 100644
> --- a/drivers/s390/crypto/zcrypt_msgtype6.c
> +++ b/drivers/s390/crypto/zcrypt_msgtype6.c
> @@ -551,6 +551,12 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
>   *
>   * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
>   */
> +struct type86_reply_hdrs {
> +	struct type86_hdr hdr;
> +	struct type86_fmt2_ext fmt2;
> +	/* ... payload may follow ... */
> +} __packed;
> +

There is already a `struct type86_fmt2_msg` in this file (line 329 ff.).

>  struct type86x_reply {
>  	struct type86_hdr hdr;
>  	struct type86_fmt2_ext fmt2;
> @@ -1101,23 +1107,38 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
>  				      struct ica_xcRB *xcrb,
>  				      struct ap_message *ap_msg)
>  {
> -	int rc;
> +	unsigned int reply_bufsize_minus_headers =
> +		zq->reply.bufsize - sizeof(struct type86_reply_hdrs);

I don't like this variable name. What about `max_payload_size`?

>  	struct response_type *rtype = ap_msg->private;
>  	struct {
>  		struct type6_hdr hdr;
>  		struct CPRBX cprbx;
>  		/* ... more data blocks ... */
>  	} __packed * msg = ap_msg->msg;
> -
> -	/*
> -	 * Set the queue's reply buffer length minus 128 byte padding
> -	 * as reply limit for the card firmware.
> -	 */
> -	msg->hdr.fromcardlen1 = min_t(unsigned int, msg->hdr.fromcardlen1,
> -				      zq->reply.bufsize - 128);
> -	if (msg->hdr.fromcardlen2)
> -		msg->hdr.fromcardlen2 =
> -			zq->reply.bufsize - msg->hdr.fromcardlen1 - 128;
> +	int rc, delta;
> +
> +	/* limit each of the two from fields to AP bus limit - headers */

I would also use "maximal payload size" here.
/* limit each of the two from fields to the maximum payload size */

> +	msg->hdr.fromcardlen1 = min_t(unsigned int,
> +				      msg->hdr.fromcardlen1,
> +				      reply_bufsize_minus_headers);
> +	msg->hdr.fromcardlen2 = min_t(unsigned int,
> +				      msg->hdr.fromcardlen2,
> +				      reply_bufsize_minus_headers);
> +
> +	/* calculate delta if the sum of both exceeds AP bus limit - headers */

dito:
/* calculate delta if the sum of both exceeds the maximum payload size */

> +	delta = msg->hdr.fromcardlen1 + msg->hdr.fromcardlen2
> +		- reply_bufsize_minus_headers;
> +	if (delta > 0) {
> +		/*
> +		 * Sum exceeds AP bus limit - headers, prune fromcardlen1

dito:
 * Sum exceeds the maximum payload size, prune fromcardlen1

> +		 * (always trust fromcardlen2)
> +		 */
> +		if (delta > msg->hdr.fromcardlen1) {
> +			rc = -EINVAL;
> +			goto out;
> +		}
> +		msg->hdr.fromcardlen1 -= delta;
> +	}
>  
>  	init_completion(&rtype->work);
>  	rc = ap_queue_message(zq->queue, ap_msg);
> @@ -1240,7 +1261,7 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
>  	 * as reply limit for the card firmware.
>  	 */
>  	msg->hdr.fromcardlen1 = zq->reply.bufsize -
> -		sizeof(struct type86_hdr) - sizeof(struct type86_fmt2_ext);
> +		sizeof(struct type86_reply_hdrs);
>  
>  	init_completion(&rtype->work);
>  	rc = ap_queue_message(zq->queue, ap_msg);

-- 
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@xxxxxxxxxxxxx



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux