dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Inki Dae <inki.dae@samsung.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [RFC] deadlock in "drm/exynos: fix wrong pointer access at vm close"
Date: Mon, 23 Sep 2013 14:07:28 +0100	[thread overview]
Message-ID: <20130923130727.GV13318@ZenIV.linux.org.uk> (raw)
In-Reply-To: <055301ceb831$6f8d42c0$4ea7c840$%dae@samsung.com>

On Mon, Sep 23, 2013 at 04:49:30PM +0900, Inki Dae wrote:
> Hi,
> 
> > -----Original Message-----
> > From: Al Viro [mailto:viro@ftp.linux.org.uk] On Behalf Of Al Viro
> > Sent: Monday, September 23, 2013 6:29 AM
> > To: YoungJun Cho
> > Cc: dri-devel@lists.freedesktop.org; Inki Dae
> > Subject: [RFC] deadlock in "drm/exynos: fix wrong pointer access at vm
> > close"
> > 
> > 	You have drm_dev->struct_mutex grabbed before ->mmap_sem in
> > exynos_drm_gem_mmap_ioctl() and after - in exynos_drm_gem_fault()
> > (since ->fault() is always called with ->mmap_sem held).  Looks like
> > a garden-variety AB-BA deadlock...
> > 
> 
> Right, if mmap system call is requested by another process between ->f_op
> pointer changing and restoring, the deadlock can be incurred.
> 
> For this, I think we can resolve this issue like below,
> 
> At exynos_drm_gem_mmap_ioctl()
> 	down_write(&mm->mmap_sem);
> 	mutex_lock(&dev->struct_mutex);
> 	...

Umm...  If you do it that way, why bother with changing ->private_data
at all?  You can as well stash obj in dev->dev_private->something after
you've grabbed the mutex and have ->mmap() pick it there...

Said that, I really don't like that approach - both playing with ->f_op
and the games with private vmas; exynos_gem_get_vma(), AFAICS, calls
find_vma() (without bothering to hold ->mmap_sem, BTW - there's nothing
to prevent the result of find_vma() being freed just as it's returned
to caller) and clones it manually, regardless of whether that vma allows
to clone itself or not.  Quite a few drivers rely on that not happening...

IOW, you are already digging deep inside VM guts and this only makes
it deeper ;-/

And no, the deadlock doesn't depend on race between ioctl() and mmap()
from another process; all it takes is
1) thread A does clone(), creating thread B that shares address space with
it.
2) thread A does that ioctl, creating a mapping
3) thread A does that ioctl again, creating another mapping, while thread
B dereferences an address in the first mapping and triggers a page fault.

The only race is on step 3 in the above; the question about mmap() vs.
ioctl() was about mmap(2) _during_ that ioctl() hitting
exynos_drm_gem_mmap_buffer() instead of exynos_drm_gem_mmap() it would've
called before or after ioctl().  Here the interesting case is when
callers of mmap() and ioctl() do *not* share the address space, since
in that case mmap(2) won't notice ->mmap_sem held by you - it's on the
different mm_struct, so mmap(2) will get to calling the ->f_op->mmap()
without waiting for you to restore ->f_op...

For another bug in the same area, try building that driver modular and
watch what happens to use count after a round of this switching ->f_op and
restoring it back to original; fops_get() in there is wrong and AFAICS
pointless.

  reply	other threads:[~2013-09-23 13:07 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-22 21:29 [RFC] deadlock in "drm/exynos: fix wrong pointer access at vm close" Al Viro
2013-09-23  7:49 ` Inki Dae
2013-09-23 13:07   ` Al Viro [this message]
2013-09-24  4:41     ` Inki Dae
2013-09-26  3:26       ` Al Viro
2013-09-28 17:17         ` Inki Dae
2013-09-25  4:34     ` Inki Dae
2013-09-26  3:28       ` Al Viro
2013-09-28 17:47         ` Inki Dae
2013-09-28 17:50           ` Inki Dae

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=20130923130727.GV13318@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=inki.dae@samsung.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).