Skip to content

Commit 4cfca53

Browse files
hfreudehcahca
authored andcommitted
s390/zcrypt: fix reply buffer calculations for CCA replies
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 two fields exceeds the AP bus limit for this card the first 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. Investigations showed 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@linux.ibm.com> Reviewed-by: Holger Dengler <dengler@linux.ibm.com> Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 1f7e906 commit 4cfca53

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

drivers/s390/crypto/zcrypt_msgtype6.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,23 +1101,36 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
11011101
struct ica_xcRB *xcrb,
11021102
struct ap_message *ap_msg)
11031103
{
1104-
int rc;
11051104
struct response_type *rtype = ap_msg->private;
11061105
struct {
11071106
struct type6_hdr hdr;
11081107
struct CPRBX cprbx;
11091108
/* ... more data blocks ... */
11101109
} __packed * msg = ap_msg->msg;
1111-
1112-
/*
1113-
* Set the queue's reply buffer length minus 128 byte padding
1114-
* as reply limit for the card firmware.
1115-
*/
1116-
msg->hdr.fromcardlen1 = min_t(unsigned int, msg->hdr.fromcardlen1,
1117-
zq->reply.bufsize - 128);
1118-
if (msg->hdr.fromcardlen2)
1119-
msg->hdr.fromcardlen2 =
1120-
zq->reply.bufsize - msg->hdr.fromcardlen1 - 128;
1110+
unsigned int max_payload_size;
1111+
int rc, delta;
1112+
1113+
/* calculate maximum payload for this card and msg type */
1114+
max_payload_size = zq->reply.bufsize - sizeof(struct type86_fmt2_msg);
1115+
1116+
/* limit each of the two from fields to the maximum payload size */
1117+
msg->hdr.fromcardlen1 = min(msg->hdr.fromcardlen1, max_payload_size);
1118+
msg->hdr.fromcardlen2 = min(msg->hdr.fromcardlen2, max_payload_size);
1119+
1120+
/* calculate delta if the sum of both exceeds max payload size */
1121+
delta = msg->hdr.fromcardlen1 + msg->hdr.fromcardlen2
1122+
- max_payload_size;
1123+
if (delta > 0) {
1124+
/*
1125+
* Sum exceeds maximum payload size, prune fromcardlen1
1126+
* (always trust fromcardlen2)
1127+
*/
1128+
if (delta > msg->hdr.fromcardlen1) {
1129+
rc = -EINVAL;
1130+
goto out;
1131+
}
1132+
msg->hdr.fromcardlen1 -= delta;
1133+
}
11211134

11221135
init_completion(&rtype->work);
11231136
rc = ap_queue_message(zq->queue, ap_msg);

0 commit comments

Comments
 (0)