diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2009-06-17 21:02:11 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-06-17 21:02:11 -0400 |
commit | 29a1bd6bf8c7a9ff511aaaf7e40fd6ca5198babe (patch) | |
tree | 03af95bef95d927742cd7a8349ae22c3320ff57c /fs | |
parent | 2ad780978b7c0c3e7877949f098cbd06e7c73839 (diff) |
NFS: Use xdr_stream-based XDR encoder for MNT's dirpath argument
Check the length of the supplied dirpath, and see that it fits
properly in the RPC buffer.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/mount_clnt.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index af45a374d56f..93361afcd5da 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -21,6 +21,21 @@ | |||
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * Defined by RFC 1094, section A.3; and RFC 1813, section 5.1.4 | ||
25 | */ | ||
26 | #define MNTPATHLEN (1024) | ||
27 | |||
28 | /* | ||
29 | * XDR data type sizes | ||
30 | */ | ||
31 | #define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN)) | ||
32 | |||
33 | /* | ||
34 | * XDR argument and result sizes | ||
35 | */ | ||
36 | #define MNT_enc_dirpath_sz encode_dirpath_sz | ||
37 | |||
38 | /* | ||
24 | * Defined by RFC 1094, section A.5 | 39 | * Defined by RFC 1094, section A.5 |
25 | */ | 40 | */ |
26 | enum { | 41 | enum { |
@@ -135,6 +150,31 @@ static int xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, | |||
135 | return 0; | 150 | return 0; |
136 | } | 151 | } |
137 | 152 | ||
153 | static int encode_mntdirpath(struct xdr_stream *xdr, const char *pathname) | ||
154 | { | ||
155 | const u32 pathname_len = strlen(pathname); | ||
156 | __be32 *p; | ||
157 | |||
158 | if (unlikely(pathname_len > MNTPATHLEN)) | ||
159 | return -EIO; | ||
160 | |||
161 | p = xdr_reserve_space(xdr, sizeof(u32) + pathname_len); | ||
162 | if (unlikely(p == NULL)) | ||
163 | return -EIO; | ||
164 | xdr_encode_opaque(p, pathname, pathname_len); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int mnt_enc_dirpath(struct rpc_rqst *req, __be32 *p, | ||
170 | const char *dirpath) | ||
171 | { | ||
172 | struct xdr_stream xdr; | ||
173 | |||
174 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | ||
175 | return encode_mntdirpath(&xdr, dirpath); | ||
176 | } | ||
177 | |||
138 | static int xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, | 178 | static int xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, |
139 | struct mnt_fhstatus *res) | 179 | struct mnt_fhstatus *res) |
140 | { | 180 | { |
@@ -164,16 +204,15 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, | |||
164 | return 0; | 204 | return 0; |
165 | } | 205 | } |
166 | 206 | ||
167 | #define MNT_dirpath_sz (1 + 256) | ||
168 | #define MNT_fhstatus_sz (1 + 8) | 207 | #define MNT_fhstatus_sz (1 + 8) |
169 | #define MNT_fhstatus3_sz (1 + 16) | 208 | #define MNT_fhstatus3_sz (1 + 16) |
170 | 209 | ||
171 | static struct rpc_procinfo mnt_procedures[] = { | 210 | static struct rpc_procinfo mnt_procedures[] = { |
172 | [MOUNTPROC_MNT] = { | 211 | [MOUNTPROC_MNT] = { |
173 | .p_proc = MOUNTPROC_MNT, | 212 | .p_proc = MOUNTPROC_MNT, |
174 | .p_encode = (kxdrproc_t) xdr_encode_dirpath, | 213 | .p_encode = (kxdrproc_t)mnt_enc_dirpath, |
175 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus, | 214 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus, |
176 | .p_arglen = MNT_dirpath_sz, | 215 | .p_arglen = MNT_enc_dirpath_sz, |
177 | .p_replen = MNT_fhstatus_sz, | 216 | .p_replen = MNT_fhstatus_sz, |
178 | .p_statidx = MOUNTPROC_MNT, | 217 | .p_statidx = MOUNTPROC_MNT, |
179 | .p_name = "MOUNT", | 218 | .p_name = "MOUNT", |
@@ -183,9 +222,9 @@ static struct rpc_procinfo mnt_procedures[] = { | |||
183 | static struct rpc_procinfo mnt3_procedures[] = { | 222 | static struct rpc_procinfo mnt3_procedures[] = { |
184 | [MOUNTPROC3_MNT] = { | 223 | [MOUNTPROC3_MNT] = { |
185 | .p_proc = MOUNTPROC3_MNT, | 224 | .p_proc = MOUNTPROC3_MNT, |
186 | .p_encode = (kxdrproc_t) xdr_encode_dirpath, | 225 | .p_encode = (kxdrproc_t)mnt_enc_dirpath, |
187 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus3, | 226 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus3, |
188 | .p_arglen = MNT_dirpath_sz, | 227 | .p_arglen = MNT_enc_dirpath_sz, |
189 | .p_replen = MNT_fhstatus3_sz, | 228 | .p_replen = MNT_fhstatus3_sz, |
190 | .p_statidx = MOUNTPROC3_MNT, | 229 | .p_statidx = MOUNTPROC3_MNT, |
191 | .p_name = "MOUNT", | 230 | .p_name = "MOUNT", |