[PATCH 2/2] 9p: destroy client in symmetric order

From: Leon Romanovsky
Date: Thu Sep 29 2022 - 05:38:28 EST


Make sure that all variables are initialized and released in correct
order.

Reported-by: syzbot+de52531662ebb8823b26@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Leon Romanovsky <leon@xxxxxxxxxx>
---
net/9p/client.c | 37 ++++++++++++-------------------------
1 file changed, 12 insertions(+), 25 deletions(-)

diff --git a/net/9p/client.c b/net/9p/client.c
index aaa37b07e30a..8277e33506e7 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -179,7 +179,6 @@ static int parse_opts(char *opts, struct p9_client *clnt)
goto free_and_return;
}

- v9fs_put_trans(clnt->trans_mod);
clnt->trans_mod = v9fs_get_trans_by_name(s);
if (!clnt->trans_mod) {
pr_info("Could not find request transport: %s\n",
@@ -187,7 +186,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
ret = -EINVAL;
}
kfree(s);
- break;
+ goto free_and_return;
case Opt_legacy:
clnt->proto_version = p9_proto_legacy;
break;
@@ -211,9 +210,14 @@ static int parse_opts(char *opts, struct p9_client *clnt)
}
}

+ clnt->trans_mod = v9fs_get_default_trans();
+ if (!clnt->trans_mod) {
+ ret = -EPROTONOSUPPORT;
+ p9_debug(P9_DEBUG_ERROR,
+ "No transport defined or default transport\n");
+ }
+
free_and_return:
- if (ret)
- v9fs_put_trans(clnt->trans_mod);
kfree(tmp_options);
return ret;
}
@@ -956,19 +960,14 @@ static int p9_client_version(struct p9_client *c)

struct p9_client *p9_client_create(const char *dev_name, char *options)
{
- int err;
struct p9_client *clnt;
char *client_id;
+ int err = 0;

- err = 0;
- clnt = kmalloc(sizeof(*clnt), GFP_KERNEL);
+ clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
if (!clnt)
return ERR_PTR(-ENOMEM);

- clnt->trans_mod = NULL;
- clnt->trans = NULL;
- clnt->fcall_cache = NULL;
-
client_id = utsname()->nodename;
memcpy(clnt->name, client_id, strlen(client_id) + 1);

@@ -980,16 +979,6 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
if (err < 0)
goto free_client;

- if (!clnt->trans_mod)
- clnt->trans_mod = v9fs_get_default_trans();
-
- if (!clnt->trans_mod) {
- err = -EPROTONOSUPPORT;
- p9_debug(P9_DEBUG_ERROR,
- "No transport defined or default transport\n");
- goto free_client;
- }
-
p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);

@@ -1044,9 +1033,8 @@ void p9_client_destroy(struct p9_client *clnt)

p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt);

- if (clnt->trans_mod)
- clnt->trans_mod->close(clnt);
-
+ kmem_cache_destroy(clnt->fcall_cache);
+ clnt->trans_mod->close(clnt);
v9fs_put_trans(clnt->trans_mod);

idr_for_each_entry(&clnt->fids, fid, id) {
@@ -1056,7 +1044,6 @@ void p9_client_destroy(struct p9_client *clnt)

p9_tag_cleanup(clnt);

- kmem_cache_destroy(clnt->fcall_cache);
kfree(clnt);
}
EXPORT_SYMBOL(p9_client_destroy);
--
2.37.3