staging: android: ion: fix ION_IOC_{MAP,SHARE} use-after-free

commit 2c155709e4ef2d86d0176aac82e44c048a7e0255 upstream.

The ION_IOC_{MAP,SHARE} ioctls drop and reacquire client->lock several
times while operating on one of the client's ion_handles.  This creates
windows where userspace can call ION_IOC_FREE on the same client with
the same handle, and effectively make the kernel drop its own reference.
For example:

- thread A: ION_IOC_ALLOC creates an ion_handle with refcount 1
- thread A: starts ION_IOC_MAP and increments the refcount to 2
- thread B: ION_IOC_FREE decrements the refcount to 1
- thread B: ION_IOC_FREE decrements the refcount to 0 and frees the
            handle
- thread A: continues ION_IOC_MAP with a dangling ion_handle * to
            freed memory

Fix this by holding client->lock for the duration of
ION_IOC_{MAP,SHARE}, preventing the concurrent ION_IOC_FREE.  Also
remove ion_handle_get_by_id(), since there's literally no way to use it
safely.

This patch is applied on top of 4.4.y, and applies to older kernels
too.  4.9.y was fixed separately.  Kernels 4.12 and later are
unaffected, since all the underlying ion_handle infrastructure has been
ripped out.

Issue: SEC-3442
Change-Id: Id8b349f8161659862f518b40fbf68f657d52b4dd
Cc: stable@vger.kernel.org # v4.4-
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Acked-by: Laura Abbott <labbott@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Git-commit: 2c155709e4ef2d86d0176aac82e44c048a7e0255
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[quic_cgoldswo@quicinc.com: Retain ion_handle_get_by_id() and remove in
 subsequent commit ]
Signed-off-by: Chris Goldsworthy <quic_cgoldswo@quicinc.com>
Signed-off-by: Vijayanand Jitta <quic_vjitta@quicinc.com>
(cherry picked from commit 798d89db60833c46b811d0c1b7cf323df0fe1288)
1 file changed