All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dominique Martinet <asmadeus@codewreck.org>
To: Leon Romanovsky <leon@kernel.org>
Cc: v9fs-developer@lists.sourceforge.net, linux_oss@crudebyte.com,
	linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com,
	syzbot+67d13108d855f451cafc@syzkaller.appspotmail.com,
	davem@davemloft.net, edumazet@google.com, ericvh@gmail.com,
	kuba@kernel.org, lucho@ionkov.net, netdev@vger.kernel.org,
	syzbot+de52531662ebb8823b26@syzkaller.appspotmail.com
Subject: Re: [PATCH 2/2] 9p: destroy client in symmetric order
Date: Thu, 29 Sep 2022 19:29:33 +0900	[thread overview]
Message-ID: <YzVzjR4Yz3Oo3JS+@codewreck.org> (raw)
In-Reply-To: <743fc62b2e8d15c84e234744e3f3f136c467752d.1664442592.git.leonro@nvidia.com>

Leon Romanovsky wrote on Thu, Sep 29, 2022 at 12:37:56PM +0300:
> Make sure that all variables are initialized and released in correct
> order.

Haven't tried running or compiling, comments out of my head that might
be wrong below

> 
> Reported-by: syzbot+de52531662ebb8823b26@syzkaller.appspotmail.com

You're adding this report tag but I don't see how you fix that failure.
What you need is p9_tag_cleanup(clnt) from p9_client_destroy -- I assume
this isn't possible for any fid to be allocated at this point so the fid
destroying loop is -probably- optional.

I would assume it is needed from p9_client_version failures.


> Signed-off-by: Leon Romanovsky <leon@kernel.org>
> ---
>  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);

Pretty sure you'll be "leaking transports" if someone tries to pass
trans=foo multiple times; this can't be removed...(continues below)...


>  			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;

... unless you also break the whole parsing, with this asking for -o
trans=virtio,msize=1M will just ignore the msize argument.
(or anything else that follows)

I appreciate that you're trying to avoid the get_default_trans below,
but unless you just remember the last string and try to get it get/put
trans is the most straight forward way to go.


(Note you just got me to try weird parsing and my old version was
double-puting these modules because of the put_trans below in this
function echoes with the client destroy. That'd just require removing
the put here though (or nulling after put), yet another invariant I had
wrongly assumed... Anyway.)


>  		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);

(oh, and if you parse options after trans= you'll need some sort of
escape hatch here...)

>  	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);

Pretty sure kmem_cache used to issue a warning when we did that (hence
me trying to move it up on allocation) -- at this point there can still
be in flight requests we need to finish freeing before we can destroy
the 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);

--
Dominique

  reply	other threads:[~2022-09-29 10:30 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-29  9:37 [PATCH 0/2] Fix to latest syzkaller bugs in 9p area Leon Romanovsky
2022-09-29  9:37 ` [PATCH 1/2] Revert "9p: p9_client_create: use p9_client_destroy on failure" Leon Romanovsky
2022-10-04 13:10   ` Dan Carpenter
2022-10-04 21:01     ` Dominique Martinet
2022-10-06 16:19       ` Leon Romanovsky
2022-09-29  9:37 ` [PATCH 2/2] 9p: destroy client in symmetric order Leon Romanovsky
2022-09-29 10:29   ` Dominique Martinet [this message]
2022-09-29 10:53     ` Leon Romanovsky
2022-10-04 13:03       ` Christian Schoenebeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YzVzjR4Yz3Oo3JS+@codewreck.org \
    --to=asmadeus@codewreck.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=ericvh@gmail.com \
    --cc=kuba@kernel.org \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux_oss@crudebyte.com \
    --cc=lucho@ionkov.net \
    --cc=netdev@vger.kernel.org \
    --cc=syzbot+67d13108d855f451cafc@syzkaller.appspotmail.com \
    --cc=syzbot+de52531662ebb8823b26@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=v9fs-developer@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.