summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeghana Barkalle <mbarkalle@google.com>2023-05-16 20:23:10 +0000
committerTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2023-12-13 16:36:31 +0000
commit3c3738fafc1c80d84ead3b586f72a05b7e26b32e (patch)
treee2df7c723c46cdcd4656d6df708f399b1d768c66
parentc8834e1ec22abf3964fcf07fcfe29ffa0af0cb50 (diff)
downloadlwis-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.c23
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);
}
}
}