From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C94433A5423 for ; Sat, 28 Mar 2026 17:01:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774717268; cv=none; b=CQ1vb5MnJ/+bVLJIsrhwtKRV0ahbriTXDsOAuLVNjFQpLSbamQD486FhK0DZ7eP+BxM/kJ9KHhrpB/g3Y4Kcy886ruhzj+VoADzLL+U5ZlsVU7b/L7x9d2dYrDrJKKchkQy9joJeJ3KeGAXZZE88FNFw2UCVJXd3IxxOAxEKg34= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774717268; c=relaxed/simple; bh=TbBVjSzCT28AiVV9a/VF7l9qbFrhgev0v1XC9Nsck5g=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=LgFrTPwgE/Dn5jEiGoxY0btCCeIzia1B6Age4CkPs1D4O3O4iNf3psp/YMWRtLwhZPZ77fkEsKI8K0z1oi2+/K4hwQquiIRMIjwKU1RpjfXy7n3J93llXg5R7HlfxtztxruYvZZaXnoVBveZEGmNxtzr95i+SHkPyoKks4qeHM0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KPCXkNsd; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KPCXkNsd" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-4838c15e3cbso25111935e9.3 for ; Sat, 28 Mar 2026 10:01:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774717265; x=1775322065; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Bg18eS1djMVIP5KxOMkHWnTtPI0ppyIsarR2yPbY2iY=; b=KPCXkNsdqgLnNnWG5kbGNGvT8wi2C4Qm6aHUmPg82hv0WydLTwlU2s968kAO7nTWnW wBaadnzCJd6Q6OoGbtyIFqktC3Y9PlEmqOJ5pbErvGKHkd9NxrEK5pndSy/01X7oI3Li MjhQ2aNa+rk3n38R/r6cvmfjA5UnBzzQLNcuT0lrsFI7H0eBBoI3AdZwhqWgvXAwljea w2RofDFwDezcAZavNp8yDxnCcXQW4k7PflYxW3uyuA4rmKtHIp0s/BB3CJIhj8nKm3u2 7bpVJGB3b/U9CNgNs/JHl1HfV8CaioiUtxUB6ll624s45jIOyla0qYIk3CCQz5BcdF/t Ha3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774717265; x=1775322065; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Bg18eS1djMVIP5KxOMkHWnTtPI0ppyIsarR2yPbY2iY=; b=Xd6FMFsloc0F+8x57bw9MvJPZ1o2sub0Mpwj/ixqhuWe+dYX2rfYuPrLEj10+mIctz s2kdzOONjom2oflY/YRH8ZviXo3tn03rb4Mdgax7RacR90cSRnHLiQH1WHIqwuwu3Yp8 S8EBYcY0e5tRxFpgib/jpo9Ga37ilXXm0sLZnS3cFzEdWUOxeifwNGdFskdHDsQTGhLZ c9Wf/ln7kJ7+p3jdW9XCNXNvAlcXMEzBD+VWregGC5FnZmYNBnUJfhZeCChUDTZsZp59 9r1vTIPfCLatI5/BoWL++w8sebSutQ8TezGIkh8iwQNzYS3OINr/QVgY0HnsEA3qRlti a92Q== X-Forwarded-Encrypted: i=1; AJvYcCXbksuHU8jiIvNHXejWatMISu3C6PtRXO84WLLexusCFC82fAr1eFogNzcCfnzJU4aNu0sjeNaSKUwstqw=@vger.kernel.org X-Gm-Message-State: AOJu0YzQ/0Enqeu1l0QB+tWA3bQ9hNkvVpqf3g36fNu7MDv5cWT8jW1h qhYT5nNk42uhHKf2f4rZsMM/2XkpHbJJoHw46nJDTveDCfvfgG4Pt+Qr X-Gm-Gg: ATEYQzx2fGXKDBSn5X3YCvHRh7bIZKZwaPTJxaY0fctGgFJ9xq/mb1lBGPjMziBkHUz zp0dz1e+DvXoKjkbYsQ1op9/Ao+9qvUMaHmmPbyWKtryDaY8Lyle9IFAbCCuUZDJs+P8dOCeqvR 0yc+AvnkIrbZ8whtP1wgB7rM116/9Pj0prnr4ms7aF8dEh1jDYZFaPBhe1DIJZumegCqZTeTWfw LrbEXcVB5Qi14cMs4N3iD4F4qEeFjCoZFPEl7ff5TeVla9MmV9aN2lmtZ2qqJQWzmvHldLPCe7q g45s0uIhPdXFky/jnxp2lzWKgr5sY63OSWKpmPZJsak5G0opNlOORKE5UxM5lbAY/Gd2LkAL45S lwzJhtQguLAXFl3BVxxlwUb3rGOicK/YBsTtRrMO2j5OnmkmxWAqYpLIk27GaTh6IzktINCU0bc tW+z30kAq7/0wDsT3AbhO63ABBYsKHRiIbUbTOLaoDWXIbwa8SyqC2fUPi0M3RgP+h0KGRGlvgM NNxJE475xi5 X-Received: by 2002:a05:600c:41c4:b0:486:fc5f:1ab9 with SMTP id 5b1f17b1804b1-48727d8410cmr76271105e9.14.1774717265143; Sat, 28 Mar 2026 10:01:05 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4872718dfdfsm38161075e9.30.2026.03.28.10.01.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Mar 2026 10:01:04 -0700 (PDT) From: David Carlier To: Andrew Morton , Peter Xu Cc: Mike Rapoport , linux-mm@kvack.org, linux-kernel@vger.kernel.org, David Carlier Subject: [PATCH 1/2] mm/userfaultfd: fix stale ops and VMA type mismatch after copy retry Date: Sat, 28 Mar 2026 17:01:00 +0000 Message-ID: <20260328170101.184163-1-devnexen@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In mfill_atomic_pte_copy(), ops is derived from the VMA once and passed to __mfill_atomic_pte(). When the initial copy_from_user() fails under pagefault_disable(), mfill_copy_folio_retry() drops all locks, performs the copy with page faults enabled, then re-acquires locks via mfill_get_vma(). During this window, the VMA can be replaced entirely (e.g. munmap + mmap + UFFDIO_REGISTER by another thread), but ops is never re-validated. If a shared shmem VMA is replaced by an anonymous VMA, the stale shmem_uffd_ops->filemap_add calls shmem_mfill_filemap_add() with an anonymous VMA, causing a NULL pointer dereference at file_inode(vma-> vm_file) since vm_file is NULL for anonymous mappings. The mmap_changing guard does not fully prevent this because userfaultfd_unmap_prep() only increments mmap_changing when UFFD_FEATURE_EVENT_UNMAP is enabled, which is optional. Without it, munmap proceeds without any signal to the retry path. The copy_from_user() in the retry runs with page faults enabled and can block on slow backing stores (FUSE, NFS), significantly widening the race window. Fix this by: - Validating that the VMA's userfaultfd context matches state->ctx in mfill_get_vma() to detect cross-context VMA replacement. - Re-checking that vma_uffd_ops() still matches the frozen ops after the retry, and that the VMA is still VM_SHARED when ops expects it to be, returning -EAGAIN otherwise. Signed-off-by: David Carlier --- mm/userfaultfd.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 481ec7eb4442..2a6e034b15aa 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -225,8 +225,9 @@ static int mfill_get_vma(struct mfill_state *state) */ down_read(&ctx->map_changing_lock); state->vma = dst_vma; + err = -EAGAIN; - if (atomic_read(&ctx->mmap_changing)) + if (dst_vma->vm_userfaultfd_ctx.ctx != ctx || atomic_read(&ctx->mmap_changing)) goto out_unlock; err = -EINVAL; @@ -498,6 +499,12 @@ static int __mfill_atomic_pte(struct mfill_state *state, ret = mfill_copy_folio_retry(state, folio); if (ret) goto err_folio_put; + if (vma_uffd_ops(state->vma) != ops || + (ops != &anon_uffd_ops && + !(state->vma->vm_flags & VM_SHARED))) { + ret = -EAGAIN; + goto err_folio_put; + } } } else if (uffd_flags_mode_is(flags, MFILL_ATOMIC_ZEROPAGE)) { clear_user_highpage(&folio->page, state->dst_addr); -- 2.53.0