{"id":"CVE-2026-98999","kind":"vulnerability","aliases":["CVE-2026-98999"],"related":[],"title":"Linux kernel xe driver: stale list entry leads to use-after-free","description":"In the Linux kernel, the following vulnerability has been resolved:\n\ndrm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin\n\nxe_bo_pin_external() and xe_bo_unpin_external() maintain the bo's\npinned_link list membership in xe->pinned.late.external, based on\nwhether the current call is the outermost pin or the final unpin.\nHowever, the same external bo's pin_count can also be raised and\nlowered directly by __xe_pin_fb_vma()/__xe_unpin_fb_vma(), which pin\nthe bo as a display scanout buffer without going through\nxe_bo_pin_external()/xe_bo_unpin_external() at all, and have no\nnotion of, or ownership over, pinned_link.\n\nIf a bo is pinned both externally (e.g. dma-buf export) and as an fb,\nand the external unpin happens first, xe_bo_unpin_external() correctly\nobserves pin_count > 1 and leaves the bo on pinned_link. When the fb\nunpin later performs the true last unpin (pin_count 1 -> 0), it never\ntouches pinned_link, leaving the bo linked on xe->pinned.late.external\nindefinitely. Once the bo is subsequently freed, this stale list entry\npoints into freed memory, corrupting the list and risking a\nuse-after-free the next time the list is walked or spliced.\n\nThe backup object pin/unpin sites in xe_bo_notifier_prepare_pinned()/\nxe_bo_notifier_unprepare_pinned() have the same bypass characteristic,\nthough they never add their bo to a pinned list, so are not affected\nby this particular list-corruption issue.\n\nMove the pinned_link removal into xe_bo_account_unpin(), which already\nruns on every unpin path (kernel, external, framebuffer, backup\nobject) right before the true 1 -> 0 pin_count transition. Since\nlist_del_init() only operates on the node itself, this removal is\nlist-agnostic and safe to perform regardless of which list (external\nor kernel_bo_present) the bo happens to be linked on, or which code\npath is performing the final unpin. Drop the now-redundant explicit\nlist_del_init() calls in xe_bo_unpin_external() and xe_bo_unpin().\n\nv2:\n- New patch\n\nv3:\n- Rebased on changes to previous patch.\n\n(cherry picked from commit ca58d36a1f93af586ee93b340c9f9fd81312cc01)","summary":"In the Intel Xe DRM driver, a buffer pinned both externally (for example by dma-buf export) and as a display framebuffer can stay linked on a kernel pinned list after its final unpin. Once that buffer is freed, the dangling list entry can corrupt the list or cause a use-after-free.","severity":"unknown","cvss":null,"epss":0.00219,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["drm","intel-xe","kernel","linux","runtime"],"not_affected_if":[],"how_to_check":"- unknown","fix":"- unknown","status":"open","published_at":"2026-10-23T13:17:22+00:00","first_seen_at":"2026-10-23T21:57:33+00:00","triaged_at":"2026-10-25T04:55:57+00:00","updated_at":"2026-10-25T12:38:50+00:00","category":"runtime","confidence":0.5,"triage":{"at":"2026-10-25T04:55:57Z","model":"claude-haiku-5-5","output":{"fix":"- unknown","reach":"local","title":"Linux kernel xe driver: stale list entry leads to use-after-free","impact":"high","summary":"In the Intel Xe DRM driver, a buffer pinned both externally (for example by dma-buf export) and as a display framebuffer can stay linked on a kernel pinned list after its final unpin. Once that buffer is freed, the dangling list entry can corrupt the list or cause a use-after-free.","category":"runtime","nicknames":[],"who_cares":["linux","kernel","intel-xe","drm"],"confidence":0.5,"needs_auth":"unknown","worst_case":"Kernel memory corruption from a use-after-free in the driver","analyst_note":"Check the upstream kernel commit ca58d36a1f93af586ee93b340c9f9fd81312cc01 and the NVD entry for affected and fixed kernel versions and whether the xe driver is reachable by unprivileged users.","how_to_check":"- unknown","needs_analyst":true,"not_affected_if":[],"who_is_affected":"unknown","user_interaction":"unknown","needs_special_setup":"unknown","severity_if_unknown":"unknown"},"cost_usd":0.000609,"input_tokens":4034,"output_tokens":411,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-2026':15A,18A '-98999':16A,19A '/__xe_unpin_fb_vma':160C '/xe_bo_unpin_external':177C '0':241C,357C '1':220C,240C,356C 'account':338C 'add':312C 'affect':322C 'agnost':376C 'alreadi':341C 'also':149C 'backup':289C,350C 'base':126C 'bo':107C,112C,117C,144C,164C,174C,192C,213C,224C,249C,257C,295C,300C,314C,337C,388C,391C,418C,423C 'buf':43B,200C 'buffer':34B,64B,169C 'bypass':307C 'ca58d36a1f93af586ee93b340c9f9fd81312cc01':439C 'call':131C,415C 'caus':76B 'chang':431C 'characterist':308C 'cherri':435C 'code':399C 'commit':438C 'correct':216C 'corrupt':72B,269C,328C 'count':147C,219C,239C,359C 'current':130C 'cve':14A,17A 'dangl':68B 'del':363C,413C 'direct':154C 'display':48B,167C 'dma':42B,199C 'dma-buf':41B,198C 'driver':4A,32B 'drm':20B,31B 'drm/xe':92C 'drop':406C 'e.g':197C 'entri':7A,70B,97C,264C 'everi':344C 'exampl':39B 'explicit':411C 'export':44B,201C 'extern':37B,109C,114C,143C,176C,196C,208C,215C,348C,385C,420C 'fb':100C,158C,205C,230C 'fb-pin':99C 'final':60B,104C,138C,404C 'first':211C 'fix':93C 'follow':87C 'framebuff':49B,349C 'free':13A,81B,278C 'freed':66B,260C,267C 'go':171C 'happen':210C,392C 'howev':140C 'indefinit':254C 'init':364C,414C 'intel':22B,29B 'intel-x':21B 'issu':329C 'kernel':2A,24B,55B,85C,347C,387C 'last':236C 'later':232C 'lead':8A 'leav':222C,247C 'link':52B,96C,120C,189C,227C,246C,250C,333C,395C 'linux':1A,25B,84C 'list':6A,57B,69B,74B,121C,263C,271C,283C,318C,327C,362C,375C,384C,412C 'list-agnost':374C 'list-corrupt':326C 'lower':153C 'maintain':115C 'membership':122C 'memori':268C 'move':330C 'never':243C,311C 'new':426C 'next':280C 'node':369C 'notifi':296C,301C 'notion':183C 'now-redund':408C 'object':290C,351C 'observ':217C 'oper':366C 'outermost':134C 'ownership':186C 'particular':325C 'patch':427C,434C 'path':346C,400C 'perform':102C,233C,380C,402C 'pick':436C 'pin':35B,56B,95C,101C,108C,119C,135C,146C,157C,162C,175C,188C,194C,218C,226C,238C,245C,298C,303C,317C,332C,358C 'pin/unpin':291C 'pinned.late.external':125C,253C 'point':265C 'prepar':297C 'present':389C 'previous':433C 'rais':151C 'rebas':429C 'redund':410C 'regardless':381C 'remov':334C,372C 'resolv':91C 'right':352C 'risk':273C 'run':342C 'runtim':26B 'safe':378C 'scanout':168C 'sinc':361C 'site':292C 'splice':287C 'stale':5A,94C,262C 'stay':51B 'subsequ':259C 'though':309C 'time':281C 'touch':244C 'transit':360C 'true':235C,355C 'unpin':61B,105C,113C,139C,209C,214C,231C,237C,339C,345C,405C,419C,424C 'unprepar':302C 'use':11A,79B,276C 'use-after-fre':10A,78B,275C 'v2':425C 'v3':428C 'vma':159C 'vulner':88C 'walk':285C 'whether':128C 'without':170C 'xe':3A,23B,30B,106C,111C,124C,156C,173C,212C,252C,294C,299C,336C,417C,422C","nicknames":[],"mitigations":[],"who_affected":null,"tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-23T13:17:22+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-98999","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-98999","severity":null,"published_at":"2026-10-23T13:17:22+00:00","modified_at":"2026-10-23T13:17:22+00:00","first_seen_at":"2026-10-23T21:57:33+00:00","fetched_at":"2026-10-23T22:29:03+00:00","note":null},{"source":"epss","external_id":"CVE-2026-98999","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-98999","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-25T12:38:50+00:00","fetched_at":"2026-10-25T12:38:50+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"}