From 2ead59f1678660d3366485396426b3d52d6876fd Mon Sep 17 00:00:00 2001 From: Arun Prakash Date: Fri, 23 Apr 2021 17:02:31 +0530 Subject: [PATCH] BACKPORT: 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 Signed-off-by: UtsavBalar1231 --- 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 2dd51d079102..8d657211098c 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -583,6 +583,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; @@ -695,12 +696,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); } @@ -721,15 +722,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); } @@ -782,6 +784,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);