summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorZhengchuan Liang <zcliangcn@gmail.com>2026-04-11 23:10:26 +0800
committerPaolo Abeni <pabeni@redhat.com>2026-04-14 13:21:54 +0200
commitf7cf8ece8cee3c1ee361991470cdb1eb65ab02e8 (patch)
treebc09837d2aa45bac11c552851e40e5870538876e
parentfe72340daaf1af588be88056faf98965f39e6032 (diff)
downloadwireguard-linux-f7cf8ece8cee3c1ee361991470cdb1eb65ab02e8.tar.xz
wireguard-linux-f7cf8ece8cee3c1ee361991470cdb1eb65ab02e8.zip
net: caif: clear client service pointer on teardown
`caif_connect()` can tear down an existing client after remote shutdown by calling `caif_disconnect_client()` followed by `caif_free_client()`. `caif_free_client()` releases the service layer referenced by `adap_layer->dn`, but leaves that pointer stale. When the socket is later destroyed, `caif_sock_destructor()` calls `caif_free_client()` again and dereferences the freed service pointer. Clear the client/service links before releasing the service object so repeated teardown becomes harmless. Fixes: 43e369210108 ("caif: Move refcount from service layer to sock and dev.") Cc: stable@kernel.org Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Co-developed-by: Yuan Tan <yuantan098@gmail.com> Signed-off-by: Yuan Tan <yuantan098@gmail.com> Suggested-by: Xin Liu <bird@lzu.edu.cn> Tested-by: Ren Wei <enjou1224z@gmail.com> Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Link: https://patch.msgid.link/9f3d37847c0037568aae698ca23cd47c6691acb0.1775897577.git.zcliangcn@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--net/caif/cfsrvl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c
index 171fa32ada85..d687fd0b4ed3 100644
--- a/net/caif/cfsrvl.c
+++ b/net/caif/cfsrvl.c
@@ -191,10 +191,20 @@ bool cfsrvl_phyid_match(struct cflayer *layer, int phyid)
void caif_free_client(struct cflayer *adap_layer)
{
+ struct cflayer *serv_layer;
struct cfsrvl *servl;
- if (adap_layer == NULL || adap_layer->dn == NULL)
+
+ if (!adap_layer)
+ return;
+
+ serv_layer = adap_layer->dn;
+ if (!serv_layer)
return;
- servl = container_obj(adap_layer->dn);
+
+ layer_set_dn(adap_layer, NULL);
+ layer_set_up(serv_layer, NULL);
+
+ servl = container_obj(serv_layer);
servl->release(&servl->layer);
}
EXPORT_SYMBOL(caif_free_client);