Skip to content

Commit 19c12ea

Browse files
drosen-googleZhengShunQian
authored andcommitted
staging: android: ion: check for kref overflow
This patch is against 4.4. It does not apply to master due to a large rework of ion in 4.12 which removed the affected functions altogther. 4c23cbf ("staging: android: ion: Remove import interface") Userspace can cause the kref to handles to increment arbitrarily high. Ensure it does not overflow. Signed-off-by: Daniel Rosenberg <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a4e390f commit 19c12ea

File tree

1 file changed

+14
-3
lines changed
  • drivers/staging/android/ion

1 file changed

+14
-3
lines changed

drivers/staging/android/ion/ion.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*
1616
*/
1717

18+
#include <linux/atomic.h>
1819
#include <linux/device.h>
1920
#include <linux/err.h>
2021
#include <linux/file.h>
@@ -396,6 +397,16 @@ void ion_handle_get(struct ion_handle *handle)
396397
kref_get(&handle->ref);
397398
}
398399

400+
/* Must hold the client lock */
401+
static struct ion_handle *ion_handle_get_check_overflow(
402+
struct ion_handle *handle)
403+
{
404+
if (atomic_read(&handle->ref.refcount) + 1 == 0)
405+
return ERR_PTR(-EOVERFLOW);
406+
ion_handle_get(handle);
407+
return handle;
408+
}
409+
399410
static int ion_handle_put_nolock(struct ion_handle *handle)
400411
{
401412
int ret;
@@ -442,9 +453,9 @@ static struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
442453

443454
handle = idr_find(&client->idr, id);
444455
if (handle)
445-
ion_handle_get(handle);
456+
return ion_handle_get_check_overflow(handle);
446457

447-
return handle ? handle : ERR_PTR(-EINVAL);
458+
return ERR_PTR(-EINVAL);
448459
}
449460

450461
struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
@@ -1530,7 +1541,7 @@ struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd)
15301541
/* if a handle exists for this buffer just take a reference to it */
15311542
handle = ion_handle_lookup(client, buffer);
15321543
if (!IS_ERR(handle)) {
1533-
ion_handle_get(handle);
1544+
handle = ion_handle_get_check_overflow(handle);
15341545
mutex_unlock(&client->lock);
15351546
goto end;
15361547
}

0 commit comments

Comments
 (0)