Commit 9affa435 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd4: fix NULL dereference in nfsd/clients display code



We hold the cl_lock here, and that's enough to keep stateid's from going
away, but it's not enough to prevent the files they point to from going
away.  Take fi_lock and a reference and check for NULL, as we do in
other code.

Reported-by: default avatarNeilBrown <neilb@suse.de>
Fixes: 78599c42 ("nfsd4: add file to display list of client's opens")
Reviewed-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent becd2014
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -507,6 +507,17 @@ find_any_file(struct nfs4_file *f)
	return ret;
}

static struct nfsd_file *find_deleg_file(struct nfs4_file *f)
{
	struct nfsd_file *ret = NULL;

	spin_lock(&f->fi_lock);
	if (f->fi_deleg_file)
		ret = nfsd_file_get(f->fi_deleg_file);
	spin_unlock(&f->fi_lock);
	return ret;
}

static atomic_long_t num_delegations;
unsigned long max_delegations;

@@ -2444,6 +2455,8 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
	oo = ols->st_stateowner;
	nf = st->sc_file;
	file = find_any_file(nf);
	if (!file)
		return 0;

	seq_printf(s, "- ");
	nfs4_show_stateid(s, &st->sc_stateid);
@@ -2481,6 +2494,8 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
	oo = ols->st_stateowner;
	nf = st->sc_file;
	file = find_any_file(nf);
	if (!file)
		return 0;

	seq_printf(s, "- ");
	nfs4_show_stateid(s, &st->sc_stateid);
@@ -2513,7 +2528,9 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)

	ds = delegstateid(st);
	nf = st->sc_file;
	file = nf->fi_deleg_file;
	file = find_deleg_file(nf);
	if (!file)
		return 0;

	seq_printf(s, "- ");
	nfs4_show_stateid(s, &st->sc_stateid);
@@ -2529,6 +2546,7 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
	seq_printf(s, ", ");
	nfs4_show_fname(s, file);
	seq_printf(s, " }\n");
	nfsd_file_put(file);

	return 0;
}