2004-04-16 21:17:25

by Dave Jones

[permalink] [raw]
Subject: NFS thinko

Dereferencing 'exp' before the check for NULL.

Dave


--- linux-2.6.5/include/linux/nfsd/export.h~ 2004-04-16 22:13:28.000000000 +0100
+++ linux-2.6.5/include/linux/nfsd/export.h 2004-04-16 22:14:21.000000000 +0100
@@ -118,13 +118,15 @@
if (ek && !IS_ERR(ek)) {
struct svc_export *exp = ek->ek_export;
int err;
+ if (!exp)
+ goto out;
cache_get(&exp->h);
expkey_put(&ek->h, &svc_expkey_cache);
- if (exp &&
- (err = cache_check(&svc_export_cache, &exp->h, reqp)))
+ if (err = cache_check(&svc_export_cache, &exp->h, reqp))
exp = ERR_PTR(err);
return exp;
} else
+out:
return ERR_PTR(PTR_ERR(ek));
}


2004-04-16 21:35:30

by Russell King

[permalink] [raw]
Subject: Re: NFS thinko

On Fri, Apr 16, 2004 at 10:16:28PM +0100, Dave Jones wrote:
> Dereferencing 'exp' before the check for NULL.

Hmm. If we're referencing 'ek' to get at exp, 'ek' isn't an error,
so it shouldn't be passed into PTR_ERR().

> --- linux-2.6.5/include/linux/nfsd/export.h~ 2004-04-16 22:13:28.000000000 +0100
> +++ linux-2.6.5/include/linux/nfsd/export.h 2004-04-16 22:14:21.000000000 +0100
> @@ -118,13 +118,15 @@
> if (ek && !IS_ERR(ek)) {
> struct svc_export *exp = ek->ek_export;
> int err;
> + if (!exp)
> + goto out;
> cache_get(&exp->h);
> expkey_put(&ek->h, &svc_expkey_cache);
> - if (exp &&
> - (err = cache_check(&svc_export_cache, &exp->h, reqp)))
> + if (err = cache_check(&svc_export_cache, &exp->h, reqp))
> exp = ERR_PTR(err);
> return exp;
> } else
> +out:
> return ERR_PTR(PTR_ERR(ek));
> }

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core

2004-04-16 22:15:14

by J. Bruce Fields

[permalink] [raw]
Subject: Re: NFS thinko

On Fri, Apr 16, 2004 at 10:16:28PM +0100, Dave Jones wrote:
> Dereferencing 'exp' before the check for NULL.

It would be a bug if exp were ever NULL there. Better just to delete
that check entirely.

--Bruce Fields


If ek = exp_find_key() is not an error, then ek->ek_export should be
set; no point in checking if it's NULL.


include/linux/nfsd/export.h | 3 +--
1 files changed, 1 insertion(+), 2 deletions(-)

diff -puN include/linux/nfsd/export.h~export_exp_deref_fix include/linux/nfsd/export.h
--- linux-2.6.6-rc1/include/linux/nfsd/export.h~export_exp_deref_fix 2004-04-16 17:51:57.000000000 -0400
+++ linux-2.6.6-rc1-bfields/include/linux/nfsd/export.h 2004-04-16 17:58:30.000000000 -0400
@@ -120,8 +120,7 @@ exp_find(struct auth_domain *clp, int fs
int err;
cache_get(&exp->h);
expkey_put(&ek->h, &svc_expkey_cache);
- if (exp &&
- (err = cache_check(&svc_export_cache, &exp->h, reqp)))
+ if ((err = cache_check(&svc_export_cache, &exp->h, reqp)))
exp = ERR_PTR(err);
return exp;
} else

_