From: Trond Myklebust <trond.myklebust@fys.uio.no>
To: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Cc: Michal Piotrowski <michal.k.k.piotrowski@gmail.com>,
bfields@fieldses.org, neilb@suse.de, nfs@lists.sourceforge.net,
linux-kernel@vger.kernel.org
Subject: Re: [NFS] [BUG] 2.6.23-rc5 kernel BUG at fs/nfs/nfs4xdr.c:945
Date: Mon, 24 Sep 2007 17:26:12 -0400 [thread overview]
Message-ID: <1190669172.6700.20.camel@heimdal.trondhjem.org> (raw)
In-Reply-To: <46F80991.6010001@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 912 bytes --]
On Tue, 2007-09-25 at 00:31 +0530, Kamalesh Babulal wrote:
> > I'm mystified. I'm quite unable to reproduce this on my own setup: the
> > ENAMETOOLONG error reporting mechanism prevents me from even getting
> > near the above bug.
> >
> > Could you add a little printk into the 'encode_lookup' routine on line
> > 944 of fs/nfs/nfs4xdr.c to display the value of 'len'?
> >
> > Cheers
> > Trond
>
> Hi Trond,
>
> Sorry, for replying so late, i have included the printk as you have requested.
>
> len passed on encode_lookup [811]RESERVE_SPACE(819) failed in function encode_lookup
OK. That is definitely wrong! We shouldn't be allowing anything > 255
according to <limits.h>.
Looks like that code in fs/nfs/client.c has been wrong since its
inception in 2.6.18. Not only for NFSv4, but for NFSv2 and v3 too. We
only caught it 'cos v4 has more stringent tests...
Take two on the patch attached...
Trond
[-- Attachment #2: linux-2.6.23-002-fix_nfs4_namelen.dif --]
[-- Type: message/rfc822, Size: 4082 bytes --]
From: Trond Myklebust <Trond.Myklebust@netapp.com>
Subject: No Subject
Date: Sun, 9 Sep 2007 00:10:51 +0200
Message-ID: <1190669172.6700.21.camel@heimdal.trondhjem.org>
It doesn't look as if the NFS file name limit is being initialised correctly
in the struct nfs_server. Make sure that we limit whatever is being set in
nfs_probe_fsinfo() and nfs_init_server().
Also ensure that readdirplus and nfs4_path_walk respect our file name
limits.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
fs/nfs/client.c | 29 +++++++++++++++++++----------
fs/nfs/dir.c | 2 ++
fs/nfs/getroot.c | 3 +++
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index a49f9fe..a204484 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -588,16 +588,6 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
server->namelen = data->namlen;
/* Create a client RPC handle for the NFSv3 ACL management interface */
nfs_init_server_aclclient(server);
- if (clp->cl_nfsversion == 3) {
- if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
- server->namelen = NFS3_MAXNAMLEN;
- if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
- server->caps |= NFS_CAP_READDIRPLUS;
- } else {
- if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
- server->namelen = NFS2_MAXNAMLEN;
- }
-
dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
return 0;
@@ -794,6 +784,16 @@ struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
error = nfs_probe_fsinfo(server, mntfh, &fattr);
if (error < 0)
goto error;
+ if (server->nfs_client->rpc_ops->version == 3) {
+ if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
+ server->namelen = NFS3_MAXNAMLEN;
+ if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
+ server->caps |= NFS_CAP_READDIRPLUS;
+ } else {
+ if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
+ server->namelen = NFS2_MAXNAMLEN;
+ }
+
if (!(fattr.valid & NFS_ATTR_FATTR)) {
error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
if (error < 0) {
@@ -984,6 +984,9 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
if (error < 0)
goto error;
+ if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+ server->namelen = NFS4_MAXNAMLEN;
+
BUG_ON(!server->nfs_client);
BUG_ON(!server->nfs_client->rpc_ops);
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
@@ -1056,6 +1059,9 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
if (error < 0)
goto error;
+ if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+ server->namelen = NFS4_MAXNAMLEN;
+
dprintk("Referral FSID: %llx:%llx\n",
(unsigned long long) server->fsid.major,
(unsigned long long) server->fsid.minor);
@@ -1115,6 +1121,9 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
if (error < 0)
goto out_free_server;
+ if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
+ server->namelen = NFS4_MAXNAMLEN;
+
dprintk("Cloned FSID: %llx:%llx\n",
(unsigned long long) server->fsid.major,
(unsigned long long) server->fsid.minor);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ea97408..e4a04d1 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1162,6 +1162,8 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
}
if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))
return NULL;
+ if (name.len > NFS_SERVER(dir)->namelen)
+ return NULL;
/* Note: caller is already holding the dir->i_mutex! */
dentry = d_alloc(parent, &name);
if (dentry == NULL)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index d1cbf0a..522e5ad 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -175,6 +175,9 @@ next_component:
path++;
name.len = path - (const char *) name.name;
+ if (name.len > NFS4_MAXNAMLEN)
+ return -ENAMETOOLONG;
+
eat_dot_dir:
while (*path == '/')
path++;
next prev parent reply other threads:[~2007-09-24 21:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-07 10:02 Kamalesh Babulal
2007-09-07 15:29 ` J. Bruce Fields
2007-09-10 18:02 ` Kamalesh Babulal
2007-09-07 23:56 ` Michal Piotrowski
2007-09-08 22:12 ` [NFS] " Trond Myklebust
2007-09-10 8:11 ` suzuki
2007-09-10 21:03 ` Trond Myklebust
2007-09-11 4:56 ` suzuki
2007-09-10 13:06 ` Kamalesh Babulal
2007-09-19 17:31 ` Trond Myklebust
2007-09-24 19:01 ` Kamalesh Babulal
2007-09-24 21:26 ` Trond Myklebust [this message]
2007-09-28 12:05 ` Kamalesh Babulal
2007-09-10 12:56 ` Kamalesh Babulal
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=1190669172.6700.20.camel@heimdal.trondhjem.org \
--to=trond.myklebust@fys.uio.no \
--cc=bfields@fieldses.org \
--cc=kamalesh@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.k.k.piotrowski@gmail.com \
--cc=neilb@suse.de \
--cc=nfs@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®