fs/nfs/dir.c | 15 --------------- fs/nfs/nfs3proc.c | 2 ++ fs/nfs/nfs4proc.c | 4 +++- fs/nfs/nfs4xdr.c | 35 ++++++++++++++++++++++++++++++++++- fs/nfs/proc.c | 2 ++ include/linux/nfs4.h | 2 ++ 6 files changed, 43 insertions(+), 17 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.7-04-access/fs/nfs/dir.c linux-2.6.7-05-fix_symlink/fs/nfs/dir.c --- linux-2.6.7-04-access/fs/nfs/dir.c 2004-06-13 20:53:28.000000000 -0400 +++ linux-2.6.7-05-fix_symlink/fs/nfs/dir.c 2004-06-13 20:53:33.000000000 -0400 @@ -1299,19 +1299,6 @@ nfs_symlink(struct inode *dir, struct de dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name, symname); - error = -ENAMETOOLONG; - switch (NFS_PROTO(dir)->version) { - case 2: - if (strlen(symname) > NFS2_MAXPATHLEN) - goto out; - break; - case 3: - if (strlen(symname) > NFS3_MAXPATHLEN) - goto out; - default: - break; - } - #ifdef NFS_PARANOIA if (dentry->d_inode) printk("nfs_proc_symlink: %s/%s not negative!\n", @@ -1341,8 +1328,6 @@ dentry->d_parent->d_name.name, dentry->d d_drop(dentry); } unlock_kernel(); - -out: return error; } diff -u --recursive --new-file --show-c-function linux-2.6.7-04-access/fs/nfs/nfs3proc.c linux-2.6.7-05-fix_symlink/fs/nfs/nfs3proc.c --- linux-2.6.7-04-access/fs/nfs/nfs3proc.c 2004-06-13 20:53:28.000000000 -0400 +++ linux-2.6.7-05-fix_symlink/fs/nfs/nfs3proc.c 2004-06-13 20:53:33.000000000 -0400 @@ -540,6 +540,8 @@ nfs3_proc_symlink(struct inode *dir, str }; int status; + if (path->len > NFS3_MAXPATHLEN) + return -ENAMETOOLONG; dprintk("NFS call symlink %s -> %s\n", name->name, path->name); dir_attr.valid = 0; fattr->valid = 0; diff -u --recursive --new-file --show-c-function linux-2.6.7-04-access/fs/nfs/nfs4proc.c linux-2.6.7-05-fix_symlink/fs/nfs/nfs4proc.c --- linux-2.6.7-04-access/fs/nfs/nfs4proc.c 2004-06-13 20:53:28.000000000 -0400 +++ linux-2.6.7-05-fix_symlink/fs/nfs/nfs4proc.c 2004-06-14 14:26:53.000000000 -0400 @@ -1092,12 +1092,14 @@ static int nfs4_proc_symlink(struct inod .fattr = fattr, }; struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK], .rpc_argp = &arg, .rpc_resp = &res, }; int status; + if (path->len > NFS4_MAXPATHLEN) + return -ENAMETOOLONG; arg.u.symlink = path; fattr->valid = 0; diff -u --recursive --new-file --show-c-function linux-2.6.7-04-access/fs/nfs/nfs4xdr.c linux-2.6.7-05-fix_symlink/fs/nfs/nfs4xdr.c --- linux-2.6.7-04-access/fs/nfs/nfs4xdr.c 2004-06-13 20:53:16.000000000 -0400 +++ linux-2.6.7-05-fix_symlink/fs/nfs/nfs4xdr.c 2004-06-13 20:53:33.000000000 -0400 @@ -84,6 +84,7 @@ static int nfs_stat_to_errno(int); ((3+NFS4_FHSIZE) >> 2)) #define encode_getattr_maxsz (op_encode_hdr_maxsz + 3) #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) +#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) #define nfs4_fattr_bitmap_maxsz (36 + 2 * nfs4_name_maxsz) #define decode_getattr_maxsz (op_decode_hdr_maxsz + 3 + \ nfs4_fattr_bitmap_maxsz) @@ -118,8 +119,13 @@ static int nfs_stat_to_errno(int); #define encode_link_maxsz (op_encode_hdr_maxsz + \ nfs4_name_maxsz) #define decode_link_maxsz (op_decode_hdr_maxsz + 5) +#define encode_symlink_maxsz (op_encode_hdr_maxsz + \ + 1 + nfs4_name_maxsz + \ + nfs4_path_maxsz + \ + nfs4_fattr_bitmap_maxsz) +#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) #define encode_create_maxsz (op_encode_hdr_maxsz + \ - 2 + 2 * nfs4_name_maxsz + \ + 2 + nfs4_name_maxsz + \ nfs4_fattr_bitmap_maxsz) #define decode_create_maxsz (op_decode_hdr_maxsz + 8) #define NFS4_enc_compound_sz (1024) /* XXX: large enough? */ @@ -313,6 +319,16 @@ static int nfs_stat_to_errno(int); decode_savefh_maxsz + \ decode_putfh_maxsz + \ decode_link_maxsz) +#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_symlink_maxsz + \ + encode_getattr_maxsz + \ + encode_getfh_maxsz) +#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + decode_symlink_maxsz + \ + decode_getattr_maxsz + \ + decode_getfh_maxsz) #define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_create_maxsz + \ @@ -1244,6 +1260,14 @@ out: } /* + * Encode SYMLINK request + */ +static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args) +{ + return nfs4_xdr_enc_create(req, p, args); +} + +/* * Encode GETATTR request */ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct nfs4_getattr_arg *args) @@ -3222,6 +3246,14 @@ out: } /* + * Decode SYMLINK response + */ +static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res) +{ + return nfs4_xdr_dec_create(rqstp, p, res); +} + +/* * Decode GETATTR response */ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_getattr_res *res) @@ -3804,6 +3836,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(REMOVE, enc_remove, dec_remove), PROC(RENAME, enc_rename, dec_rename), PROC(LINK, enc_link, dec_link), + PROC(SYMLINK, enc_symlink, dec_symlink), PROC(CREATE, enc_create, dec_create), PROC(PATHCONF, enc_pathconf, dec_pathconf), PROC(STATFS, enc_statfs, dec_statfs), diff -u --recursive --new-file --show-c-function linux-2.6.7-04-access/fs/nfs/proc.c linux-2.6.7-05-fix_symlink/fs/nfs/proc.c --- linux-2.6.7-04-access/fs/nfs/proc.c 2004-06-13 11:59:26.000000000 -0400 +++ linux-2.6.7-05-fix_symlink/fs/nfs/proc.c 2004-06-13 20:53:33.000000000 -0400 @@ -400,6 +400,8 @@ nfs_proc_symlink(struct inode *dir, stru }; int status; + if (path->len > NFS2_MAXPATHLEN) + return -ENAMETOOLONG; dprintk("NFS call symlink %s -> %s\n", name->name, path->name); fattr->valid = 0; status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0); diff -u --recursive --new-file --show-c-function linux-2.6.7-04-access/include/linux/nfs4.h linux-2.6.7-05-fix_symlink/include/linux/nfs4.h --- linux-2.6.7-04-access/include/linux/nfs4.h 2004-06-13 11:58:38.000000000 -0400 +++ linux-2.6.7-05-fix_symlink/include/linux/nfs4.h 2004-06-13 20:53:33.000000000 -0400 @@ -15,6 +15,7 @@ #define NFS4_VERIFIER_SIZE 8 #define NFS4_FHSIZE 128 +#define NFS4_MAXPATHLEN PATH_MAX #define NFS4_MAXNAMLEN NAME_MAX #define NFS4_ACCESS_READ 0x0001 @@ -315,6 +316,7 @@ enum { NFSPROC4_CLNT_REMOVE, NFSPROC4_CLNT_RENAME, NFSPROC4_CLNT_LINK, + NFSPROC4_CLNT_SYMLINK, NFSPROC4_CLNT_CREATE, NFSPROC4_CLNT_PATHCONF, NFSPROC4_CLNT_STATFS,