CVE-2026-71227: Libkcapi: infinite loop denial of service in libkcapi _kcapi_aio_read_all() due to unhandled io_getevents() timeout return

Published Apr 26, 2026
·
Updated

A flaw was found in libkcapi. A local attacker can influence an application that uses the Asynchronous Input/Output (AIO) interface. By reusing an AIO-enabled handle after a prior completion error, the kcapiaioreadall() function can enter a non-terminating wait loop. This can lead to a persistent denial of service, making the affected application or thread unresponsive.

Other sources

AIONLYREPORT package: libkcapi-1.5.0-3.el10 ------ Summary: Denial of Service via Infinite Loop in AIO Read on Timeout: reuse of an AIO-enabled handle after a prior completion error can leave kcapiaioreadall() in a non-progress timeout loop and hang the caller indefinitely. Requirements to exploit: An attacker must be able to influence an application that uses the AIO interface from libkcapi-1.5.0-3.el10, initializes handles with KCAPIINITAIO, triggers at least one AIO completion error, and then reuses the same handle in a later AIO operation so that kcapiaioreadiov() waits for more completions than remain outstanding. Component affected: libkcapi-1.5.0-3.el10, lib/kcapi-kernel-if.c, kcapiaioreadall() and kcapiaioreadiov() Version affected: libkcapi-1.5.0-3.el10, when built with AIO support and exercised through handles initialized with KCAPIINITAIO Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - 5.1 (MEDIUM) AV:L - The available evidence establishes exploitability through a local process invoking the affected library AIO path; broader remote reachability depends on a consuming application and is not established here. AC:H - Triggering the flaw requires an AIO-enabled path, KCAPIINITAIO, at least one completion error, and later handle reuse with more requested completions than remain outstanding. PR:N - No privileges are required to invoke the affected API path. UI:N - No separate user interaction is required once attacker-controlled input reaches the affected AIO flow. S:U - The impact remains within the vulnerable process. C:N - No confidentiality impact is established. I:N - No integrity impact is established. A:H - The affected thread or request path can enter a non-terminating wait loop, causing a persistent denial of service. Impact: Moderate. Under Red Hat's severity guidance, this is more than Low because a successful trigger can reliably deny availability for an affected thread or operation. It is below Important because exploitability depends on the optional AIO interface, KCAPIINITAIO, and a specific error-and-reuse sequence that is not shown to be the default or broadly reachable deployment path. Embargo: no Reason: This is an availability-only issue in a configuration-dependent AIO code path with a practical workaround, so non-embargoed handling is appropriate. Acknowledgement: Aisle Research Vulnerability Details: In lib/kcapi-kernel-if.c, kcapiaioreadall() waits for toread completions but does not handle a timeout return of 0 from iogetevents(): c while (toread) { int rc = iogetevents(handle->aio.aioctx, 1, (long)toread, events, timeout); if (rc < 0) return rc; ... toread -= (uint32t)rc; } If iogetevents() times out and returns 0, toread is unchanged and the loop makes no progress. kcapiaioreadiov() can drive that condition while waiting for a busy IOCB slot: c while (cb->aiofildes) { struct timespec timeout = { .tvsec = 0, .tvnsec = 10000 }; ret = kcapiaioreadall(handle, iovlen, &timeout); if (ret < 0) return ret; } The available evidence indicates that, after an earlier AIO completion error causes kcapiaioreadall() to return before all slots are drained, a later reuse of the same handle can call kcapiaioreadall(handle, iovlen, &timeout) even when fewer completions can still arrive. Repeated timeout returns then leave the caller in a non-terminating wait loop. The demonstrated impact is denial of service through a stuck thread or operation; no confidentiality or integrity impact is established. Steps to reproduce: 1. Use a build with AIO enabled and initialize a handle with KCAPIINITAIO. 2. Call an AIO API such as kcapiaeaddecryptaio or kcapicipheraio with multiple IOVs and force at least one completion error, for example by supplying an invalid AEAD tag for one request. 3. Reuse the same handle for another AIO call where iovlen is greater than the number of still-completable prior events. 4. Observe kcapiaioreadiov() entering while (cb->aiofildes) and repeatedly calling kcapiaioreadall(handle, iovlen, &timeout). 5. Observe iogetevents(..., timeout) returning 0 repeatedly while kcapiaioreadall() does not reduce toread, leaving the thread stuck. Mitigation: Until a fixed package is available, avoid the affected AIO path where feasible. If AIO must be used, do not reuse a handle after any AIO completion error; destroy and reinitialize the handle before subsequent AIO operations. Deployments that do not require AIO should avoid initializing handles with KCAPIINITAIO. Proposed Fix: A minimal fix is to treat zero-completion timeouts as errors, clear IOCB slot state before returning the first completion error, and wait for only one completion while recycling a busy IOCB slot. diff diff --git a/lib/kcapi-kernel-if.c b/lib/kcapi-kernel-if.c @@ -426,6 +426,7 @@ int kcapiaioreadall(struct kcapihandle handle, sizet toread, while (toread) { + int firsterr = 0; int i; struct ioevent events[KCAPIAIOCONCURRENT]; int rc = iogetevents(handle->aio.aioctx, 1, (long)toread, @@ -433,18 +434,24 @@ int kcapiaioreadall(struct kcapihandle handle, sizet toread, if (rc < 0) return rc; + if (rc == 0) + return timeout ? -ETIMEDOUT : -EIO; for (i = 0; i < rc; i++) { struct iocb cb; - if (events[i].res < 0) { + if (events[i].res < 0 && !firsterr) + firsterr = (int)events[i].res; + if (events[i].res < 0) handle->aio.iocbret[events[i].data] = events[i].res; - return (int)events[i].res; - } - - cb = (struct iocb )(uintptrt)events[i].obj; - if (events[i].res > 0) + else if (events[i].res > 0) handle->aio.iocbret[events[i].data] = events[i].res; - else + else { + cb = (struct iocb )(uintptrt)events[i].obj; handle->aio.iocbret[events[i].data] = (s64)cb->aionbytes; + } + + cb = (struct iocb )(uintptrt)events[i].obj; cb->aiofildes = 0; } + if (firsterr) + return firsterr; toread -= (uint32t)rc; } @@ -510,7 +517,7 @@ int kcapiaioreadiov(struct kcapihandle handle, struct timespec timeout; timeout.tvsec = 0; timeout.tvnsec = 10000; - ret = kcapiaioreadall(handle, iovlen, &timeout); + ret = kcapiaioreadall(handle, 1, &timeout); if (ret < 0) return ret; } ------ This report was generated using AI technology. Always review AI-generated content prior to use

Red Hat

Affected Software

7 affected components
libkcapi libkcapi=1.5.0-3.el10
redhat Hardened Images
redhat OpenShift Container Platform=4.0
Smuellerdd Libkcapi>=0.12.0<1.5.1
redhat Enterprise Linux=8.0
redhat Enterprise Linux=9.0
redhat Enterprise Linux=10.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Configuration

    Avoid reusing the same AIO-enabled handle (initialized with KCAPI_INIT_AIO) after any AIO completion error; instead destroy and reinitialize the handle before subsequent AIO operations.

    libkcapi AIO interface KCAPI_INIT_AIO handle reuse behavior = do not reuse an AIO-enabled handle after any AIO completion error
  2. Compensating control

    If possible, avoid initializing or using libkcapi AIO paths (KCAPI_INIT_AIO / _kcapi_aio_read_all / _kcapi_aio_read_iov). If AIO must be used, ensure you do not reuse a handle after any AIO completion error.

Event History

Apr 26, 2026
Data Sourced
via Red Hat·08:18 PM
DescriptionSeverityAffected Software
Aug 5, 2026
CVE Published
via MITRE·12:42 PM
Data Sourced
via MITRE·12:42 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·01:24 PM
DescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203