Re: [PATCH v10 2/5] s390/zcrypt: Improve CCA CPRB length and overflow checks
Holger Dengler <[email protected]> Fri, 31 Jul 2026 11:49:36 +0200
| Newsgroups | dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-s390 |
|---|---|
| Message-ID | <[email protected]> |
On 7/30/26 16:48, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider: > > New issues: > - [Medium] Uninitialized alignment padding bytes may be read during function code extraction in `xcrb_msg_to_type6cprb_msgx`. Valid finding, but already handled by patch 5/5 in this series. > Pre-existing issues: > - [Critical] A 64-bit integer overflow in `xcrb_msg_to_type6_ep11cprb_msgx` allows a massive `req_len` to bypass the buffer size check. > - [High] The EP11 request path lacks minimum size validation, leading to uninitialized kernel memory access. > - [High] A user can bypass administrative domain permission checks by setting the target domain to AUTOSEL_DOM (0xFFFF). These pre-existing findings will be analyzed and - if valid - covered by a separate series. > -- > > --- Patch [2]: [PATCH v10 2/5] s390/zcrypt: Improve CCA CPRB length and overflow checks --- > commit 168ea93b9d93d40b4d0625f5a9d932544117496a > Author: Harald Freudenberger <[email protected]> > > s390/zcrypt: Improve CCA CPRB length and overflow checks > > This patch improves input validation in the xcrb_msg_to_type6cprb_msgx > function. It uses size_t for length calculations, adds bounds checks after > alignment, validates the minimum control block size, and detects overflow > in sum calculations. > >> diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c >> --- a/drivers/s390/crypto/zcrypt_msgtype6.c >> +++ b/drivers/s390/crypto/zcrypt_msgtype6.c > > [ ... ] > >> @@ -404,8 +395,8 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg, >> xcrb->request_control_blk_addr, >> xcrb->request_control_blk_length)) >> return -EFAULT; >> - if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > >> - xcrb->request_control_blk_length) >> + /* copy subfunction code into AP msg type 6 function code field */ >> + if (msg->cprbx.cprb_len > req_cblen - sizeof(msg->hdr.function_code)) > > [Severity: Medium] > Can this relaxed bounds check result in reading uninitialized alignment > padding? > > If a userspace caller sends a CCA ioctl where > xcrb->request_control_blk_length is not a multiple of 4 (for example, 21), > the z_copy_from_user() call copies exactly 21 bytes. Up to 3 bytes of > padding might be left uninitialized. > > Because the check now compares against req_cblen instead of > xcrb->request_control_blk_length, could a crafted cprbx.cprb_len (e.g., 22) > pass this validation and point into the uninitialized padding area, allowing > the subsequent memcpy() to read uninitialized kernel heap memory into > msg->hdr.function_code? > >> return -EINVAL; >> function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; >> memcpy(msg->hdr.function_code, function_code, > > [ ... ] > > > While reviewing these length check improvements, I also noticed a few > pre-existing issues in related code: > > > [Severity: Critical] > This isn't a bug introduced by this patch, but does > xcrb_msg_to_type6_ep11cprb_msgx() suffer from a similar 64-bit integer > overflow? > > In drivers/s390/crypto/zcrypt_msgtype6.c:xcrb_msg_to_type6_ep11cprb_msgx(): > > ap_msg->len = sizeof(struct type6_hdr) + CEIL4(xcrb->req_len); > if (ap_msg->len > ap_msg->bufsize) > return -EINVAL; > > If a userspace caller passes an ioctl with req_len equal to U64_MAX - 79, > CEIL4(req_len) evaluates to U64_MAX - 79. Adding sizeof(struct type6_hdr) > wraps the 64-bit value to 8, completely bypassing the buffer bounds check. > > Would the subsequent copy_from_user() then zero-fill the kernel heap on > failure and cause memory corruption? > > > [Severity: High] > This is a pre-existing issue, but the EP11 request path seems to lack the > minimum size validation that this patch adds to the CCA path. > > In drivers/s390/crypto/zcrypt_msgtype6.c:xcrb_msg_to_type6_ep11cprb_msgx(): > > if (z_copy_from_user(userspace, msg->userdata, > (char __force __user *)xcrb->req, xcrb->req_len)) { > > If an attacker submits an EP11 ioctl with a small req_len (e.g., 4 bytes), > the kernel copies only 4 bytes. Could the function then read EP11 structure > fields such as msg->pld_lenfmt and msg->cprbx.flags from uninitialized > memory to determine function codes and domains? > > > [Severity: High] > This isn't a bug introduced by this patch, but looking at the domain > permissions, is there a way to bypass administrative checks? > > In drivers/s390/crypto/zcrypt_api.c:_zcrypt_send_cprb(): > > if (perms != &ap_perms && domain < AP_DOMAINS) { > if (ap_msg.flags & AP_MSG_FLAG_ADMIN) { > if (!test_bit_inv(domain, perms->adm)) { > > And similarly in _zcrypt_send_ep11_cprb(): > > if (perms != &ap_perms && domain < AUTOSEL_DOM) { > if (ap_msg.flags & AP_MSG_FLAG_ADMIN) { > if (!test_bit_inv(domain, perms->adm)) { > > If a user submits a CPRBX or EP11 request containing an administrative > command and sets the embedded domain field to 0xFFFF (AUTOSEL_DOM), the > condition domain < AP_DOMAINS evaluates to false. > > Does this cause the administrative permission check to be completely skipped, > allowing a user with only usage privileges to execute administrative > commands on that domain? > -- Mit freundlichen Grüßen / Kind regards Holger Dengler