|
15 | 15 | *
|
16 | 16 | */
|
17 | 17 |
|
| 18 | +#include <linux/atomic.h> |
18 | 19 | #include <linux/device.h>
|
19 | 20 | #include <linux/err.h>
|
20 | 21 | #include <linux/file.h>
|
@@ -396,6 +397,16 @@ void ion_handle_get(struct ion_handle *handle)
|
396 | 397 | kref_get(&handle->ref);
|
397 | 398 | }
|
398 | 399 |
|
| 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 | + |
399 | 410 | static int ion_handle_put_nolock(struct ion_handle *handle)
|
400 | 411 | {
|
401 | 412 | int ret;
|
@@ -442,9 +453,9 @@ static struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
|
442 | 453 |
|
443 | 454 | handle = idr_find(&client->idr, id);
|
444 | 455 | if (handle)
|
445 |
| - ion_handle_get(handle); |
| 456 | + return ion_handle_get_check_overflow(handle); |
446 | 457 |
|
447 |
| - return handle ? handle : ERR_PTR(-EINVAL); |
| 458 | + return ERR_PTR(-EINVAL); |
448 | 459 | }
|
449 | 460 |
|
450 | 461 | 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)
|
1530 | 1541 | /* if a handle exists for this buffer just take a reference to it */
|
1531 | 1542 | handle = ion_handle_lookup(client, buffer);
|
1532 | 1543 | if (!IS_ERR(handle)) {
|
1533 |
| - ion_handle_get(handle); |
| 1544 | + handle = ion_handle_get_check_overflow(handle); |
1534 | 1545 | mutex_unlock(&client->lock);
|
1535 | 1546 | goto end;
|
1536 | 1547 | }
|
|
0 commit comments