diff options
author | Meghana Barkalle <mbarkalle@google.com> | 2023-05-16 20:23:10 +0000 |
---|---|---|
committer | Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> | 2023-12-13 16:36:31 +0000 |
commit | 3c3738fafc1c80d84ead3b586f72a05b7e26b32e (patch) | |
tree | e2df7c723c46cdcd4656d6df708f399b1d768c66 | |
parent | c8834e1ec22abf3964fcf07fcfe29ffa0af0cb50 (diff) | |
download | lwis-3c3738fafc1c80d84ead3b586f72a05b7e26b32e.tar.gz |
LWIS: Fix use of transaction pointer after free
During client flush, transaction pointer was used to
delete the pending node map after free. Fixing this
issue by deleting the node before freeing transaction.
Bug: 299130975
Test: GCA Smoke test
Change-Id: I5c49b3fc143d95664272a22af50f0c2dbf598ccc
(cherry picked from commit b871fb504923c511dccf4dafc74079807fd21bd9)
Signed-off-by: Meghana Barkalle <mbarkalle@google.com>
-rw-r--r-- | lwis_transaction.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/lwis_transaction.c b/lwis_transaction.c index 33babf6..8372370 100644 --- a/lwis_transaction.c +++ b/lwis_transaction.c @@ -428,7 +428,7 @@ static int process_transaction(struct lwis_client *client, struct lwis_transacti static void cancel_transaction(struct lwis_device *lwis_dev, struct lwis_transaction **ptransaction, int error_code, struct list_head *pending_events, - struct list_head *pending_fences) + struct list_head *pending_fences, bool delete_pending_map_node) { int pending_status; struct lwis_transaction *transaction = *ptransaction; @@ -454,6 +454,11 @@ static void cancel_transaction(struct lwis_device *lwis_dev, struct lwis_transac pending_status = error_code == -ECANCELED ? 1 : error_code; lwis_pending_fences_move_all(lwis_dev, transaction, pending_fences, pending_status); } + + if (delete_pending_map_node) { + hash_del(&transaction->pending_map_node); + } + lwis_transaction_free(lwis_dev, ptransaction); } @@ -475,7 +480,7 @@ void lwis_process_transactions_in_queue(struct lwis_client *client) list_del(&transaction->process_queue_node); cancel_transaction(client->lwis_dev, &transaction, transaction->resp->error_code, &pending_events, - &pending_fences); + &pending_fences, false); } else { spin_unlock_irqrestore(&client->transaction_lock, flags); process_transaction(client, &transaction, &pending_events, &pending_fences, @@ -541,7 +546,8 @@ static void cancel_all_transactions_in_queue_locked(struct lwis_client *client, transaction = list_entry(it_tran, struct lwis_transaction, process_queue_node); list_del(&transaction->process_queue_node); - cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL); + cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL, + false); } } } @@ -574,14 +580,14 @@ int lwis_transaction_client_flush(struct lwis_client *client) list_for_each_safe (it_tran, it_tran_tmp, &it_evt_list->list) { transaction = list_entry(it_tran, struct lwis_transaction, event_list_node); list_del(&transaction->event_list_node); - cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL); + cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL, + false); } hash_del(&it_evt_list->node); kfree(it_evt_list); } hash_for_each_safe (client->pending_transactions, i, tmp, transaction, pending_map_node) { - cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL); - hash_del(&transaction->pending_map_node); + cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL, true); } spin_unlock_irqrestore(&client->transaction_lock, flags); @@ -629,7 +635,8 @@ int lwis_transaction_client_cleanup(struct lwis_client *client) } list_del(&transaction->event_list_node); if (transaction->resp->error_code || client->lwis_dev->enabled == 0) { - cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL); + cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, NULL, NULL, + false); } else { spin_unlock_irqrestore(&client->transaction_lock, flags); process_transaction(client, &transaction, @@ -1093,7 +1100,7 @@ void lwis_transaction_fence_trigger(struct lwis_client *client, struct lwis_fenc } else { cancel_transaction(client->lwis_dev, &transaction, -ECANCELED, &pending_events, - &pending_fences); + &pending_fences, false); } } } |