All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jann Horn <jannh@google.com>
To: Andrew Morton <akpm@linux-foundation.org>, linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org,
	"Eric W . Biederman" <ebiederm@xmission.com>,
	Michel Lespinasse <walken@google.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Sakari Ailus <sakari.ailus@linux.intel.com>
Subject: [PATCH 3/4] mmap locking API: Don't check locking if the mm isn't live yet
Date: Tue, 29 Sep 2020 18:20:00 -0700	[thread overview]
Message-ID: <CAG48ez03YJG9JU_6tGiMcaVjuTyRE_o4LEQ7901b5ZoCnNAjcg@mail.gmail.com> (raw)
In-Reply-To: <20200930011944.19869-1-jannh@google.com>

In preparation for adding a mmap_assert_locked() check in
__get_user_pages(), teach the mmap_assert_*locked() helpers that it's fine
to operate on an mm without locking in the middle of execve() as long as
it hasn't been installed on a process yet.

Existing code paths that do this are (reverse callgraph):

  get_user_pages_remote
    get_arg_page
      copy_strings
      copy_string_kernel
      remove_arg_zero
    tomoyo_dump_page
      tomoyo_print_bprm
      tomoyo_scan_bprm
      tomoyo_environ

Signed-off-by: Jann Horn <jannh@google.com>
---
 fs/exec.c                 |  8 ++++++++
 include/linux/mm_types.h  |  9 +++++++++
 include/linux/mmap_lock.h | 16 ++++++++++++----
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index a91003e28eaa..c02b0e8e1c0b 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1129,6 +1129,14 @@ static int exec_mmap(struct mm_struct *mm)
 		}
 	}

+#if defined(CONFIG_LOCKDEP) || defined(CONFIG_DEBUG_VM)
+	/*
+	 * From here on, the mm may be accessed concurrently, and proper locking
+	 * is required for things like get_user_pages_remote().
+	 */
+	mm->mmap_lock_required = 1;
+#endif
+
 	task_lock(tsk);
 	active_mm = tsk->active_mm;
 	membarrier_exec_mmap(mm);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index ed028af3cb19..89fee0d0d652 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -552,6 +552,15 @@ struct mm_struct {
 		atomic_long_t hugetlb_usage;
 #endif
 		struct work_struct async_put_work;
+#if defined(CONFIG_LOCKDEP) || defined(CONFIG_DEBUG_VM)
+		/*
+		 * Notes whether this mm has been installed on a process yet.
+		 * If not, only the task going through execve() can access this
+		 * mm, and no locking is needed around get_user_pages_remote().
+		 * This flag is only used for debug checks.
+		 */
+		bool mmap_lock_required;
+#endif
 	} __randomize_layout;

 	/*
diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h
index 0707671851a8..c4fd874954d7 100644
--- a/include/linux/mmap_lock.h
+++ b/include/linux/mmap_lock.h
@@ -77,14 +77,22 @@ static inline void
mmap_read_unlock_non_owner(struct mm_struct *mm)

 static inline void mmap_assert_locked(struct mm_struct *mm)
 {
-	lockdep_assert_held(&mm->mmap_lock);
-	VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm);
+#if defined(CONFIG_LOCKDEP) || defined(CONFIG_DEBUG_VM)
+	if (mm->mmap_lock_required) {
+		lockdep_assert_held(&mm->mmap_lock);
+		VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm);
+	}
+#endif
 }

 static inline void mmap_assert_write_locked(struct mm_struct *mm)
 {
-	lockdep_assert_held_write(&mm->mmap_lock);
-	VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm);
+#if defined(CONFIG_LOCKDEP) || defined(CONFIG_DEBUG_VM)
+	if (mm->mmap_lock_required) {
+		lockdep_assert_held_write(&mm->mmap_lock);
+		VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm);
+	}
+#endif
 }

 #endif /* _LINUX_MMAP_LOCK_H */
-- 
2.28.0.709.gb0816b6eb0-goog

  parent reply	other threads:[~2020-09-30  1:20 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200930011944.19869-1-jannh@google.com>
2020-09-30  1:20 ` [PATCH 2/4] binfmt_elf: Take the mmap lock around find_extend_vma() Jann Horn
2020-09-30  1:20   ` Jann Horn
2020-09-30 23:22   ` Michel Lespinasse
2020-09-30 23:22     ` Michel Lespinasse
2020-09-30  1:20 ` Jann Horn [this message]
2020-09-30  1:20   ` [PATCH 3/4] mmap locking API: Don't check locking if the mm isn't live yet Jann Horn
2020-09-30 12:30   ` Jason Gunthorpe
2020-09-30 12:50     ` Jann Horn
2020-09-30 12:50       ` Jann Horn
2020-09-30 20:14       ` Jann Horn
2020-09-30 20:14         ` Jann Horn
2020-09-30 23:26         ` Jason Gunthorpe
2020-09-30 23:51           ` Jann Horn
2020-09-30 23:51             ` Jann Horn
2020-10-01 19:15             ` Jason Gunthorpe
2020-10-01 20:16               ` Jann Horn
2020-10-01 20:16                 ` Jann Horn
2020-10-01 23:41                 ` Jason Gunthorpe
2020-10-01 23:55                   ` Jann Horn
2020-10-01 23:55                     ` Jann Horn
2020-09-30 23:42         ` Michel Lespinasse
2020-09-30 23:42           ` Michel Lespinasse
2020-09-30  1:20 ` [PATCH 4/4] mm/gup: Assert that the mmap lock is held in __get_user_pages() Jann Horn
2020-09-30  1:20   ` Jann Horn
2020-09-30 12:32   ` Jason Gunthorpe
2020-09-30 23:24     ` Michel Lespinasse
2020-09-30 23:24       ` Michel Lespinasse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAG48ez03YJG9JU_6tGiMcaVjuTyRE_o4LEQ7901b5ZoCnNAjcg@mail.gmail.com \
    --to=jannh@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=ebiederm@xmission.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mchehab@kernel.org \
    --cc=sakari.ailus@linux.intel.com \
    --cc=walken@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.