UBUNTU-CVE-2026-89757: Medium severity ubuntu/linux-hwe-edge vulnerability
In the Linux kernel, the following vulnerability has been resolved: mm/mglru: fix and remove redundant unevictable folio handling sortfolio() has a shortcut for moving folios that are no longer evictable but are still sitting on a generation list. However, this shortcut is buggy. It does not follow the PGlru usage convention, and it has a more serious issue. Unevictable folios are not threaded on lists[LRUUNEVICTABLE], so that folio->lru can be reused to hold folio->mlockcount (see the comment in lruvecinit()). Hence lruvecaddfolio() skips the listadd() for them, and every other place that turns a folio unevictable initialises mlockcount explicitly: lruadd() sets it to 0, mlockfolio() and mlocknewfolio() set it to !!foliotestmlocked(folio). sortfolio() sets nothing, and the lrugendelfolio() right above it may have already poisoned folio->lru via listdel(), so mlockcount ends up aliasing LISTPOISON2, which reads as 0x122, i.e. 290. The result is user visible. On munlock, munlockfolio() decrements that bogus count, finds it still non-zero and bails out before clearing PGmlocked, so the folio remains unevictable and the Mlocked accounting stays inflated until the folio is freed. The shortcut also touches the LRU flags in the wrong order. It calls lrugendelfolio() while PGlru is still set, so a concurrent foliotestclearlru() (e.g. compaction, folioisolatelru()) can succeed on a folio that has already been taken off the generation list, which may lead to unexpected behavior. So fix it by isolating them as common folios and letting the generic shrink path cull them. This matches the classical LRU behavior, and there should be no visible effect on the generic eviction or isolation behavior. There is no performance concern either, such a folio goes through this once, and then it is off the generation lists for good.