From nobody Tue Apr 7 04:35:04 2026 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (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 B87CA1EDA32 for ; Mon, 16 Mar 2026 07:00:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773644450; cv=none; b=CeR/6f+RpWgn0H7r1V8N2Ds3kg4HIOy43ECugmUwx+f3SMMudxw5h9xd0ewXBzdZA9u3yA+kVrR/MypXoPqdvd+UBwo+qTHWcBr/sBaBteWPaQ/qq0ygewiAoaJrSbp62W0bZ57jiqQa86RuIZhvAxmiLHO4pml1mM2Li9MfE6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773644450; c=relaxed/simple; bh=9E63yGLae86ycpk/Q1ufqYZHt8AQJWuJ91zeyoCsIlQ=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=LjYymbE405Yia8CRzEd8n3LQp4x9QtEJYVQV8+LcXwatslCUKUfHyn1DOZzu+Qi0UyaaRfcqcdMzrbm04eBq5Cp0+n58Oh/pzEi9IglYnjlzzSlifPM4v4pvLN6lxJ3YIFN4n2i/mY/YXcgQg3MbmhhZcQGKUotKf2MdoKxxhUI= 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=fH+hgqjs; arc=none smtp.client-ip=209.85.214.177 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="fH+hgqjs" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-2aaed195901so19539475ad.0 for ; Mon, 16 Mar 2026 00:00:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773644449; x=1774249249; 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=lj6uVSzjPpo1QsVQpIX9Z8xIGy6J1Sb3UZgbPXec1Go=; b=fH+hgqjsKN6Zw7YpDp+KFTpr/UEFSfy23MxyYaterr/nE2dXRCXtXDfao9oqwtkXqf LoLXECAQUUtm35pxMWAUfgliVlrTNkU76LeqKM3mektdnqjTD1fadS8B06f8Uip+Rh/+ 8zUlJjfvsZVSxBIeTr/UK24EIZvOyFTZ9PhhMbY8gvA76IM04TqA9O3mIJ270rNfwusr IhtL9N98dgeadr/7PYUfDOQGAkrB4n4nAHUV++bersp6jBbY82FVQL6X0teTuLRgoUJc fBCrquWVpumZc8ZWTRnPYtbDrtdt9oT+MJTWRTci9o4Mp9yqBh72P8nWt5b04tOAKpWc seQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773644449; x=1774249249; 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=lj6uVSzjPpo1QsVQpIX9Z8xIGy6J1Sb3UZgbPXec1Go=; b=o06XE9DmoebyWqkeH3kEPgbLp4JRAfOytvhXBY910JV57pLLHLj6cYInM6LDsQ7Sz+ j/fMNQ9nK0swMbjLgDuo/c7z4OdnvgpDOhhMyFYyJ14Ql+sF5TIO/2xKJduyM3b8GL+q LtBxlNCDukJCL/RgpxDdYKBVocz0U9X0I9kSjXkfE36owJ12GfSm2Q+L2s6hWUo9ECRU 2hYWO2VZnuTSz3OzmzCoQJGV+68/spppq63Qab0UalYbtP22mGl1B9VZywzrGI+8FyOF Ucr1g0UFYs9kJQuVn8DJeuJIxEc1SYdL2vqgRGLpG9BXVOiDiuAQmXQbTQKSOpqfFzv0 yLTQ== X-Forwarded-Encrypted: i=1; AJvYcCXC0zVcufulhEVCkhvvJwen8gECsSYeanXgJ8odXjZbxS0ndL3nJ/yQMpV/k6VHsDcSF8lLUuaQ/YP7Bx4=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9JFTQ9anq2KhHiqDValf1FCb2rM+ZHSSwl3OLJmSUxdVs8+5p w9/fBr/5xf3wCWXCJ8sMBF+o0WfsfgLDQUuwILU3oPU+8If5Cwt4+6ZX X-Gm-Gg: ATEYQzw/NlwefJhLKkUi/X6iI+eISu1yhWqZu3wyoI4MkACxT6sMRwaQJolfQio/xIC H6oTy5zoThJ27HvQiDS4PSO3NEBZ4YakPeV2ibsuaNHincVUWAIL32cckje1PlK87HtzV1z6om1 XitpQLURIxM7wvZTP89DdQc93CxV+hO+kuVFQLiobLbxtu5U7zilcq7+YNxFtHDUR8JKkg2N5td P8VxKWOif5J5p0bPJ2hCsfmLSPRsDs6e60fLVWk5LQX0Hyuzohu5tLkTiUBahdoVNBaACXXTwk3 NzRuLS97YzclYqOdkBRsQaYDmqIKI57s/zeXSoW1ocaWIzV8Z3FYLh5BRtM4Xi+cg4xEFmmtSNx Mbbi9vkcuTE2HjbQzN6S++NbWL/sKNv1v2w1dVxjeTvWYzIkyh5xbjBG13c0Hhm6fVArut8qkX1 m3AM+sl05raQmuV/9yCRGfY4zexuG2XQnQekuFuELD8cHWzzyjChIn7gabpKjS1OYcKWMy/S9T+ do1sw== X-Received: by 2002:a17:903:1ce:b0:2b0:5cb4:d894 with SMTP id d9443c01a7336-2b05cb4d961mr11761005ad.13.1773644448830; Mon, 16 Mar 2026 00:00:48 -0700 (PDT) Received: from deepanshu-kernel-hacker.. ([2405:201:682f:389d:5861:3d76:a555:a45]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2aece83ded9sm96884865ad.81.2026.03.16.00.00.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Mar 2026 00:00:47 -0700 (PDT) From: Deepanshu Kartikey To: akpm@linux-foundation.org, rppt@kernel.org, peterx@redhat.com Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Deepanshu Kartikey , syzbot+e24a2e34fad0efbac047@syzkaller.appspotmail.com, Deepanshu Kartikey Subject: [PATCH] mm/userfaultfd: re-validate vma in mfill_atomic() loop under CONFIG_PER_VMA_LOCK Date: Mon, 16 Mar 2026 12:30:39 +0530 Message-ID: <20260316070039.549506-1-kartikey406@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Under CONFIG_PER_VMA_LOCK, mfill_atomic() holds only a per-VMA read lock across its page-by-page copy loop. A concurrent UFFDIO_UNREGISTER can acquire mmap_write_lock() and split the VMA mid-loop via __split_vma(), which calls vma_start_write() via __vma_enter_locked(). The split happens in the race window between CHECK 1 and vm_refcnt++ in vma_start_read(). During this window vm_refcnt equals the base attached value, so vma_start_write() sees no readers and proceeds immediately without waiting, shrinking vma->vm_end in place. Both seqnum checks in vma_start_read() miss this because after mmap_write_unlock(), mm_lock_seq is incremented past vm_lock_seq making them unequal, so a split VMA is returned to mfill_atomic(). On the next iteration, mfill_atomic_install_pte() calls folio_add_new_anon_rmap() with state.dst_addr >=3D vma->vm_end, triggering its sanity check: address < vma->vm_start || address + (nr << 12) > vma->vm_end WARNING: mm/rmap.c:1682 folio_add_new_anon_rmap+0x5fe/0x14b0 Fix this by checking on each loop iteration whether state.dst_addr has fallen outside state.vma. If so, release the stale vma, update dst_start and len to reflect the current position, and re-lookup the vma via mfill_get_vma(). Reported-by: syzbot+e24a2e34fad0efbac047@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3De24a2e34fad0efbac047" Tested-by: syzbot+e24a2e34fad0efbac047@syzkaller.appspotmail.com Signed-off-by: Deepanshu Kartikey --- mm/userfaultfd.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 9ffc80d0a51b..ab73c2106c38 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -910,6 +910,22 @@ static __always_inline ssize_t mfill_atomic(struct use= rfaultfd_ctx *ctx, =20 while (state.src_addr < src_start + len) { VM_WARN_ON_ONCE(state.dst_addr >=3D dst_start + len); + /* + * Under CONFIG_PER_VMA_LOCK, a concurrent UFFDIO_UNREGISTER can + * split state.vma while we hold only the per-VMA read lock. The + * split shrinks vma->vm_end in place, causing dst_addr to fall + * outside the VMA bounds. Re-validate dst_addr on each iteration + * and re-lookup the vma if it has been split. + */ + if (state.dst_addr < state.vma->vm_start || + state.dst_addr >=3D state.vma->vm_end) { + mfill_put_vma(&state); + state.dst_start =3D state.dst_addr; + state.len =3D dst_start + len - state.dst_addr; + err =3D mfill_get_vma(&state); + if (err) + break; + } =20 err =3D mfill_get_pmd(&state); if (err) --=20 2.43.0