From a8174f0e11af9019feabf8625385b0ae20bcd00b Mon Sep 17 00:00:00 2001 From: Arun Prakash Date: Fri, 23 Apr 2021 17:02:31 +0530 Subject: [PATCH] soc: qcom: smp2p: Fix possible smp2p entry double free In case of restore path there could be a chance that smp2p entry duble freed or valid entry might be uninitialized. Also fix entry deference after being freed by calling kfree(). Change-Id: I5dcb12e01972e19f3c0fa1fc1be3596abca984e9 Signed-off-by: Arun Prakash --- drivers/soc/qcom/smp2p.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 83cfd0f5947b..d93a2ca79ebc 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -573,6 +573,7 @@ static int smp2p_parse_ipc(struct qcom_smp2p *smp2p) static int qcom_smp2p_probe(struct platform_device *pdev) { struct smp2p_entry *entry; + struct smp2p_entry *next_entry; struct device_node *node; struct qcom_smp2p *smp2p; const char *key; @@ -686,12 +687,12 @@ unreg_ws: wakeup_source_unregister(smp2p->ws); unwind_interfaces: - list_for_each_entry(entry, &smp2p->inbound, node) { + list_for_each_entry_safe(entry, next_entry, &smp2p->inbound, node) { irq_domain_remove(entry->domain); kfree(entry); } - list_for_each_entry(entry, &smp2p->outbound, node) { + list_for_each_entry_safe(entry, next_entry, &smp2p->outbound, node) { qcom_smem_state_unregister(entry->state); kfree(entry); } @@ -712,15 +713,16 @@ static int qcom_smp2p_remove(struct platform_device *pdev) { struct qcom_smp2p *smp2p = platform_get_drvdata(pdev); struct smp2p_entry *entry; + struct smp2p_entry *next_entry; wakeup_source_unregister(smp2p->ws); - list_for_each_entry(entry, &smp2p->inbound, node) { + list_for_each_entry_safe(entry, next_entry, &smp2p->inbound, node) { irq_domain_remove(entry->domain); kfree(entry); } - list_for_each_entry(entry, &smp2p->outbound, node) { + list_for_each_entry_safe(entry, next_entry, &smp2p->outbound, node) { qcom_smem_state_unregister(entry->state); kfree(entry); } @@ -773,6 +775,7 @@ static int qcom_smp2p_restore(struct device *dev) enable_irq_wake(smp2p->irq); /* Kick the outgoing edge after allocating entries */ qcom_smp2p_kick(smp2p); + return ret; rel_entry: kfree(entry);