Re: [PATCH] Detect early free of a live mm

From: Mark Rutland
Date: Wed Feb 28 2018 - 07:18:21 EST


Ugh, I messed up Peter's email when sending this out. please
s/infraded/infradead/ if replying to the first mail.

Sorry about that.

Mark.

On Wed, Feb 28, 2018 at 12:14:58PM +0000, Mark Rutland wrote:
> KASAN splats indicate that in some cases we free a live mm, then
> continue to access it, with potentially disastrous results. This is
> likely due to a mismatched mmdrop() somewhere in the kernel, but so far
> the culprit remains elusive.
>
> Let's have __mmdrop() verify that the mm isn't live for the current
> task, similar to the existing check for init_mm. This way, we can catch
> this class of issue earlier, and without requiring KASAN.
>
> Signed-off-by: Mark Rutland <mark.rutland@xxxxxxx>
> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> Cc: Ingo Molnar <mingo@xxxxxxxxxx>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx>
> Cc: Michal Hocko <mhocko@xxxxxxxx>
> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxx>
> Cc: Rik van Riel <riel@xxxxxxxxxx>
> Cc: Will Deacon <will.deacon@xxxxxxx>
> ---
> kernel/fork.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> Hi,
>
> For context, we're seeing an intermittent use-after-free of an mm on
> arm64 [1], where it looks like an mm has been freed earlier than
> expected. So far KASAN has only caught legitimate mmdrop() uses, where
> mm_count is presumably already bogus.
>
> Mark.
>
> [1] https://lkml.kernel.org/r/20180214120254.qq4w4s42ecxio7lu@xxxxxxxxxxxxxxxxxxxxxxxxx
>
> diff --git a/kernel/fork.c b/kernel/fork.c
> index e5d9d405ae4e..6922d93551b8 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -595,6 +595,8 @@ static void check_mm(struct mm_struct *mm)
> void __mmdrop(struct mm_struct *mm)
> {
> BUG_ON(mm == &init_mm);
> + BUG_ON(mm == current->mm);
> + BUG_ON(mm == current->active_mm);
> mm_free_pgd(mm);
> destroy_context(mm);
> hmm_mm_destroy(mm);
> --
> 2.11.0
>