]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.152/staging-android-ion-check-for-kref-overflow.patch
Linux 4.4.152
[thirdparty/kernel/stable-queue.git] / releases / 4.4.152 / staging-android-ion-check-for-kref-overflow.patch
1 From drosen@google.com Wed Aug 22 11:00:12 2018
2 From: Daniel Rosenberg <drosen@google.com>
3 Date: Tue, 21 Aug 2018 13:31:50 -0700
4 Subject: staging: android: ion: check for kref overflow
5 To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
6 Cc: linux-kernel@vger.kernel.org, kernel-team@android.com, Daniel Rosenberg <drosen@google.com>
7 Message-ID: <20180821203150.231997-1-drosen@google.com>
8
9 From: Daniel Rosenberg <drosen@google.com>
10
11 This patch is against 4.4. It does not apply to master due to a large
12 rework of ion in 4.12 which removed the affected functions altogther.
13 4c23cbff073f3b9b ("staging: android: ion: Remove import interface")
14
15 Userspace can cause the kref to handles to increment
16 arbitrarily high. Ensure it does not overflow.
17
18 Signed-off-by: Daniel Rosenberg <drosen@google.com>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20 ---
21 v2: Fixed patch corruption :(
22
23
24 It applies from 3.18 to 4.11, although with a trivial conflict resolution
25 for the later branches.
26 drivers/staging/android/ion/ion.c | 17 ++++++++++++++---
27 1 file changed, 14 insertions(+), 3 deletions(-)
28
29 --- a/drivers/staging/android/ion/ion.c
30 +++ b/drivers/staging/android/ion/ion.c
31 @@ -15,6 +15,7 @@
32 *
33 */
34
35 +#include <linux/atomic.h>
36 #include <linux/device.h>
37 #include <linux/err.h>
38 #include <linux/file.h>
39 @@ -387,6 +388,16 @@ static void ion_handle_get(struct ion_ha
40 kref_get(&handle->ref);
41 }
42
43 +/* Must hold the client lock */
44 +static struct ion_handle *ion_handle_get_check_overflow(
45 + struct ion_handle *handle)
46 +{
47 + if (atomic_read(&handle->ref.refcount) + 1 == 0)
48 + return ERR_PTR(-EOVERFLOW);
49 + ion_handle_get(handle);
50 + return handle;
51 +}
52 +
53 static int ion_handle_put_nolock(struct ion_handle *handle)
54 {
55 int ret;
56 @@ -433,9 +444,9 @@ static struct ion_handle *ion_handle_get
57
58 handle = idr_find(&client->idr, id);
59 if (handle)
60 - ion_handle_get(handle);
61 + return ion_handle_get_check_overflow(handle);
62
63 - return handle ? handle : ERR_PTR(-EINVAL);
64 + return ERR_PTR(-EINVAL);
65 }
66
67 struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
68 @@ -1202,7 +1213,7 @@ struct ion_handle *ion_import_dma_buf(st
69 /* if a handle exists for this buffer just take a reference to it */
70 handle = ion_handle_lookup(client, buffer);
71 if (!IS_ERR(handle)) {
72 - ion_handle_get(handle);
73 + handle = ion_handle_get_check_overflow(handle);
74 mutex_unlock(&client->lock);
75 goto end;
76 }