{"id":"CVE-2026-98473","kind":"vulnerability","aliases":["CVE-2026-98473"],"related":[],"title":"Linux kernel s390 vfio-ap: leaked KVM interrupt and guest page on queue removal","description":"In the Linux kernel, the following vulnerability has been resolved:\n\ns390/vfio-ap: fix KVM GISC and page leak when queue removed from host config\n\nThree related problems exist in the handling of KVM interrupt and page\nresources when a queue is removed from the host's AP configuration\nwhile assigned to a mediated device (mdev).\n\nProblem 1:\n~~~~~~~~~\nAP_RESPONSE_Q_NOT_AVAIL not handled in vfio_ap_mdev_reset_queue()\n\nWhen the AP bus removes a queue device whose adapter or domain has\nbeen removed from the host's AP configuration,\nvfio_ap_mdev_remove_queue() is called. If the queue is still in the\nhost's AP configuration at that point, it calls\nvfio_ap_mdev_reset_queue(), which issues a PQAP(ZAPQ). Since the\nadapter is already gone from the host configuration, ap_zapq() returns\nAP_RESPONSE_Q_NOT_AVAIL (0x01). This response code is not handled in\nvfio_ap_mdev_reset_queue()'s switch statement and falls through to\nthe default case, which issues a WARN but does not call\nvfio_ap_free_aqic_resources(). As a result, if IRQ handling was\nenabled for the queue by the guest, the KVM GISC registration and\nthe pinned guest page holding the notification indicator byte (NIB)\nare both leaked.\n\nThis is fixed by adding AP_RESPONSE_Q_NOT_AVAIL to the same case as\nAP_RESPONSE_DECONFIGURED and AP_RESPONSE_CHECKSTOPPED in\nvfio_ap_mdev_reset_queue(). Like those response codes, Q_NOT_AVAIL\nindicates the queue is not operational and no further reset attempts\nare possible; the correct action is to free the IRQ resources\nimmediately.\n\nProblem 2:\n~~~~~~~~~\n AP_RESPONSE_Q_NOT_AVAIL not handled in apq_status_check()\n\nIn vfio_ap_mdev_reset_queue(), there are four cases that indicate a queue\nreset has not yet completed, in which case apq_reset_check() is queued to\na work queue to verify completion of the reset operation. This function\nuses the PQAP(TAPQ) function to get the queue's status and calls\napq_status_check() to verify whether the reset has completed, failed or\nneeds to be executed again. As described in Problem #1 above,\napq_reset_check() does not specifically check for AP_RESPONSE_Q_NOT_AVAIL,\nthereby potentially leaking KVM GISC registration and the pinned guest page\nholding the NIB.\n\nThis is fixed by adding a case statement for AP_RESPONSE_Q_NOT_AVAIL to\napq_status_check() and returning -ENODEV for that case. The caller,\napq_reset_check() will then check for this return code and call\nvfio_ap_free_aqic_resources() to prevent the leak.\n\nProblem 3:\n~~~~~~~~~\nvfio_ap_free_aqic_resources() leaks saved_isc when kvm is NULL\n\nvfio_ap_free_aqic_resources() guards the call to\nkvm_s390_gisc_unregister() with:\n\n    if (q->saved_isc != VFIO_AP_ISC_INVALID &&\n        !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm)))\n\nIf matrix_mdev->kvm is NULL -- which can happen when\nvfio_ap_mdev_unset_kvm() has already run and cleared kvm before a\nsubsequent cleanup path reaches this function -- the WARN_ON fires\nand the entire block is skipped. This leaves q->saved_isc set to a\nnon-invalid value, creating a potential double-free on any subsequent\ncall to this function.\n\nWhen kvm is NULL the KVM guest is already torn down, so\nkvm_s390_gisc_unregister() need not and cannot be called; however,\nq->saved_isc must always be cleared. Fix this by separating the\nkvm_s390_gisc_unregister() call from the q->saved_isc reset. The\nWARN_ON now guards only the genuinely impossible case of matrix_mdev\nbeing NULL. A NULL kvm is handled gracefully by skipping only the\nunregister call, and q->saved_isc = VFIO_AP_ISC_INVALID is set\nunconditionally whenever saved_isc was not already invalid.\n\nAdditionally, add an else clause to the host-config check in\nvfio_ap_mdev_remove_queue() to call vfio_ap_free_aqic_resources()\ndirectly when the queue is not in the host's AP configuration. This\nserves as a backstop: when the AP bus fires the driver .remove\ncallback after an adapter is removed from the host config, the queue\nis by definition no longer addressable, so vfio_ap_mdev_reset_queue\n---truncated---","summary":"When an AP queue is removed from the host configuration while assigned to a mediated device on s390, the Linux kernel's vfio-ap driver can leak a KVM interrupt registration and a pinned guest page. The sources describe this as a resource leak and a potential double-free, with no stated code execution or data exposure.","severity":"low","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["infrastructure","kvm","linux-kernel","mainframe","s390"],"not_affected_if":["no-vfio-ap-mediated-devices","non-s390-architecture"],"how_to_check":null,"fix":null,"status":"open","published_at":"2026-10-18T16:16:57+00:00","first_seen_at":"2026-10-23T21:57:15+00:00","triaged_at":"2026-10-25T05:25:59+00:00","updated_at":"2026-10-25T05:25:59+00:00","category":"infrastructure","confidence":0.6,"triage":{"at":"2026-10-25T05:25:59Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"local","title":"Linux kernel s390 vfio-ap: leaked KVM interrupt and guest page on queue removal","impact":"low","summary":"When an AP queue is removed from the host configuration while assigned to a mediated device on s390, the Linux kernel's vfio-ap driver can leak a KVM interrupt registration and a pinned guest page. The sources describe this as a resource leak and a potential double-free, with no stated code execution or data exposure.","category":"infrastructure","nicknames":[],"who_cares":["linux-kernel","s390","kvm","mainframe"],"confidence":0.6,"needs_auth":"unknown","worst_case":"kernel resource leak and possible double-free on s390 hosts","analyst_note":"Find the fixed kernel versions and stable backport commits for this s390 vfio-ap fix at https://nvd.nist.gov/vuln/detail/CVE-2026-98473 and the kernel git stable tree.","how_to_check":"unknown","needs_analyst":true,"not_affected_if":["non-s390-architecture","no-vfio-ap-mediated-devices"],"who_is_affected":"unknown","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000708,"input_tokens":4880,"output_tokens":440,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-2026':17A,20A '-98473':18A,21A '0x01':229C '1':143C,442C '2':356C '3':519C 'action':347C 'adapt':166C,213C,770C 'add':301C,475C,719C 'addit':718C 'address':784C 'alreadi':215C,579C,635C,716C 'alway':654C 'ap':6A,31B,53B,133C,144C,153C,159C,176C,179C,194C,202C,221C,224C,238C,261C,302C,312C,316C,321C,357C,370C,452C,480C,510C,521C,533C,551C,574C,705C,731C,738C,752C,761C,787C 'apq':365C,390C,421C,444C,486C,497C 'aqic':263C,512C,523C,535C,740C 'assign':40B,136C 'attempt':342C 'avail':148C,228C,306C,331C,361C,456C,484C 'backstop':758C 'block':599C 'bus':160C,762C 'byte':292C 'call':184C,200C,259C,420C,508C,539C,623C,648C,666C,699C,736C 'callback':767C 'caller':496C 'cannot':646C 'case':251C,310C,377C,389C,477C,494C,682C 'check':367C,392C,423C,446C,450C,488C,499C,502C,728C 'checkstop':318C 'claus':722C 'cleanup':587C 'clear':582C,656C 'code':83B,232C,328C,506C 'complet':386C,401C,430C 'config':110C,727C,776C 'configur':38B,134C,177C,195C,220C,753C 'correct':346C 'creat':614C 'cve':16A,19A 'data':86B 'deconfigur':314C 'default':250C 'definit':781C 'describ':68B,439C 'devic':44B,140C,164C 'direct':742C 'domain':168C 'doubl':78B,618C 'double-fre':77B,617C 'driver':54B,765C 'els':721C 'enabl':272C 'enodev':491C 'entir':598C 'execut':84B,436C 'exist':114C 'exposur':87B 'fail':431C 'fall':246C 'fire':595C,763C 'fix':99C,299C,473C,657C 'follow':93C 'four':376C 'free':79B,262C,350C,511C,522C,534C,619C,739C 'function':407C,412C,591C,626C 'genuin':680C 'get':414C 'gisc':101C,281C,461C,543C,641C,664C 'gone':216C 'grace':693C 'guard':537C,677C 'guest':11A,64B,278C,286C,466C,633C 'handl':117C,150C,235C,270C,363C,692C 'happen':571C 'hold':288C,468C 'host':37B,109C,131C,174C,192C,219C,726C,750C,775C 'host-config':725C 'howev':649C 'immedi':354C 'imposs':681C 'indic':291C,332C,379C 'infrastructur':22B 'interrupt':9A,59B,120C 'invalid':553C,612C,707C,717C 'irq':269C,352C 'isc':527C,549C,552C,606C,652C,671C,703C,706C,713C 'issu':207C,253C 'kernel':2A,26B,49B,91C 'kvm':8A,23B,58B,100C,119C,280C,460C,529C,541C,562C,566C,577C,583C,628C,632C,639C,662C,690C 'leak':7A,56B,73B,104C,296C,459C,517C,525C 'leav':603C 'like':325C 'linux':1A,25B,48B,90C 'linux-kernel':24B 'longer':783C 'mainfram':27B 'matrix':557C,560C,564C,684C 'mdev':141C,154C,180C,203C,239C,322C,371C,558C,561C,565C,575C,685C,732C,788C 'mediat':43B,139C 'must':653C 'need':433C,643C 'nib':293C,470C 'non':611C 'non-invalid':610C 'notif':290C 'null':531C,568C,630C,687C,689C 'oper':337C,405C 'page':12A,65B,103C,122C,287C,467C 'path':588C 'pin':63B,285C,465C 'point':198C 'possibl':344C 'potenti':76B,458C,616C 'pqap':209C,410C 'prevent':515C 'problem':113C,142C,355C,441C,518C 'q':146C,226C,304C,329C,359C,454C,482C,547C,556C,559C,604C,650C,669C,701C 'queu':394C 'queue':14A,32B,106C,126C,156C,163C,182C,187C,205C,241C,275C,324C,334C,373C,381C,398C,416C,734C,745C,778C,790C 'reach':589C 'registr':60B,282C,462C 'relat':112C 'remov':15A,34B,107C,128C,161C,171C,181C,733C,766C,772C 'reset':155C,204C,240C,323C,341C,372C,382C,391C,404C,428C,445C,498C,672C,789C 'resolv':97C 'resourc':72B,123C,264C,353C,513C,524C,536C,741C 'respons':145C,225C,231C,303C,313C,317C,327C,358C,453C,481C 'result':267C 'return':223C,490C,505C 'run':580C 's390':3A,28B,46B,542C,640C,663C 's390/vfio-ap':98C 'save':526C,548C,605C,651C,670C,702C,712C 'separ':660C 'serv':755C 'set':607C,709C 'sinc':211C 'skip':601C,695C 'sourc':67B 'specif':449C 'state':82B 'statement':244C,478C 'status':366C,418C,422C,487C 'still':189C 'subsequ':586C,622C 'switch':243C 'tapq':411C 'therebi':457C 'three':111C 'torn':636C 'truncat':791C 'uncondit':710C 'unregist':544C,642C,665C,698C 'unset':576C 'use':408C 'valu':613C 'verifi':400C,425C 'vfio':5A,52B,152C,178C,201C,237C,260C,320C,369C,509C,520C,532C,550C,573C,704C,730C,737C,786C 'vfio-ap':4A,51B 'vulner':94C 'warn':255C,554C,593C,674C 'whenev':711C 'whether':426C 'whose':165C 'work':397C 'yet':385C 'zapq':210C,222C","nicknames":[],"mitigations":[],"who_affected":null,"tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-18T16:16:57+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-98473","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-98473","severity":null,"published_at":"2026-10-18T16:16:57+00:00","modified_at":"2026-10-19T10:18:57+00:00","first_seen_at":"2026-10-23T21:57:15+00:00","fetched_at":"2026-10-23T22:28:56+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}