From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2B1B833A71B for ; Mon, 3 Aug 2026 08:33:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785746021; cv=none; b=tgt4WHKoeoKu7+1bFiGVKgeZxYvDv+I55vGRjA0q7o3PxdTXxqxkZCzqOMrH13OTI0QrSmQ+LI9o1Ybku/Bf/cxz+CETzAsLU9IdMMnX2BjWpkLUsq+HCNy8sm+ViOh1iAug0IBC/xmPzlgDh2kexTehjbgmUxEa/YZ9/LqvtmI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785746021; c=relaxed/simple; bh=lTbHoz+GMfXEZM6JvS5ELuUO2I/+3aS/GrJxIcVMKTo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DY/Tt8UMwVGEuWsPOiLQrQYA6heRb/sP6/Vv8ktFkO0L0ybpGGJ6dpOyHiWYMUsD/TS+CBnbhAljqhrB1ukZ9lLg+w0E/N56EL/2YAXM/zIrDmlXWhGYCaCijXrRCA3TF7N9iVUfe9N5FZbiUpsWDIX+7XJlbCpLKsCiu8+1qM4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=iJDrKYpX; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="iJDrKYpX" Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 672Llqqc291117 for ; Mon, 3 Aug 2026 08:33:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=B3VxU7l8FDB0bxu9O qEHVDlyrteRXtTKy0AztCBxzxk=; b=iJDrKYpXLIt/RoQXvNX3+scLelkuyGwph asSAIPTM4i/jgv33xBDi+qowMRTtXXN6xPf2dp23lgJyjyv3hKGoNJHDTMcFEWwV ilPh6VdTt6OpGVYVhlKfwnZDvQtNbcKCvCneqZhKu1csiOT1+FhangJLMQZPfhDn 8sLtuAouzj3ZtCmRSZvIRq1WQVQUgAaVQAh0XSmniqGm8+BY6PEc7W3ox/x7jTMy 1KIwSaK1batb2AeZSs7vCSBE5oo2pBmQ6ZVxy9jJ6Rcy5JgDcDGVbBjEYSh0rF/h laocWq/hU5+1akdkVPim/Y5TaachBLEjKCxDWJBDfdwVti+Tn7B7w== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8eufd5a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 03 Aug 2026 08:33:38 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 6738QJYp006496 for ; Mon, 3 Aug 2026 08:33:38 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsugvvk4f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 03 Aug 2026 08:33:38 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (smtpav02.fra02v.mail.ibm.com [10.20.54.101]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 6738XYj428311920 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 08:33:34 GMT Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2216720063; Mon, 3 Aug 2026 08:33:34 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 008E32005A; Mon, 3 Aug 2026 08:33:34 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav02.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 08:33:33 +0000 (GMT) From: Harald Freudenberger To: dengler@linux.ibm.com, fcallies@linux.ibm.com, ifranzki@linux.ibm.com Cc: freude@linux.ibm.com, linux-s390@vger.kernel.org, Heiko Carstens , Vasily Gorbik , Alexander Gordeev Subject: [PATCH v11 4/5] s390/zcrypt: Improve EP11 CPRB domain handling with ASN.1 parsing Date: Mon, 3 Aug 2026 10:33:37 +0200 Message-ID: <20260803083339.212885-5-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803083339.212885-1-freude@linux.ibm.com> References: <20260803083339.212885-1-freude@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-s390@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: L7j7BV2j0OL64qg0kxfew_OzpHpvjL-C X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDA3MiBTYWx0ZWRfX2JoQ3QnacHFU FrtQ7aef3fYpSVN16a9qSvjaKxtDLkwz+skhf5sZtpJt0900qZO1YhzGLQhQA3PsRTDj+RbRWKV l+HMXOdPSLe+/YWzCehvnDRZxn8nX5M= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDA3MiBTYWx0ZWRfX42IGasQqE9Sn DMdYr9bvNhJAUmQ0zEv5btbKStpQug8F2fE4pdH1DznDAIDoqnS+9Qh3fvwJF+4KG7VTslbSXUd JjEAU9eiSSytmVvpSGuL0cgj02c8gP+WVhYZR3/Vcu/hTL9EHxF2wHYpfvltGSNg1PEvCuxkNFB P2UywCe6e96eGuW82F59gL/3VOO10rq8sr7CGVDSJFRjXIzuVken/Dh0SAy+ffu0kh9bkvpw7PN DuFO2t5kIN1sahJLiTFgwxTTF5Y66LcWT9x0ssZ97BK4iXbNg5gckfgxHUu/2kd+lk18cNI2Wc7 9v2mkEEVLJ17Va/ns8GqpcDujL8GpYW7xrPFYSOa4KjvvyEqgEld1uJhve/HxQduX9+8zi5T9eX lnMh+Qzt0GofKZREM0LCQcewq79qbSVxaVnEANOao4FD9u3ttrLqYw8q4HY6so0jkTXorrlZlg/ iTQkHA2ePt8P5Wnp41Q== X-Proofpoint-GUID: L7j7BV2j0OL64qg0kxfew_OzpHpvjL-C X-Authority-Analysis: v=2.4 cv=KfzidwYD c=1 sm=1 tr=0 ts=6a705262 cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=VwQbUJbxAAAA:8 a=hoYYr1_72z9RSZTYHFsA:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-02_06,2026-07-30_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 suspectscore=0 malwarescore=0 adultscore=0 clxscore=1015 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030072 The zcrypt_msgtype6_send_ep11_cprb() function uses fragile struct overlays to access and modify the domain field in the EP11 CPRB payload, creating maintainability and security concerns: 1. Struct overlay approach (pld_hdr) assumes fixed payload structure and doesn't validate the actual ASN.1 encoding. 2. Complex length format detection logic is error-prone and doesn't properly validate bounds at each parsing step. 3. Direct struct member access bypasses proper ASN.1 validation. Fix by replacing struct overlays with explicit ASN.1 parsing that validates each field (payload tag/length, function tag/length/value, optional domain tag/length/value) with proper bounds checking at every step. Add asn1_int_encode() helper function to safely write integer values with correct endianness conversion. This makes the code consistent with the validation pattern introduced with the rework of the xcrb_msg_to_type6_ep11cprb_msgx() function. Fixes: e2c6d91eb8b1 ("s390/zcrypt: Rework domain processing within zcrypt device driver") Signed-off-by: Harald Freudenberger Cc: stable@vger.kernel.org # 7.1+ --- drivers/s390/crypto/zcrypt_msgtype6.c | 127 +++++++++++++++++++------- 1 file changed, 96 insertions(+), 31 deletions(-) diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index 7e1f76c935ee..e79e68b4dd41 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c @@ -1226,6 +1226,28 @@ int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb, func_code, domain); } +/* + * Simple asn1 int writer/encoder helper function + * Returns number of bytes processed or < 0 on failure + * Only accepts int length values of 1, 2 or 4. + */ +static inline int asn1_int_encode(u8 *buf, size_t intlen, u32 u) +{ + switch (intlen) { + case 1: + *buf = (u8)u; + return 1; + case 2: + put_unaligned_be16((u16)u, buf); + return 2; + case 4: + put_unaligned_be32((u32)u, buf); + return 4; + default: + return -EINVAL; + } +} + /* * The request distributor calls this function if it picked the CEX4P * device to handle a send_ep11_cprb request. @@ -1238,51 +1260,94 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue * struct ap_message *ap_msg) { int rc; - unsigned int lfmt; struct ap_response_type *resp_type = &ap_msg->response; struct { struct type6_hdr hdr; struct ep11_cprb cprbx; - unsigned char pld_tag; /* fixed value 0x30 */ - unsigned char pld_lenfmt; /* payload length format */ } __packed * msg = ap_msg->msg; - struct pld_hdr { - unsigned char func_tag; /* fixed value 0x4 */ - unsigned char func_len; /* fixed value 0x4 */ - unsigned int func_val; /* function ID */ - unsigned char dom_tag; /* fixed value 0x4 */ - unsigned char dom_len; /* fixed value 0x4 */ - unsigned int dom_val; /* domain id */ - } __packed * payload_hdr = NULL; /* * The target domain field within the cprb body/payload block will be * replaced by the usage domain for non-management commands only. * Therefore we check the first bit of the 'flags' parameter for * management command indication. - * 0 - non management command - * 1 - management command */ - if (!((msg->cprbx.flags & 0x80) == 0x80)) { - msg->cprbx.target_id = (unsigned int) - AP_QID_QUEUE(zq->queue->qid); - - if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/ - switch (msg->pld_lenfmt & 0x03) { - case 1: - lfmt = 2; - break; - case 2: - lfmt = 3; - break; - default: + if (!(msg->cprbx.flags & 0x80)) { + int i, offs = 0; + size_t pld_len; + u8 *pld; + u32 u; + + /* update target field in ep11_cprb */ + msg->cprbx.target_id = (u32)AP_QID_QUEUE(zq->queue->qid); + + /* ptr and length to payload */ + pld = ap_msg->msg + + sizeof(struct type6_hdr) + sizeof(struct ep11_cprb); + pld_len = msg->cprbx.payload_len; + if (pld_len < MIN_EP11_PAYLOAD_SIZE) + return -EINVAL; + + /* + * Parse the asn1 payload, at least we have + * pld tag (1 octet) + * payload length (1-5 octets) + * function tag (1 octet) + * function length (1-5 octets) + * function value (1-4 octets) + * ----- optional fields ----- + * domain tag (1 octet) + * domain length (1-5 octets) + * domain value (1-4 octets) + * ... maybe much more data ... + */ + + /* payload tag */ + if (pld[offs++] != 0x30) + return -EINVAL; + /* payload length field */ + i = asn1_length_decode(pld + offs, pld_len - offs, &u); + if (i < 0) + return -EINVAL; + offs += i; + if (offs >= pld_len || u > pld_len - offs) + return -EINVAL; + /* function tag */ + if (pld[offs++] != 0x04) + return -EINVAL; + /* function length */ + if (offs >= pld_len) + return -EINVAL; + i = asn1_length_decode(pld + offs, pld_len - offs, &u); + if (i < 0) + return -EINVAL; + offs += i; + if (u > pld_len - offs) + return -EINVAL; + /* skip over the function value */ + offs += u; + /* is there some payload left which could hold a domain value ? */ + if (offs < pld_len && pld_len - offs >= 3) { + /* domain tag */ + if (pld[offs++] != 0x04) return -EINVAL; - } - } else { - lfmt = 1; /* length format #1 */ + /* domain length */ + i = asn1_length_decode(pld + offs, pld_len - offs, &u); + if (i < 0) + return -EINVAL; + offs += i; + if (offs >= pld_len || u > pld_len - offs) + return -EINVAL; + /* + * pld[offs] is now at the start of the domain value + * with the value sprawled in u octets. + */ + i = asn1_int_encode(pld + offs, u, + AP_QID_QUEUE(zq->queue->qid)); + if (i < 0) + return -EINVAL; + offs += i; } - payload_hdr = (struct pld_hdr *)((&msg->pld_lenfmt) + lfmt); - payload_hdr->dom_val = AP_QID_QUEUE(zq->queue->qid); } /* -- 2.43.0