diff options
-rw-r--r-- | fs/lockd/clnt4xdr.c | 14 | ||||
-rw-r--r-- | fs/lockd/clntxdr.c | 14 | ||||
-rw-r--r-- | fs/nfs/callback_xdr.c | 59 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 84 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 163 | ||||
-rw-r--r-- | fs/nfs/nfs42xdr.c | 21 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 451 | ||||
-rw-r--r-- | fs/nfsd/nfs4callback.c | 13 |
8 files changed, 219 insertions, 600 deletions
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index 214a2fa1f1e3..7df6324ccb8a 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c | |||
@@ -75,17 +75,6 @@ static void nlm4_compute_offsets(const struct nlm_lock *lock, | |||
75 | } | 75 | } |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * Handle decode buffer overflows out-of-line. | ||
79 | */ | ||
80 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | ||
81 | { | ||
82 | dprintk("lockd: %s prematurely hit the end of our receive buffer. " | ||
83 | "Remaining buffer length is %tu words.\n", | ||
84 | func, xdr->end - xdr->p); | ||
85 | } | ||
86 | |||
87 | |||
88 | /* | ||
89 | * Encode/decode NLMv4 basic data types | 78 | * Encode/decode NLMv4 basic data types |
90 | * | 79 | * |
91 | * Basic NLMv4 data types are defined in Appendix II, section 6.1.4 | 80 | * Basic NLMv4 data types are defined in Appendix II, section 6.1.4 |
@@ -176,7 +165,6 @@ out_size: | |||
176 | dprintk("NFS: returned cookie was too long: %u\n", length); | 165 | dprintk("NFS: returned cookie was too long: %u\n", length); |
177 | return -EIO; | 166 | return -EIO; |
178 | out_overflow: | 167 | out_overflow: |
179 | print_overflow_msg(__func__, xdr); | ||
180 | return -EIO; | 168 | return -EIO; |
181 | } | 169 | } |
182 | 170 | ||
@@ -236,7 +224,6 @@ out_bad_xdr: | |||
236 | __func__, be32_to_cpup(p)); | 224 | __func__, be32_to_cpup(p)); |
237 | return -EIO; | 225 | return -EIO; |
238 | out_overflow: | 226 | out_overflow: |
239 | print_overflow_msg(__func__, xdr); | ||
240 | return -EIO; | 227 | return -EIO; |
241 | } | 228 | } |
242 | 229 | ||
@@ -309,7 +296,6 @@ static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result) | |||
309 | out: | 296 | out: |
310 | return error; | 297 | return error; |
311 | out_overflow: | 298 | out_overflow: |
312 | print_overflow_msg(__func__, xdr); | ||
313 | return -EIO; | 299 | return -EIO; |
314 | } | 300 | } |
315 | 301 | ||
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index 747b9c8c940a..4df62f635529 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c | |||
@@ -71,17 +71,6 @@ static void nlm_compute_offsets(const struct nlm_lock *lock, | |||
71 | } | 71 | } |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * Handle decode buffer overflows out-of-line. | ||
75 | */ | ||
76 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | ||
77 | { | ||
78 | dprintk("lockd: %s prematurely hit the end of our receive buffer. " | ||
79 | "Remaining buffer length is %tu words.\n", | ||
80 | func, xdr->end - xdr->p); | ||
81 | } | ||
82 | |||
83 | |||
84 | /* | ||
85 | * Encode/decode NLMv3 basic data types | 74 | * Encode/decode NLMv3 basic data types |
86 | * | 75 | * |
87 | * Basic NLMv3 data types are not defined in an IETF standards | 76 | * Basic NLMv3 data types are not defined in an IETF standards |
@@ -173,7 +162,6 @@ out_size: | |||
173 | dprintk("NFS: returned cookie was too long: %u\n", length); | 162 | dprintk("NFS: returned cookie was too long: %u\n", length); |
174 | return -EIO; | 163 | return -EIO; |
175 | out_overflow: | 164 | out_overflow: |
176 | print_overflow_msg(__func__, xdr); | ||
177 | return -EIO; | 165 | return -EIO; |
178 | } | 166 | } |
179 | 167 | ||
@@ -231,7 +219,6 @@ out_enum: | |||
231 | __func__, be32_to_cpup(p)); | 219 | __func__, be32_to_cpup(p)); |
232 | return -EIO; | 220 | return -EIO; |
233 | out_overflow: | 221 | out_overflow: |
234 | print_overflow_msg(__func__, xdr); | ||
235 | return -EIO; | 222 | return -EIO; |
236 | } | 223 | } |
237 | 224 | ||
@@ -303,7 +290,6 @@ static int decode_nlm_holder(struct xdr_stream *xdr, struct nlm_res *result) | |||
303 | out: | 290 | out: |
304 | return error; | 291 | return error; |
305 | out_overflow: | 292 | out_overflow: |
306 | print_overflow_msg(__func__, xdr); | ||
307 | return -EIO; | 293 | return -EIO; |
308 | } | 294 | } |
309 | 295 | ||
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index bc7c1766a2be..06233bfa6d73 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -72,16 +72,6 @@ static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p) | |||
72 | return xdr_ressize_check(rqstp, p); | 72 | return xdr_ressize_check(rqstp, p); |
73 | } | 73 | } |
74 | 74 | ||
75 | static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes) | ||
76 | { | ||
77 | __be32 *p; | ||
78 | |||
79 | p = xdr_inline_decode(xdr, nbytes); | ||
80 | if (unlikely(p == NULL)) | ||
81 | printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n"); | ||
82 | return p; | ||
83 | } | ||
84 | |||
85 | static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, | 75 | static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, |
86 | const char **str, size_t maxlen) | 76 | const char **str, size_t maxlen) |
87 | { | 77 | { |
@@ -98,13 +88,13 @@ static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
98 | { | 88 | { |
99 | __be32 *p; | 89 | __be32 *p; |
100 | 90 | ||
101 | p = read_buf(xdr, 4); | 91 | p = xdr_inline_decode(xdr, 4); |
102 | if (unlikely(p == NULL)) | 92 | if (unlikely(p == NULL)) |
103 | return htonl(NFS4ERR_RESOURCE); | 93 | return htonl(NFS4ERR_RESOURCE); |
104 | fh->size = ntohl(*p); | 94 | fh->size = ntohl(*p); |
105 | if (fh->size > NFS4_FHSIZE) | 95 | if (fh->size > NFS4_FHSIZE) |
106 | return htonl(NFS4ERR_BADHANDLE); | 96 | return htonl(NFS4ERR_BADHANDLE); |
107 | p = read_buf(xdr, fh->size); | 97 | p = xdr_inline_decode(xdr, fh->size); |
108 | if (unlikely(p == NULL)) | 98 | if (unlikely(p == NULL)) |
109 | return htonl(NFS4ERR_RESOURCE); | 99 | return htonl(NFS4ERR_RESOURCE); |
110 | memcpy(&fh->data[0], p, fh->size); | 100 | memcpy(&fh->data[0], p, fh->size); |
@@ -117,11 +107,11 @@ static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | |||
117 | __be32 *p; | 107 | __be32 *p; |
118 | unsigned int attrlen; | 108 | unsigned int attrlen; |
119 | 109 | ||
120 | p = read_buf(xdr, 4); | 110 | p = xdr_inline_decode(xdr, 4); |
121 | if (unlikely(p == NULL)) | 111 | if (unlikely(p == NULL)) |
122 | return htonl(NFS4ERR_RESOURCE); | 112 | return htonl(NFS4ERR_RESOURCE); |
123 | attrlen = ntohl(*p); | 113 | attrlen = ntohl(*p); |
124 | p = read_buf(xdr, attrlen << 2); | 114 | p = xdr_inline_decode(xdr, attrlen << 2); |
125 | if (unlikely(p == NULL)) | 115 | if (unlikely(p == NULL)) |
126 | return htonl(NFS4ERR_RESOURCE); | 116 | return htonl(NFS4ERR_RESOURCE); |
127 | if (likely(attrlen > 0)) | 117 | if (likely(attrlen > 0)) |
@@ -135,7 +125,7 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) | |||
135 | { | 125 | { |
136 | __be32 *p; | 126 | __be32 *p; |
137 | 127 | ||
138 | p = read_buf(xdr, NFS4_STATEID_SIZE); | 128 | p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE); |
139 | if (unlikely(p == NULL)) | 129 | if (unlikely(p == NULL)) |
140 | return htonl(NFS4ERR_RESOURCE); | 130 | return htonl(NFS4ERR_RESOURCE); |
141 | memcpy(stateid->data, p, NFS4_STATEID_SIZE); | 131 | memcpy(stateid->data, p, NFS4_STATEID_SIZE); |
@@ -156,7 +146,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound | |||
156 | status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ); | 146 | status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ); |
157 | if (unlikely(status != 0)) | 147 | if (unlikely(status != 0)) |
158 | return status; | 148 | return status; |
159 | p = read_buf(xdr, 12); | 149 | p = xdr_inline_decode(xdr, 12); |
160 | if (unlikely(p == NULL)) | 150 | if (unlikely(p == NULL)) |
161 | return htonl(NFS4ERR_RESOURCE); | 151 | return htonl(NFS4ERR_RESOURCE); |
162 | hdr->minorversion = ntohl(*p++); | 152 | hdr->minorversion = ntohl(*p++); |
@@ -176,7 +166,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound | |||
176 | static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) | 166 | static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) |
177 | { | 167 | { |
178 | __be32 *p; | 168 | __be32 *p; |
179 | p = read_buf(xdr, 4); | 169 | p = xdr_inline_decode(xdr, 4); |
180 | if (unlikely(p == NULL)) | 170 | if (unlikely(p == NULL)) |
181 | return htonl(NFS4ERR_RESOURCE_HDR); | 171 | return htonl(NFS4ERR_RESOURCE_HDR); |
182 | *op = ntohl(*p); | 172 | *op = ntohl(*p); |
@@ -205,7 +195,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, | |||
205 | status = decode_delegation_stateid(xdr, &args->stateid); | 195 | status = decode_delegation_stateid(xdr, &args->stateid); |
206 | if (unlikely(status != 0)) | 196 | if (unlikely(status != 0)) |
207 | return status; | 197 | return status; |
208 | p = read_buf(xdr, 4); | 198 | p = xdr_inline_decode(xdr, 4); |
209 | if (unlikely(p == NULL)) | 199 | if (unlikely(p == NULL)) |
210 | return htonl(NFS4ERR_RESOURCE); | 200 | return htonl(NFS4ERR_RESOURCE); |
211 | args->truncate = ntohl(*p); | 201 | args->truncate = ntohl(*p); |
@@ -227,7 +217,7 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, | |||
227 | __be32 status = 0; | 217 | __be32 status = 0; |
228 | uint32_t iomode; | 218 | uint32_t iomode; |
229 | 219 | ||
230 | p = read_buf(xdr, 4 * sizeof(uint32_t)); | 220 | p = xdr_inline_decode(xdr, 4 * sizeof(uint32_t)); |
231 | if (unlikely(p == NULL)) | 221 | if (unlikely(p == NULL)) |
232 | return htonl(NFS4ERR_BADXDR); | 222 | return htonl(NFS4ERR_BADXDR); |
233 | 223 | ||
@@ -245,14 +235,14 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, | |||
245 | if (unlikely(status != 0)) | 235 | if (unlikely(status != 0)) |
246 | return status; | 236 | return status; |
247 | 237 | ||
248 | p = read_buf(xdr, 2 * sizeof(uint64_t)); | 238 | p = xdr_inline_decode(xdr, 2 * sizeof(uint64_t)); |
249 | if (unlikely(p == NULL)) | 239 | if (unlikely(p == NULL)) |
250 | return htonl(NFS4ERR_BADXDR); | 240 | return htonl(NFS4ERR_BADXDR); |
251 | p = xdr_decode_hyper(p, &args->cbl_range.offset); | 241 | p = xdr_decode_hyper(p, &args->cbl_range.offset); |
252 | p = xdr_decode_hyper(p, &args->cbl_range.length); | 242 | p = xdr_decode_hyper(p, &args->cbl_range.length); |
253 | return decode_layout_stateid(xdr, &args->cbl_stateid); | 243 | return decode_layout_stateid(xdr, &args->cbl_stateid); |
254 | } else if (args->cbl_recall_type == RETURN_FSID) { | 244 | } else if (args->cbl_recall_type == RETURN_FSID) { |
255 | p = read_buf(xdr, 2 * sizeof(uint64_t)); | 245 | p = xdr_inline_decode(xdr, 2 * sizeof(uint64_t)); |
256 | if (unlikely(p == NULL)) | 246 | if (unlikely(p == NULL)) |
257 | return htonl(NFS4ERR_BADXDR); | 247 | return htonl(NFS4ERR_BADXDR); |
258 | p = xdr_decode_hyper(p, &args->cbl_fsid.major); | 248 | p = xdr_decode_hyper(p, &args->cbl_fsid.major); |
@@ -275,7 +265,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, | |||
275 | args->ndevs = 0; | 265 | args->ndevs = 0; |
276 | 266 | ||
277 | /* Num of device notifications */ | 267 | /* Num of device notifications */ |
278 | p = read_buf(xdr, sizeof(uint32_t)); | 268 | p = xdr_inline_decode(xdr, sizeof(uint32_t)); |
279 | if (unlikely(p == NULL)) { | 269 | if (unlikely(p == NULL)) { |
280 | status = htonl(NFS4ERR_BADXDR); | 270 | status = htonl(NFS4ERR_BADXDR); |
281 | goto out; | 271 | goto out; |
@@ -298,7 +288,8 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, | |||
298 | for (i = 0; i < n; i++) { | 288 | for (i = 0; i < n; i++) { |
299 | struct cb_devicenotifyitem *dev = &args->devs[i]; | 289 | struct cb_devicenotifyitem *dev = &args->devs[i]; |
300 | 290 | ||
301 | p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE); | 291 | p = xdr_inline_decode(xdr, (4 * sizeof(uint32_t)) + |
292 | NFS4_DEVICEID4_SIZE); | ||
302 | if (unlikely(p == NULL)) { | 293 | if (unlikely(p == NULL)) { |
303 | status = htonl(NFS4ERR_BADXDR); | 294 | status = htonl(NFS4ERR_BADXDR); |
304 | goto err; | 295 | goto err; |
@@ -329,7 +320,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, | |||
329 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); | 320 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); |
330 | 321 | ||
331 | if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) { | 322 | if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) { |
332 | p = read_buf(xdr, sizeof(uint32_t)); | 323 | p = xdr_inline_decode(xdr, sizeof(uint32_t)); |
333 | if (unlikely(p == NULL)) { | 324 | if (unlikely(p == NULL)) { |
334 | status = htonl(NFS4ERR_BADXDR); | 325 | status = htonl(NFS4ERR_BADXDR); |
335 | goto err; | 326 | goto err; |
@@ -359,7 +350,7 @@ static __be32 decode_sessionid(struct xdr_stream *xdr, | |||
359 | { | 350 | { |
360 | __be32 *p; | 351 | __be32 *p; |
361 | 352 | ||
362 | p = read_buf(xdr, NFS4_MAX_SESSIONID_LEN); | 353 | p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN); |
363 | if (unlikely(p == NULL)) | 354 | if (unlikely(p == NULL)) |
364 | return htonl(NFS4ERR_RESOURCE); | 355 | return htonl(NFS4ERR_RESOURCE); |
365 | 356 | ||
@@ -379,13 +370,13 @@ static __be32 decode_rc_list(struct xdr_stream *xdr, | |||
379 | goto out; | 370 | goto out; |
380 | 371 | ||
381 | status = htonl(NFS4ERR_RESOURCE); | 372 | status = htonl(NFS4ERR_RESOURCE); |
382 | p = read_buf(xdr, sizeof(uint32_t)); | 373 | p = xdr_inline_decode(xdr, sizeof(uint32_t)); |
383 | if (unlikely(p == NULL)) | 374 | if (unlikely(p == NULL)) |
384 | goto out; | 375 | goto out; |
385 | 376 | ||
386 | rc_list->rcl_nrefcalls = ntohl(*p++); | 377 | rc_list->rcl_nrefcalls = ntohl(*p++); |
387 | if (rc_list->rcl_nrefcalls) { | 378 | if (rc_list->rcl_nrefcalls) { |
388 | p = read_buf(xdr, | 379 | p = xdr_inline_decode(xdr, |
389 | rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); | 380 | rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); |
390 | if (unlikely(p == NULL)) | 381 | if (unlikely(p == NULL)) |
391 | goto out; | 382 | goto out; |
@@ -418,7 +409,7 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, | |||
418 | if (status) | 409 | if (status) |
419 | return status; | 410 | return status; |
420 | 411 | ||
421 | p = read_buf(xdr, 5 * sizeof(uint32_t)); | 412 | p = xdr_inline_decode(xdr, 5 * sizeof(uint32_t)); |
422 | if (unlikely(p == NULL)) | 413 | if (unlikely(p == NULL)) |
423 | return htonl(NFS4ERR_RESOURCE); | 414 | return htonl(NFS4ERR_RESOURCE); |
424 | 415 | ||
@@ -461,7 +452,7 @@ static __be32 decode_recallany_args(struct svc_rqst *rqstp, | |||
461 | uint32_t bitmap[2]; | 452 | uint32_t bitmap[2]; |
462 | __be32 *p, status; | 453 | __be32 *p, status; |
463 | 454 | ||
464 | p = read_buf(xdr, 4); | 455 | p = xdr_inline_decode(xdr, 4); |
465 | if (unlikely(p == NULL)) | 456 | if (unlikely(p == NULL)) |
466 | return htonl(NFS4ERR_BADXDR); | 457 | return htonl(NFS4ERR_BADXDR); |
467 | args->craa_objs_to_keep = ntohl(*p++); | 458 | args->craa_objs_to_keep = ntohl(*p++); |
@@ -480,7 +471,7 @@ static __be32 decode_recallslot_args(struct svc_rqst *rqstp, | |||
480 | struct cb_recallslotargs *args = argp; | 471 | struct cb_recallslotargs *args = argp; |
481 | __be32 *p; | 472 | __be32 *p; |
482 | 473 | ||
483 | p = read_buf(xdr, 4); | 474 | p = xdr_inline_decode(xdr, 4); |
484 | if (unlikely(p == NULL)) | 475 | if (unlikely(p == NULL)) |
485 | return htonl(NFS4ERR_BADXDR); | 476 | return htonl(NFS4ERR_BADXDR); |
486 | args->crsa_target_highest_slotid = ntohl(*p++); | 477 | args->crsa_target_highest_slotid = ntohl(*p++); |
@@ -492,14 +483,14 @@ static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_arg | |||
492 | __be32 *p; | 483 | __be32 *p; |
493 | unsigned int len; | 484 | unsigned int len; |
494 | 485 | ||
495 | p = read_buf(xdr, 12); | 486 | p = xdr_inline_decode(xdr, 12); |
496 | if (unlikely(p == NULL)) | 487 | if (unlikely(p == NULL)) |
497 | return htonl(NFS4ERR_BADXDR); | 488 | return htonl(NFS4ERR_BADXDR); |
498 | 489 | ||
499 | p = xdr_decode_hyper(p, &args->cbnl_owner.clientid); | 490 | p = xdr_decode_hyper(p, &args->cbnl_owner.clientid); |
500 | len = be32_to_cpu(*p); | 491 | len = be32_to_cpu(*p); |
501 | 492 | ||
502 | p = read_buf(xdr, len); | 493 | p = xdr_inline_decode(xdr, len); |
503 | if (unlikely(p == NULL)) | 494 | if (unlikely(p == NULL)) |
504 | return htonl(NFS4ERR_BADXDR); | 495 | return htonl(NFS4ERR_BADXDR); |
505 | 496 | ||
@@ -537,7 +528,7 @@ static __be32 decode_write_response(struct xdr_stream *xdr, | |||
537 | __be32 *p; | 528 | __be32 *p; |
538 | 529 | ||
539 | /* skip the always zero field */ | 530 | /* skip the always zero field */ |
540 | p = read_buf(xdr, 4); | 531 | p = xdr_inline_decode(xdr, 4); |
541 | if (unlikely(!p)) | 532 | if (unlikely(!p)) |
542 | goto out; | 533 | goto out; |
543 | p++; | 534 | p++; |
@@ -577,7 +568,7 @@ static __be32 decode_offload_args(struct svc_rqst *rqstp, | |||
577 | return status; | 568 | return status; |
578 | 569 | ||
579 | /* decode status */ | 570 | /* decode status */ |
580 | p = read_buf(xdr, 4); | 571 | p = xdr_inline_decode(xdr, 4); |
581 | if (unlikely(!p)) | 572 | if (unlikely(!p)) |
582 | goto out; | 573 | goto out; |
583 | args->error = ntohl(*p++); | 574 | args->error = ntohl(*p++); |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 350675e3ed47..76614311f957 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -80,17 +80,6 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, | |||
80 | } | 80 | } |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * Handle decode buffer overflows out-of-line. | ||
84 | */ | ||
85 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | ||
86 | { | ||
87 | dprintk("NFS: %s prematurely hit the end of our receive buffer. " | ||
88 | "Remaining buffer length is %tu words.\n", | ||
89 | func, xdr->end - xdr->p); | ||
90 | } | ||
91 | |||
92 | |||
93 | /* | ||
94 | * Encode/decode NFSv2 basic data types | 83 | * Encode/decode NFSv2 basic data types |
95 | * | 84 | * |
96 | * Basic NFSv2 data types are defined in section 2.3 of RFC 1094: | 85 | * Basic NFSv2 data types are defined in section 2.3 of RFC 1094: |
@@ -110,8 +99,8 @@ static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_pgio_res *result) | |||
110 | __be32 *p; | 99 | __be32 *p; |
111 | 100 | ||
112 | p = xdr_inline_decode(xdr, 4); | 101 | p = xdr_inline_decode(xdr, 4); |
113 | if (unlikely(p == NULL)) | 102 | if (unlikely(!p)) |
114 | goto out_overflow; | 103 | return -EIO; |
115 | count = be32_to_cpup(p); | 104 | count = be32_to_cpup(p); |
116 | recvd = xdr_read_pages(xdr, count); | 105 | recvd = xdr_read_pages(xdr, count); |
117 | if (unlikely(count > recvd)) | 106 | if (unlikely(count > recvd)) |
@@ -125,9 +114,6 @@ out_cheating: | |||
125 | "count %u > recvd %u\n", count, recvd); | 114 | "count %u > recvd %u\n", count, recvd); |
126 | count = recvd; | 115 | count = recvd; |
127 | goto out; | 116 | goto out; |
128 | out_overflow: | ||
129 | print_overflow_msg(__func__, xdr); | ||
130 | return -EIO; | ||
131 | } | 117 | } |
132 | 118 | ||
133 | /* | 119 | /* |
@@ -157,13 +143,10 @@ static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status) | |||
157 | __be32 *p; | 143 | __be32 *p; |
158 | 144 | ||
159 | p = xdr_inline_decode(xdr, 4); | 145 | p = xdr_inline_decode(xdr, 4); |
160 | if (unlikely(p == NULL)) | 146 | if (unlikely(!p)) |
161 | goto out_overflow; | 147 | return -EIO; |
162 | *status = be32_to_cpup(p); | 148 | *status = be32_to_cpup(p); |
163 | return 0; | 149 | return 0; |
164 | out_overflow: | ||
165 | print_overflow_msg(__func__, xdr); | ||
166 | return -EIO; | ||
167 | } | 150 | } |
168 | 151 | ||
169 | /* | 152 | /* |
@@ -205,14 +188,11 @@ static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
205 | __be32 *p; | 188 | __be32 *p; |
206 | 189 | ||
207 | p = xdr_inline_decode(xdr, NFS2_FHSIZE); | 190 | p = xdr_inline_decode(xdr, NFS2_FHSIZE); |
208 | if (unlikely(p == NULL)) | 191 | if (unlikely(!p)) |
209 | goto out_overflow; | 192 | return -EIO; |
210 | fh->size = NFS2_FHSIZE; | 193 | fh->size = NFS2_FHSIZE; |
211 | memcpy(fh->data, p, NFS2_FHSIZE); | 194 | memcpy(fh->data, p, NFS2_FHSIZE); |
212 | return 0; | 195 | return 0; |
213 | out_overflow: | ||
214 | print_overflow_msg(__func__, xdr); | ||
215 | return -EIO; | ||
216 | } | 196 | } |
217 | 197 | ||
218 | /* | 198 | /* |
@@ -282,8 +262,8 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
282 | __be32 *p; | 262 | __be32 *p; |
283 | 263 | ||
284 | p = xdr_inline_decode(xdr, NFS_fattr_sz << 2); | 264 | p = xdr_inline_decode(xdr, NFS_fattr_sz << 2); |
285 | if (unlikely(p == NULL)) | 265 | if (unlikely(!p)) |
286 | goto out_overflow; | 266 | return -EIO; |
287 | 267 | ||
288 | fattr->valid |= NFS_ATTR_FATTR_V2; | 268 | fattr->valid |= NFS_ATTR_FATTR_V2; |
289 | 269 | ||
@@ -325,9 +305,6 @@ out_uid: | |||
325 | out_gid: | 305 | out_gid: |
326 | dprintk("NFS: returned invalid gid\n"); | 306 | dprintk("NFS: returned invalid gid\n"); |
327 | return -EINVAL; | 307 | return -EINVAL; |
328 | out_overflow: | ||
329 | print_overflow_msg(__func__, xdr); | ||
330 | return -EIO; | ||
331 | } | 308 | } |
332 | 309 | ||
333 | /* | 310 | /* |
@@ -416,23 +393,20 @@ static int decode_filename_inline(struct xdr_stream *xdr, | |||
416 | u32 count; | 393 | u32 count; |
417 | 394 | ||
418 | p = xdr_inline_decode(xdr, 4); | 395 | p = xdr_inline_decode(xdr, 4); |
419 | if (unlikely(p == NULL)) | 396 | if (unlikely(!p)) |
420 | goto out_overflow; | 397 | return -EIO; |
421 | count = be32_to_cpup(p); | 398 | count = be32_to_cpup(p); |
422 | if (count > NFS3_MAXNAMLEN) | 399 | if (count > NFS3_MAXNAMLEN) |
423 | goto out_nametoolong; | 400 | goto out_nametoolong; |
424 | p = xdr_inline_decode(xdr, count); | 401 | p = xdr_inline_decode(xdr, count); |
425 | if (unlikely(p == NULL)) | 402 | if (unlikely(!p)) |
426 | goto out_overflow; | 403 | return -EIO; |
427 | *name = (const char *)p; | 404 | *name = (const char *)p; |
428 | *length = count; | 405 | *length = count; |
429 | return 0; | 406 | return 0; |
430 | out_nametoolong: | 407 | out_nametoolong: |
431 | dprintk("NFS: returned filename too long: %u\n", count); | 408 | dprintk("NFS: returned filename too long: %u\n", count); |
432 | return -ENAMETOOLONG; | 409 | return -ENAMETOOLONG; |
433 | out_overflow: | ||
434 | print_overflow_msg(__func__, xdr); | ||
435 | return -EIO; | ||
436 | } | 410 | } |
437 | 411 | ||
438 | /* | 412 | /* |
@@ -455,8 +429,8 @@ static int decode_path(struct xdr_stream *xdr) | |||
455 | __be32 *p; | 429 | __be32 *p; |
456 | 430 | ||
457 | p = xdr_inline_decode(xdr, 4); | 431 | p = xdr_inline_decode(xdr, 4); |
458 | if (unlikely(p == NULL)) | 432 | if (unlikely(!p)) |
459 | goto out_overflow; | 433 | return -EIO; |
460 | length = be32_to_cpup(p); | 434 | length = be32_to_cpup(p); |
461 | if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN)) | 435 | if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN)) |
462 | goto out_size; | 436 | goto out_size; |
@@ -472,9 +446,6 @@ out_cheating: | |||
472 | dprintk("NFS: server cheating in pathname result: " | 446 | dprintk("NFS: server cheating in pathname result: " |
473 | "length %u > received %u\n", length, recvd); | 447 | "length %u > received %u\n", length, recvd); |
474 | return -EIO; | 448 | return -EIO; |
475 | out_overflow: | ||
476 | print_overflow_msg(__func__, xdr); | ||
477 | return -EIO; | ||
478 | } | 449 | } |
479 | 450 | ||
480 | /* | 451 | /* |
@@ -951,12 +922,12 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
951 | int error; | 922 | int error; |
952 | 923 | ||
953 | p = xdr_inline_decode(xdr, 4); | 924 | p = xdr_inline_decode(xdr, 4); |
954 | if (unlikely(p == NULL)) | 925 | if (unlikely(!p)) |
955 | goto out_overflow; | 926 | return -EAGAIN; |
956 | if (*p++ == xdr_zero) { | 927 | if (*p++ == xdr_zero) { |
957 | p = xdr_inline_decode(xdr, 4); | 928 | p = xdr_inline_decode(xdr, 4); |
958 | if (unlikely(p == NULL)) | 929 | if (unlikely(!p)) |
959 | goto out_overflow; | 930 | return -EAGAIN; |
960 | if (*p++ == xdr_zero) | 931 | if (*p++ == xdr_zero) |
961 | return -EAGAIN; | 932 | return -EAGAIN; |
962 | entry->eof = 1; | 933 | entry->eof = 1; |
@@ -964,8 +935,8 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
964 | } | 935 | } |
965 | 936 | ||
966 | p = xdr_inline_decode(xdr, 4); | 937 | p = xdr_inline_decode(xdr, 4); |
967 | if (unlikely(p == NULL)) | 938 | if (unlikely(!p)) |
968 | goto out_overflow; | 939 | return -EAGAIN; |
969 | entry->ino = be32_to_cpup(p); | 940 | entry->ino = be32_to_cpup(p); |
970 | 941 | ||
971 | error = decode_filename_inline(xdr, &entry->name, &entry->len); | 942 | error = decode_filename_inline(xdr, &entry->name, &entry->len); |
@@ -978,17 +949,13 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
978 | */ | 949 | */ |
979 | entry->prev_cookie = entry->cookie; | 950 | entry->prev_cookie = entry->cookie; |
980 | p = xdr_inline_decode(xdr, 4); | 951 | p = xdr_inline_decode(xdr, 4); |
981 | if (unlikely(p == NULL)) | 952 | if (unlikely(!p)) |
982 | goto out_overflow; | 953 | return -EAGAIN; |
983 | entry->cookie = be32_to_cpup(p); | 954 | entry->cookie = be32_to_cpup(p); |
984 | 955 | ||
985 | entry->d_type = DT_UNKNOWN; | 956 | entry->d_type = DT_UNKNOWN; |
986 | 957 | ||
987 | return 0; | 958 | return 0; |
988 | |||
989 | out_overflow: | ||
990 | print_overflow_msg(__func__, xdr); | ||
991 | return -EAGAIN; | ||
992 | } | 959 | } |
993 | 960 | ||
994 | /* | 961 | /* |
@@ -1052,17 +1019,14 @@ static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result) | |||
1052 | __be32 *p; | 1019 | __be32 *p; |
1053 | 1020 | ||
1054 | p = xdr_inline_decode(xdr, NFS_info_sz << 2); | 1021 | p = xdr_inline_decode(xdr, NFS_info_sz << 2); |
1055 | if (unlikely(p == NULL)) | 1022 | if (unlikely(!p)) |
1056 | goto out_overflow; | 1023 | return -EIO; |
1057 | result->tsize = be32_to_cpup(p++); | 1024 | result->tsize = be32_to_cpup(p++); |
1058 | result->bsize = be32_to_cpup(p++); | 1025 | result->bsize = be32_to_cpup(p++); |
1059 | result->blocks = be32_to_cpup(p++); | 1026 | result->blocks = be32_to_cpup(p++); |
1060 | result->bfree = be32_to_cpup(p++); | 1027 | result->bfree = be32_to_cpup(p++); |
1061 | result->bavail = be32_to_cpup(p); | 1028 | result->bavail = be32_to_cpup(p); |
1062 | return 0; | 1029 | return 0; |
1063 | out_overflow: | ||
1064 | print_overflow_msg(__func__, xdr); | ||
1065 | return -EIO; | ||
1066 | } | 1030 | } |
1067 | 1031 | ||
1068 | static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr, | 1032 | static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr, |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 78df4eb60f85..e5619803a4f6 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -119,17 +119,6 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Handle decode buffer overflows out-of-line. | ||
123 | */ | ||
124 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | ||
125 | { | ||
126 | dprintk("NFS: %s prematurely hit the end of our receive buffer. " | ||
127 | "Remaining buffer length is %tu words.\n", | ||
128 | func, xdr->end - xdr->p); | ||
129 | } | ||
130 | |||
131 | |||
132 | /* | ||
133 | * Encode/decode NFSv3 basic data types | 122 | * Encode/decode NFSv3 basic data types |
134 | * | 123 | * |
135 | * Basic NFSv3 data types are defined in section 2.5 of RFC 1813: | 124 | * Basic NFSv3 data types are defined in section 2.5 of RFC 1813: |
@@ -151,13 +140,10 @@ static int decode_uint32(struct xdr_stream *xdr, u32 *value) | |||
151 | __be32 *p; | 140 | __be32 *p; |
152 | 141 | ||
153 | p = xdr_inline_decode(xdr, 4); | 142 | p = xdr_inline_decode(xdr, 4); |
154 | if (unlikely(p == NULL)) | 143 | if (unlikely(!p)) |
155 | goto out_overflow; | 144 | return -EIO; |
156 | *value = be32_to_cpup(p); | 145 | *value = be32_to_cpup(p); |
157 | return 0; | 146 | return 0; |
158 | out_overflow: | ||
159 | print_overflow_msg(__func__, xdr); | ||
160 | return -EIO; | ||
161 | } | 147 | } |
162 | 148 | ||
163 | static int decode_uint64(struct xdr_stream *xdr, u64 *value) | 149 | static int decode_uint64(struct xdr_stream *xdr, u64 *value) |
@@ -165,13 +151,10 @@ static int decode_uint64(struct xdr_stream *xdr, u64 *value) | |||
165 | __be32 *p; | 151 | __be32 *p; |
166 | 152 | ||
167 | p = xdr_inline_decode(xdr, 8); | 153 | p = xdr_inline_decode(xdr, 8); |
168 | if (unlikely(p == NULL)) | 154 | if (unlikely(!p)) |
169 | goto out_overflow; | 155 | return -EIO; |
170 | xdr_decode_hyper(p, value); | 156 | xdr_decode_hyper(p, value); |
171 | return 0; | 157 | return 0; |
172 | out_overflow: | ||
173 | print_overflow_msg(__func__, xdr); | ||
174 | return -EIO; | ||
175 | } | 158 | } |
176 | 159 | ||
177 | /* | 160 | /* |
@@ -211,14 +194,14 @@ static int decode_inline_filename3(struct xdr_stream *xdr, | |||
211 | u32 count; | 194 | u32 count; |
212 | 195 | ||
213 | p = xdr_inline_decode(xdr, 4); | 196 | p = xdr_inline_decode(xdr, 4); |
214 | if (unlikely(p == NULL)) | 197 | if (unlikely(!p)) |
215 | goto out_overflow; | 198 | return -EIO; |
216 | count = be32_to_cpup(p); | 199 | count = be32_to_cpup(p); |
217 | if (count > NFS3_MAXNAMLEN) | 200 | if (count > NFS3_MAXNAMLEN) |
218 | goto out_nametoolong; | 201 | goto out_nametoolong; |
219 | p = xdr_inline_decode(xdr, count); | 202 | p = xdr_inline_decode(xdr, count); |
220 | if (unlikely(p == NULL)) | 203 | if (unlikely(!p)) |
221 | goto out_overflow; | 204 | return -EIO; |
222 | *name = (const char *)p; | 205 | *name = (const char *)p; |
223 | *length = count; | 206 | *length = count; |
224 | return 0; | 207 | return 0; |
@@ -226,9 +209,6 @@ static int decode_inline_filename3(struct xdr_stream *xdr, | |||
226 | out_nametoolong: | 209 | out_nametoolong: |
227 | dprintk("NFS: returned filename too long: %u\n", count); | 210 | dprintk("NFS: returned filename too long: %u\n", count); |
228 | return -ENAMETOOLONG; | 211 | return -ENAMETOOLONG; |
229 | out_overflow: | ||
230 | print_overflow_msg(__func__, xdr); | ||
231 | return -EIO; | ||
232 | } | 212 | } |
233 | 213 | ||
234 | /* | 214 | /* |
@@ -249,8 +229,8 @@ static int decode_nfspath3(struct xdr_stream *xdr) | |||
249 | __be32 *p; | 229 | __be32 *p; |
250 | 230 | ||
251 | p = xdr_inline_decode(xdr, 4); | 231 | p = xdr_inline_decode(xdr, 4); |
252 | if (unlikely(p == NULL)) | 232 | if (unlikely(!p)) |
253 | goto out_overflow; | 233 | return -EIO; |
254 | count = be32_to_cpup(p); | 234 | count = be32_to_cpup(p); |
255 | if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) | 235 | if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) |
256 | goto out_nametoolong; | 236 | goto out_nametoolong; |
@@ -267,9 +247,6 @@ out_cheating: | |||
267 | dprintk("NFS: server cheating in pathname result: " | 247 | dprintk("NFS: server cheating in pathname result: " |
268 | "count %u > recvd %u\n", count, recvd); | 248 | "count %u > recvd %u\n", count, recvd); |
269 | return -EIO; | 249 | return -EIO; |
270 | out_overflow: | ||
271 | print_overflow_msg(__func__, xdr); | ||
272 | return -EIO; | ||
273 | } | 250 | } |
274 | 251 | ||
275 | /* | 252 | /* |
@@ -303,13 +280,10 @@ static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier) | |||
303 | __be32 *p; | 280 | __be32 *p; |
304 | 281 | ||
305 | p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); | 282 | p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); |
306 | if (unlikely(p == NULL)) | 283 | if (unlikely(!p)) |
307 | goto out_overflow; | 284 | return -EIO; |
308 | memcpy(verifier, p, NFS3_COOKIEVERFSIZE); | 285 | memcpy(verifier, p, NFS3_COOKIEVERFSIZE); |
309 | return 0; | 286 | return 0; |
310 | out_overflow: | ||
311 | print_overflow_msg(__func__, xdr); | ||
312 | return -EIO; | ||
313 | } | 287 | } |
314 | 288 | ||
315 | /* | 289 | /* |
@@ -330,13 +304,10 @@ static int decode_writeverf3(struct xdr_stream *xdr, struct nfs_write_verifier * | |||
330 | __be32 *p; | 304 | __be32 *p; |
331 | 305 | ||
332 | p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); | 306 | p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); |
333 | if (unlikely(p == NULL)) | 307 | if (unlikely(!p)) |
334 | goto out_overflow; | 308 | return -EIO; |
335 | memcpy(verifier->data, p, NFS3_WRITEVERFSIZE); | 309 | memcpy(verifier->data, p, NFS3_WRITEVERFSIZE); |
336 | return 0; | 310 | return 0; |
337 | out_overflow: | ||
338 | print_overflow_msg(__func__, xdr); | ||
339 | return -EIO; | ||
340 | } | 311 | } |
341 | 312 | ||
342 | /* | 313 | /* |
@@ -364,13 +335,10 @@ static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status) | |||
364 | __be32 *p; | 335 | __be32 *p; |
365 | 336 | ||
366 | p = xdr_inline_decode(xdr, 4); | 337 | p = xdr_inline_decode(xdr, 4); |
367 | if (unlikely(p == NULL)) | 338 | if (unlikely(!p)) |
368 | goto out_overflow; | 339 | return -EIO; |
369 | *status = be32_to_cpup(p); | 340 | *status = be32_to_cpup(p); |
370 | return 0; | 341 | return 0; |
371 | out_overflow: | ||
372 | print_overflow_msg(__func__, xdr); | ||
373 | return -EIO; | ||
374 | } | 342 | } |
375 | 343 | ||
376 | /* | 344 | /* |
@@ -453,23 +421,20 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
453 | __be32 *p; | 421 | __be32 *p; |
454 | 422 | ||
455 | p = xdr_inline_decode(xdr, 4); | 423 | p = xdr_inline_decode(xdr, 4); |
456 | if (unlikely(p == NULL)) | 424 | if (unlikely(!p)) |
457 | goto out_overflow; | 425 | return -EIO; |
458 | length = be32_to_cpup(p++); | 426 | length = be32_to_cpup(p++); |
459 | if (unlikely(length > NFS3_FHSIZE)) | 427 | if (unlikely(length > NFS3_FHSIZE)) |
460 | goto out_toobig; | 428 | goto out_toobig; |
461 | p = xdr_inline_decode(xdr, length); | 429 | p = xdr_inline_decode(xdr, length); |
462 | if (unlikely(p == NULL)) | 430 | if (unlikely(!p)) |
463 | goto out_overflow; | 431 | return -EIO; |
464 | fh->size = length; | 432 | fh->size = length; |
465 | memcpy(fh->data, p, length); | 433 | memcpy(fh->data, p, length); |
466 | return 0; | 434 | return 0; |
467 | out_toobig: | 435 | out_toobig: |
468 | dprintk("NFS: file handle size (%u) too big\n", length); | 436 | dprintk("NFS: file handle size (%u) too big\n", length); |
469 | return -E2BIG; | 437 | return -E2BIG; |
470 | out_overflow: | ||
471 | print_overflow_msg(__func__, xdr); | ||
472 | return -EIO; | ||
473 | } | 438 | } |
474 | 439 | ||
475 | static void zero_nfs_fh3(struct nfs_fh *fh) | 440 | static void zero_nfs_fh3(struct nfs_fh *fh) |
@@ -655,8 +620,8 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
655 | __be32 *p; | 620 | __be32 *p; |
656 | 621 | ||
657 | p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2); | 622 | p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2); |
658 | if (unlikely(p == NULL)) | 623 | if (unlikely(!p)) |
659 | goto out_overflow; | 624 | return -EIO; |
660 | 625 | ||
661 | p = xdr_decode_ftype3(p, &fmode); | 626 | p = xdr_decode_ftype3(p, &fmode); |
662 | 627 | ||
@@ -690,9 +655,6 @@ out_uid: | |||
690 | out_gid: | 655 | out_gid: |
691 | dprintk("NFS: returned invalid gid\n"); | 656 | dprintk("NFS: returned invalid gid\n"); |
692 | return -EINVAL; | 657 | return -EINVAL; |
693 | out_overflow: | ||
694 | print_overflow_msg(__func__, xdr); | ||
695 | return -EIO; | ||
696 | } | 658 | } |
697 | 659 | ||
698 | /* | 660 | /* |
@@ -710,14 +672,11 @@ static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
710 | __be32 *p; | 672 | __be32 *p; |
711 | 673 | ||
712 | p = xdr_inline_decode(xdr, 4); | 674 | p = xdr_inline_decode(xdr, 4); |
713 | if (unlikely(p == NULL)) | 675 | if (unlikely(!p)) |
714 | goto out_overflow; | 676 | return -EIO; |
715 | if (*p != xdr_zero) | 677 | if (*p != xdr_zero) |
716 | return decode_fattr3(xdr, fattr); | 678 | return decode_fattr3(xdr, fattr); |
717 | return 0; | 679 | return 0; |
718 | out_overflow: | ||
719 | print_overflow_msg(__func__, xdr); | ||
720 | return -EIO; | ||
721 | } | 680 | } |
722 | 681 | ||
723 | /* | 682 | /* |
@@ -733,8 +692,8 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
733 | __be32 *p; | 692 | __be32 *p; |
734 | 693 | ||
735 | p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2); | 694 | p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2); |
736 | if (unlikely(p == NULL)) | 695 | if (unlikely(!p)) |
737 | goto out_overflow; | 696 | return -EIO; |
738 | 697 | ||
739 | fattr->valid |= NFS_ATTR_FATTR_PRESIZE | 698 | fattr->valid |= NFS_ATTR_FATTR_PRESIZE |
740 | | NFS_ATTR_FATTR_PRECHANGE | 699 | | NFS_ATTR_FATTR_PRECHANGE |
@@ -747,9 +706,6 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
747 | fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime); | 706 | fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime); |
748 | 707 | ||
749 | return 0; | 708 | return 0; |
750 | out_overflow: | ||
751 | print_overflow_msg(__func__, xdr); | ||
752 | return -EIO; | ||
753 | } | 709 | } |
754 | 710 | ||
755 | /* | 711 | /* |
@@ -773,14 +729,11 @@ static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
773 | __be32 *p; | 729 | __be32 *p; |
774 | 730 | ||
775 | p = xdr_inline_decode(xdr, 4); | 731 | p = xdr_inline_decode(xdr, 4); |
776 | if (unlikely(p == NULL)) | 732 | if (unlikely(!p)) |
777 | goto out_overflow; | 733 | return -EIO; |
778 | if (*p != xdr_zero) | 734 | if (*p != xdr_zero) |
779 | return decode_wcc_attr(xdr, fattr); | 735 | return decode_wcc_attr(xdr, fattr); |
780 | return 0; | 736 | return 0; |
781 | out_overflow: | ||
782 | print_overflow_msg(__func__, xdr); | ||
783 | return -EIO; | ||
784 | } | 737 | } |
785 | 738 | ||
786 | static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr) | 739 | static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr) |
@@ -808,15 +761,12 @@ out: | |||
808 | static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) | 761 | static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) |
809 | { | 762 | { |
810 | __be32 *p = xdr_inline_decode(xdr, 4); | 763 | __be32 *p = xdr_inline_decode(xdr, 4); |
811 | if (unlikely(p == NULL)) | 764 | if (unlikely(!p)) |
812 | goto out_overflow; | 765 | return -EIO; |
813 | if (*p != xdr_zero) | 766 | if (*p != xdr_zero) |
814 | return decode_nfs_fh3(xdr, fh); | 767 | return decode_nfs_fh3(xdr, fh); |
815 | zero_nfs_fh3(fh); | 768 | zero_nfs_fh3(fh); |
816 | return 0; | 769 | return 0; |
817 | out_overflow: | ||
818 | print_overflow_msg(__func__, xdr); | ||
819 | return -EIO; | ||
820 | } | 770 | } |
821 | 771 | ||
822 | /* | 772 | /* |
@@ -1643,8 +1593,8 @@ static int decode_read3resok(struct xdr_stream *xdr, | |||
1643 | __be32 *p; | 1593 | __be32 *p; |
1644 | 1594 | ||
1645 | p = xdr_inline_decode(xdr, 4 + 4 + 4); | 1595 | p = xdr_inline_decode(xdr, 4 + 4 + 4); |
1646 | if (unlikely(p == NULL)) | 1596 | if (unlikely(!p)) |
1647 | goto out_overflow; | 1597 | return -EIO; |
1648 | count = be32_to_cpup(p++); | 1598 | count = be32_to_cpup(p++); |
1649 | eof = be32_to_cpup(p++); | 1599 | eof = be32_to_cpup(p++); |
1650 | ocount = be32_to_cpup(p++); | 1600 | ocount = be32_to_cpup(p++); |
@@ -1667,9 +1617,6 @@ out_cheating: | |||
1667 | count = recvd; | 1617 | count = recvd; |
1668 | eof = 0; | 1618 | eof = 0; |
1669 | goto out; | 1619 | goto out; |
1670 | out_overflow: | ||
1671 | print_overflow_msg(__func__, xdr); | ||
1672 | return -EIO; | ||
1673 | } | 1620 | } |
1674 | 1621 | ||
1675 | static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, | 1622 | static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, |
@@ -1731,22 +1678,18 @@ static int decode_write3resok(struct xdr_stream *xdr, | |||
1731 | __be32 *p; | 1678 | __be32 *p; |
1732 | 1679 | ||
1733 | p = xdr_inline_decode(xdr, 4 + 4); | 1680 | p = xdr_inline_decode(xdr, 4 + 4); |
1734 | if (unlikely(p == NULL)) | 1681 | if (unlikely(!p)) |
1735 | goto out_overflow; | 1682 | return -EIO; |
1736 | result->count = be32_to_cpup(p++); | 1683 | result->count = be32_to_cpup(p++); |
1737 | result->verf->committed = be32_to_cpup(p++); | 1684 | result->verf->committed = be32_to_cpup(p++); |
1738 | if (unlikely(result->verf->committed > NFS_FILE_SYNC)) | 1685 | if (unlikely(result->verf->committed > NFS_FILE_SYNC)) |
1739 | goto out_badvalue; | 1686 | goto out_badvalue; |
1740 | if (decode_writeverf3(xdr, &result->verf->verifier)) | 1687 | if (decode_writeverf3(xdr, &result->verf->verifier)) |
1741 | goto out_eio; | 1688 | return -EIO; |
1742 | return result->count; | 1689 | return result->count; |
1743 | out_badvalue: | 1690 | out_badvalue: |
1744 | dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); | 1691 | dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); |
1745 | return -EIO; | 1692 | return -EIO; |
1746 | out_overflow: | ||
1747 | print_overflow_msg(__func__, xdr); | ||
1748 | out_eio: | ||
1749 | return -EIO; | ||
1750 | } | 1693 | } |
1751 | 1694 | ||
1752 | static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, | 1695 | static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, |
@@ -2010,12 +1953,12 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
2010 | u64 new_cookie; | 1953 | u64 new_cookie; |
2011 | 1954 | ||
2012 | p = xdr_inline_decode(xdr, 4); | 1955 | p = xdr_inline_decode(xdr, 4); |
2013 | if (unlikely(p == NULL)) | 1956 | if (unlikely(!p)) |
2014 | goto out_overflow; | 1957 | return -EAGAIN; |
2015 | if (*p == xdr_zero) { | 1958 | if (*p == xdr_zero) { |
2016 | p = xdr_inline_decode(xdr, 4); | 1959 | p = xdr_inline_decode(xdr, 4); |
2017 | if (unlikely(p == NULL)) | 1960 | if (unlikely(!p)) |
2018 | goto out_overflow; | 1961 | return -EAGAIN; |
2019 | if (*p == xdr_zero) | 1962 | if (*p == xdr_zero) |
2020 | return -EAGAIN; | 1963 | return -EAGAIN; |
2021 | entry->eof = 1; | 1964 | entry->eof = 1; |
@@ -2051,8 +1994,8 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
2051 | 1994 | ||
2052 | /* In fact, a post_op_fh3: */ | 1995 | /* In fact, a post_op_fh3: */ |
2053 | p = xdr_inline_decode(xdr, 4); | 1996 | p = xdr_inline_decode(xdr, 4); |
2054 | if (unlikely(p == NULL)) | 1997 | if (unlikely(!p)) |
2055 | goto out_overflow; | 1998 | return -EAGAIN; |
2056 | if (*p != xdr_zero) { | 1999 | if (*p != xdr_zero) { |
2057 | error = decode_nfs_fh3(xdr, entry->fh); | 2000 | error = decode_nfs_fh3(xdr, entry->fh); |
2058 | if (unlikely(error)) { | 2001 | if (unlikely(error)) { |
@@ -2069,9 +2012,6 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
2069 | 2012 | ||
2070 | return 0; | 2013 | return 0; |
2071 | 2014 | ||
2072 | out_overflow: | ||
2073 | print_overflow_msg(__func__, xdr); | ||
2074 | return -EAGAIN; | ||
2075 | out_truncated: | 2015 | out_truncated: |
2076 | dprintk("NFS: directory entry contains invalid file handle\n"); | 2016 | dprintk("NFS: directory entry contains invalid file handle\n"); |
2077 | *entry = old; | 2017 | *entry = old; |
@@ -2183,8 +2123,8 @@ static int decode_fsstat3resok(struct xdr_stream *xdr, | |||
2183 | __be32 *p; | 2123 | __be32 *p; |
2184 | 2124 | ||
2185 | p = xdr_inline_decode(xdr, 8 * 6 + 4); | 2125 | p = xdr_inline_decode(xdr, 8 * 6 + 4); |
2186 | if (unlikely(p == NULL)) | 2126 | if (unlikely(!p)) |
2187 | goto out_overflow; | 2127 | return -EIO; |
2188 | p = xdr_decode_size3(p, &result->tbytes); | 2128 | p = xdr_decode_size3(p, &result->tbytes); |
2189 | p = xdr_decode_size3(p, &result->fbytes); | 2129 | p = xdr_decode_size3(p, &result->fbytes); |
2190 | p = xdr_decode_size3(p, &result->abytes); | 2130 | p = xdr_decode_size3(p, &result->abytes); |
@@ -2193,9 +2133,6 @@ static int decode_fsstat3resok(struct xdr_stream *xdr, | |||
2193 | xdr_decode_size3(p, &result->afiles); | 2133 | xdr_decode_size3(p, &result->afiles); |
2194 | /* ignore invarsec */ | 2134 | /* ignore invarsec */ |
2195 | return 0; | 2135 | return 0; |
2196 | out_overflow: | ||
2197 | print_overflow_msg(__func__, xdr); | ||
2198 | return -EIO; | ||
2199 | } | 2136 | } |
2200 | 2137 | ||
2201 | static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, | 2138 | static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, |
@@ -2255,8 +2192,8 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr, | |||
2255 | __be32 *p; | 2192 | __be32 *p; |
2256 | 2193 | ||
2257 | p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4); | 2194 | p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4); |
2258 | if (unlikely(p == NULL)) | 2195 | if (unlikely(!p)) |
2259 | goto out_overflow; | 2196 | return -EIO; |
2260 | result->rtmax = be32_to_cpup(p++); | 2197 | result->rtmax = be32_to_cpup(p++); |
2261 | result->rtpref = be32_to_cpup(p++); | 2198 | result->rtpref = be32_to_cpup(p++); |
2262 | result->rtmult = be32_to_cpup(p++); | 2199 | result->rtmult = be32_to_cpup(p++); |
@@ -2270,9 +2207,6 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr, | |||
2270 | /* ignore properties */ | 2207 | /* ignore properties */ |
2271 | result->lease_time = 0; | 2208 | result->lease_time = 0; |
2272 | return 0; | 2209 | return 0; |
2273 | out_overflow: | ||
2274 | print_overflow_msg(__func__, xdr); | ||
2275 | return -EIO; | ||
2276 | } | 2210 | } |
2277 | 2211 | ||
2278 | static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, | 2212 | static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, |
@@ -2328,15 +2262,12 @@ static int decode_pathconf3resok(struct xdr_stream *xdr, | |||
2328 | __be32 *p; | 2262 | __be32 *p; |
2329 | 2263 | ||
2330 | p = xdr_inline_decode(xdr, 4 * 6); | 2264 | p = xdr_inline_decode(xdr, 4 * 6); |
2331 | if (unlikely(p == NULL)) | 2265 | if (unlikely(!p)) |
2332 | goto out_overflow; | 2266 | return -EIO; |
2333 | result->max_link = be32_to_cpup(p++); | 2267 | result->max_link = be32_to_cpup(p++); |
2334 | result->max_namelen = be32_to_cpup(p); | 2268 | result->max_namelen = be32_to_cpup(p); |
2335 | /* ignore remaining fields */ | 2269 | /* ignore remaining fields */ |
2336 | return 0; | 2270 | return 0; |
2337 | out_overflow: | ||
2338 | print_overflow_msg(__func__, xdr); | ||
2339 | return -EIO; | ||
2340 | } | 2271 | } |
2341 | 2272 | ||
2342 | static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, | 2273 | static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, |
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index 69f72ed2bf87..22b3425df08f 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c | |||
@@ -394,7 +394,7 @@ static int decode_write_response(struct xdr_stream *xdr, | |||
394 | 394 | ||
395 | p = xdr_inline_decode(xdr, 4); | 395 | p = xdr_inline_decode(xdr, 4); |
396 | if (unlikely(!p)) | 396 | if (unlikely(!p)) |
397 | goto out_overflow; | 397 | return -EIO; |
398 | count = be32_to_cpup(p); | 398 | count = be32_to_cpup(p); |
399 | if (count > 1) | 399 | if (count > 1) |
400 | return -EREMOTEIO; | 400 | return -EREMOTEIO; |
@@ -402,18 +402,14 @@ static int decode_write_response(struct xdr_stream *xdr, | |||
402 | status = decode_opaque_fixed(xdr, &res->stateid, | 402 | status = decode_opaque_fixed(xdr, &res->stateid, |
403 | NFS4_STATEID_SIZE); | 403 | NFS4_STATEID_SIZE); |
404 | if (unlikely(status)) | 404 | if (unlikely(status)) |
405 | goto out_overflow; | 405 | return -EIO; |
406 | } | 406 | } |
407 | p = xdr_inline_decode(xdr, 8 + 4); | 407 | p = xdr_inline_decode(xdr, 8 + 4); |
408 | if (unlikely(!p)) | 408 | if (unlikely(!p)) |
409 | goto out_overflow; | 409 | return -EIO; |
410 | p = xdr_decode_hyper(p, &res->count); | 410 | p = xdr_decode_hyper(p, &res->count); |
411 | res->verifier.committed = be32_to_cpup(p); | 411 | res->verifier.committed = be32_to_cpup(p); |
412 | return decode_verifier(xdr, &res->verifier.verifier); | 412 | return decode_verifier(xdr, &res->verifier.verifier); |
413 | |||
414 | out_overflow: | ||
415 | print_overflow_msg(__func__, xdr); | ||
416 | return -EIO; | ||
417 | } | 413 | } |
418 | 414 | ||
419 | static int decode_copy_requirements(struct xdr_stream *xdr, | 415 | static int decode_copy_requirements(struct xdr_stream *xdr, |
@@ -422,14 +418,11 @@ static int decode_copy_requirements(struct xdr_stream *xdr, | |||
422 | 418 | ||
423 | p = xdr_inline_decode(xdr, 4 + 4); | 419 | p = xdr_inline_decode(xdr, 4 + 4); |
424 | if (unlikely(!p)) | 420 | if (unlikely(!p)) |
425 | goto out_overflow; | 421 | return -EIO; |
426 | 422 | ||
427 | res->consecutive = be32_to_cpup(p++); | 423 | res->consecutive = be32_to_cpup(p++); |
428 | res->synchronous = be32_to_cpup(p++); | 424 | res->synchronous = be32_to_cpup(p++); |
429 | return 0; | 425 | return 0; |
430 | out_overflow: | ||
431 | print_overflow_msg(__func__, xdr); | ||
432 | return -EIO; | ||
433 | } | 426 | } |
434 | 427 | ||
435 | static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) | 428 | static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) |
@@ -474,15 +467,11 @@ static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) | |||
474 | 467 | ||
475 | p = xdr_inline_decode(xdr, 4 + 8); | 468 | p = xdr_inline_decode(xdr, 4 + 8); |
476 | if (unlikely(!p)) | 469 | if (unlikely(!p)) |
477 | goto out_overflow; | 470 | return -EIO; |
478 | 471 | ||
479 | res->sr_eof = be32_to_cpup(p++); | 472 | res->sr_eof = be32_to_cpup(p++); |
480 | p = xdr_decode_hyper(p, &res->sr_offset); | 473 | p = xdr_decode_hyper(p, &res->sr_offset); |
481 | return 0; | 474 | return 0; |
482 | |||
483 | out_overflow: | ||
484 | print_overflow_msg(__func__, xdr); | ||
485 | return -EIO; | ||
486 | } | 475 | } |
487 | 476 | ||
488 | static int decode_layoutstats(struct xdr_stream *xdr) | 477 | static int decode_layoutstats(struct xdr_stream *xdr) |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 2fc8f6fa25e4..24e6a45a5726 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -3144,22 +3144,12 @@ static void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req, | |||
3144 | } | 3144 | } |
3145 | #endif /* CONFIG_NFS_V4_1 */ | 3145 | #endif /* CONFIG_NFS_V4_1 */ |
3146 | 3146 | ||
3147 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | ||
3148 | { | ||
3149 | dprintk("nfs: %s: prematurely hit end of receive buffer. " | ||
3150 | "Remaining buffer length is %tu words.\n", | ||
3151 | func, xdr->end - xdr->p); | ||
3152 | } | ||
3153 | |||
3154 | static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) | 3147 | static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) |
3155 | { | 3148 | { |
3156 | ssize_t ret = xdr_stream_decode_opaque_inline(xdr, (void **)string, | 3149 | ssize_t ret = xdr_stream_decode_opaque_inline(xdr, (void **)string, |
3157 | NFS4_OPAQUE_LIMIT); | 3150 | NFS4_OPAQUE_LIMIT); |
3158 | if (unlikely(ret < 0)) { | 3151 | if (unlikely(ret < 0)) |
3159 | if (ret == -EBADMSG) | ||
3160 | print_overflow_msg(__func__, xdr); | ||
3161 | return -EIO; | 3152 | return -EIO; |
3162 | } | ||
3163 | *len = ret; | 3153 | *len = ret; |
3164 | return 0; | 3154 | return 0; |
3165 | } | 3155 | } |
@@ -3170,22 +3160,19 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
3170 | 3160 | ||
3171 | p = xdr_inline_decode(xdr, 8); | 3161 | p = xdr_inline_decode(xdr, 8); |
3172 | if (unlikely(!p)) | 3162 | if (unlikely(!p)) |
3173 | goto out_overflow; | 3163 | return -EIO; |
3174 | hdr->status = be32_to_cpup(p++); | 3164 | hdr->status = be32_to_cpup(p++); |
3175 | hdr->taglen = be32_to_cpup(p); | 3165 | hdr->taglen = be32_to_cpup(p); |
3176 | 3166 | ||
3177 | p = xdr_inline_decode(xdr, hdr->taglen + 4); | 3167 | p = xdr_inline_decode(xdr, hdr->taglen + 4); |
3178 | if (unlikely(!p)) | 3168 | if (unlikely(!p)) |
3179 | goto out_overflow; | 3169 | return -EIO; |
3180 | hdr->tag = (char *)p; | 3170 | hdr->tag = (char *)p; |
3181 | p += XDR_QUADLEN(hdr->taglen); | 3171 | p += XDR_QUADLEN(hdr->taglen); |
3182 | hdr->nops = be32_to_cpup(p); | 3172 | hdr->nops = be32_to_cpup(p); |
3183 | if (unlikely(hdr->nops < 1)) | 3173 | if (unlikely(hdr->nops < 1)) |
3184 | return nfs4_stat_to_errno(hdr->status); | 3174 | return nfs4_stat_to_errno(hdr->status); |
3185 | return 0; | 3175 | return 0; |
3186 | out_overflow: | ||
3187 | print_overflow_msg(__func__, xdr); | ||
3188 | return -EIO; | ||
3189 | } | 3176 | } |
3190 | 3177 | ||
3191 | static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, | 3178 | static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, |
@@ -3214,7 +3201,6 @@ out_bad_operation: | |||
3214 | *nfs_retval = -EREMOTEIO; | 3201 | *nfs_retval = -EREMOTEIO; |
3215 | return false; | 3202 | return false; |
3216 | out_overflow: | 3203 | out_overflow: |
3217 | print_overflow_msg(__func__, xdr); | ||
3218 | *nfs_retval = -EIO; | 3204 | *nfs_retval = -EIO; |
3219 | return false; | 3205 | return false; |
3220 | } | 3206 | } |
@@ -3235,10 +3221,9 @@ static int decode_ace(struct xdr_stream *xdr, void *ace) | |||
3235 | char *str; | 3221 | char *str; |
3236 | 3222 | ||
3237 | p = xdr_inline_decode(xdr, 12); | 3223 | p = xdr_inline_decode(xdr, 12); |
3238 | if (likely(p)) | 3224 | if (unlikely(!p)) |
3239 | return decode_opaque_inline(xdr, &strlen, &str); | 3225 | return -EIO; |
3240 | print_overflow_msg(__func__, xdr); | 3226 | return decode_opaque_inline(xdr, &strlen, &str); |
3241 | return -EIO; | ||
3242 | } | 3227 | } |
3243 | 3228 | ||
3244 | static ssize_t | 3229 | static ssize_t |
@@ -3249,10 +3234,9 @@ decode_bitmap4(struct xdr_stream *xdr, uint32_t *bitmap, size_t sz) | |||
3249 | ret = xdr_stream_decode_uint32_array(xdr, bitmap, sz); | 3234 | ret = xdr_stream_decode_uint32_array(xdr, bitmap, sz); |
3250 | if (likely(ret >= 0)) | 3235 | if (likely(ret >= 0)) |
3251 | return ret; | 3236 | return ret; |
3252 | if (ret == -EMSGSIZE) | 3237 | if (ret != -EMSGSIZE) |
3253 | return sz; | 3238 | return -EIO; |
3254 | print_overflow_msg(__func__, xdr); | 3239 | return sz; |
3255 | return -EIO; | ||
3256 | } | 3240 | } |
3257 | 3241 | ||
3258 | static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | 3242 | static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) |
@@ -3268,13 +3252,10 @@ static int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, unsigne | |||
3268 | 3252 | ||
3269 | p = xdr_inline_decode(xdr, 4); | 3253 | p = xdr_inline_decode(xdr, 4); |
3270 | if (unlikely(!p)) | 3254 | if (unlikely(!p)) |
3271 | goto out_overflow; | 3255 | return -EIO; |
3272 | *attrlen = be32_to_cpup(p); | 3256 | *attrlen = be32_to_cpup(p); |
3273 | *savep = xdr_stream_pos(xdr); | 3257 | *savep = xdr_stream_pos(xdr); |
3274 | return 0; | 3258 | return 0; |
3275 | out_overflow: | ||
3276 | print_overflow_msg(__func__, xdr); | ||
3277 | return -EIO; | ||
3278 | } | 3259 | } |
3279 | 3260 | ||
3280 | static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) | 3261 | static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) |
@@ -3303,7 +3284,7 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * | |||
3303 | if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { | 3284 | if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { |
3304 | p = xdr_inline_decode(xdr, 4); | 3285 | p = xdr_inline_decode(xdr, 4); |
3305 | if (unlikely(!p)) | 3286 | if (unlikely(!p)) |
3306 | goto out_overflow; | 3287 | return -EIO; |
3307 | *type = be32_to_cpup(p); | 3288 | *type = be32_to_cpup(p); |
3308 | if (*type < NF4REG || *type > NF4NAMEDATTR) { | 3289 | if (*type < NF4REG || *type > NF4NAMEDATTR) { |
3309 | dprintk("%s: bad type %d\n", __func__, *type); | 3290 | dprintk("%s: bad type %d\n", __func__, *type); |
@@ -3314,9 +3295,6 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * | |||
3314 | } | 3295 | } |
3315 | dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); | 3296 | dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); |
3316 | return ret; | 3297 | return ret; |
3317 | out_overflow: | ||
3318 | print_overflow_msg(__func__, xdr); | ||
3319 | return -EIO; | ||
3320 | } | 3298 | } |
3321 | 3299 | ||
3322 | static int decode_attr_fh_expire_type(struct xdr_stream *xdr, | 3300 | static int decode_attr_fh_expire_type(struct xdr_stream *xdr, |
@@ -3330,15 +3308,12 @@ static int decode_attr_fh_expire_type(struct xdr_stream *xdr, | |||
3330 | if (likely(bitmap[0] & FATTR4_WORD0_FH_EXPIRE_TYPE)) { | 3308 | if (likely(bitmap[0] & FATTR4_WORD0_FH_EXPIRE_TYPE)) { |
3331 | p = xdr_inline_decode(xdr, 4); | 3309 | p = xdr_inline_decode(xdr, 4); |
3332 | if (unlikely(!p)) | 3310 | if (unlikely(!p)) |
3333 | goto out_overflow; | 3311 | return -EIO; |
3334 | *type = be32_to_cpup(p); | 3312 | *type = be32_to_cpup(p); |
3335 | bitmap[0] &= ~FATTR4_WORD0_FH_EXPIRE_TYPE; | 3313 | bitmap[0] &= ~FATTR4_WORD0_FH_EXPIRE_TYPE; |
3336 | } | 3314 | } |
3337 | dprintk("%s: expire type=0x%x\n", __func__, *type); | 3315 | dprintk("%s: expire type=0x%x\n", __func__, *type); |
3338 | return 0; | 3316 | return 0; |
3339 | out_overflow: | ||
3340 | print_overflow_msg(__func__, xdr); | ||
3341 | return -EIO; | ||
3342 | } | 3317 | } |
3343 | 3318 | ||
3344 | static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) | 3319 | static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) |
@@ -3352,7 +3327,7 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
3352 | if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { | 3327 | if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { |
3353 | p = xdr_inline_decode(xdr, 8); | 3328 | p = xdr_inline_decode(xdr, 8); |
3354 | if (unlikely(!p)) | 3329 | if (unlikely(!p)) |
3355 | goto out_overflow; | 3330 | return -EIO; |
3356 | xdr_decode_hyper(p, change); | 3331 | xdr_decode_hyper(p, change); |
3357 | bitmap[0] &= ~FATTR4_WORD0_CHANGE; | 3332 | bitmap[0] &= ~FATTR4_WORD0_CHANGE; |
3358 | ret = NFS_ATTR_FATTR_CHANGE; | 3333 | ret = NFS_ATTR_FATTR_CHANGE; |
@@ -3360,9 +3335,6 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
3360 | dprintk("%s: change attribute=%Lu\n", __func__, | 3335 | dprintk("%s: change attribute=%Lu\n", __func__, |
3361 | (unsigned long long)*change); | 3336 | (unsigned long long)*change); |
3362 | return ret; | 3337 | return ret; |
3363 | out_overflow: | ||
3364 | print_overflow_msg(__func__, xdr); | ||
3365 | return -EIO; | ||
3366 | } | 3338 | } |
3367 | 3339 | ||
3368 | static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) | 3340 | static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) |
@@ -3376,16 +3348,13 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * | |||
3376 | if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { | 3348 | if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { |
3377 | p = xdr_inline_decode(xdr, 8); | 3349 | p = xdr_inline_decode(xdr, 8); |
3378 | if (unlikely(!p)) | 3350 | if (unlikely(!p)) |
3379 | goto out_overflow; | 3351 | return -EIO; |
3380 | xdr_decode_hyper(p, size); | 3352 | xdr_decode_hyper(p, size); |
3381 | bitmap[0] &= ~FATTR4_WORD0_SIZE; | 3353 | bitmap[0] &= ~FATTR4_WORD0_SIZE; |
3382 | ret = NFS_ATTR_FATTR_SIZE; | 3354 | ret = NFS_ATTR_FATTR_SIZE; |
3383 | } | 3355 | } |
3384 | dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); | 3356 | dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); |
3385 | return ret; | 3357 | return ret; |
3386 | out_overflow: | ||
3387 | print_overflow_msg(__func__, xdr); | ||
3388 | return -EIO; | ||
3389 | } | 3358 | } |
3390 | 3359 | ||
3391 | static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3360 | static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3398,15 +3367,12 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui | |||
3398 | if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { | 3367 | if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { |
3399 | p = xdr_inline_decode(xdr, 4); | 3368 | p = xdr_inline_decode(xdr, 4); |
3400 | if (unlikely(!p)) | 3369 | if (unlikely(!p)) |
3401 | goto out_overflow; | 3370 | return -EIO; |
3402 | *res = be32_to_cpup(p); | 3371 | *res = be32_to_cpup(p); |
3403 | bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; | 3372 | bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; |
3404 | } | 3373 | } |
3405 | dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); | 3374 | dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); |
3406 | return 0; | 3375 | return 0; |
3407 | out_overflow: | ||
3408 | print_overflow_msg(__func__, xdr); | ||
3409 | return -EIO; | ||
3410 | } | 3376 | } |
3411 | 3377 | ||
3412 | static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3378 | static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3419,15 +3385,12 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, | |||
3419 | if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { | 3385 | if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { |
3420 | p = xdr_inline_decode(xdr, 4); | 3386 | p = xdr_inline_decode(xdr, 4); |
3421 | if (unlikely(!p)) | 3387 | if (unlikely(!p)) |
3422 | goto out_overflow; | 3388 | return -EIO; |
3423 | *res = be32_to_cpup(p); | 3389 | *res = be32_to_cpup(p); |
3424 | bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; | 3390 | bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; |
3425 | } | 3391 | } |
3426 | dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); | 3392 | dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); |
3427 | return 0; | 3393 | return 0; |
3428 | out_overflow: | ||
3429 | print_overflow_msg(__func__, xdr); | ||
3430 | return -EIO; | ||
3431 | } | 3394 | } |
3432 | 3395 | ||
3433 | static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) | 3396 | static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) |
@@ -3442,7 +3405,7 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs | |||
3442 | if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { | 3405 | if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { |
3443 | p = xdr_inline_decode(xdr, 16); | 3406 | p = xdr_inline_decode(xdr, 16); |
3444 | if (unlikely(!p)) | 3407 | if (unlikely(!p)) |
3445 | goto out_overflow; | 3408 | return -EIO; |
3446 | p = xdr_decode_hyper(p, &fsid->major); | 3409 | p = xdr_decode_hyper(p, &fsid->major); |
3447 | xdr_decode_hyper(p, &fsid->minor); | 3410 | xdr_decode_hyper(p, &fsid->minor); |
3448 | bitmap[0] &= ~FATTR4_WORD0_FSID; | 3411 | bitmap[0] &= ~FATTR4_WORD0_FSID; |
@@ -3452,9 +3415,6 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs | |||
3452 | (unsigned long long)fsid->major, | 3415 | (unsigned long long)fsid->major, |
3453 | (unsigned long long)fsid->minor); | 3416 | (unsigned long long)fsid->minor); |
3454 | return ret; | 3417 | return ret; |
3455 | out_overflow: | ||
3456 | print_overflow_msg(__func__, xdr); | ||
3457 | return -EIO; | ||
3458 | } | 3418 | } |
3459 | 3419 | ||
3460 | static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3420 | static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3467,15 +3427,12 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3467 | if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { | 3427 | if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { |
3468 | p = xdr_inline_decode(xdr, 4); | 3428 | p = xdr_inline_decode(xdr, 4); |
3469 | if (unlikely(!p)) | 3429 | if (unlikely(!p)) |
3470 | goto out_overflow; | 3430 | return -EIO; |
3471 | *res = be32_to_cpup(p); | 3431 | *res = be32_to_cpup(p); |
3472 | bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; | 3432 | bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; |
3473 | } | 3433 | } |
3474 | dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); | 3434 | dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); |
3475 | return 0; | 3435 | return 0; |
3476 | out_overflow: | ||
3477 | print_overflow_msg(__func__, xdr); | ||
3478 | return -EIO; | ||
3479 | } | 3436 | } |
3480 | 3437 | ||
3481 | static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) | 3438 | static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) |
@@ -3487,14 +3444,11 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t * | |||
3487 | if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) { | 3444 | if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) { |
3488 | p = xdr_inline_decode(xdr, 4); | 3445 | p = xdr_inline_decode(xdr, 4); |
3489 | if (unlikely(!p)) | 3446 | if (unlikely(!p)) |
3490 | goto out_overflow; | 3447 | return -EIO; |
3491 | bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; | 3448 | bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; |
3492 | *res = -be32_to_cpup(p); | 3449 | *res = -be32_to_cpup(p); |
3493 | } | 3450 | } |
3494 | return 0; | 3451 | return 0; |
3495 | out_overflow: | ||
3496 | print_overflow_msg(__func__, xdr); | ||
3497 | return -EIO; | ||
3498 | } | 3452 | } |
3499 | 3453 | ||
3500 | static int decode_attr_exclcreat_supported(struct xdr_stream *xdr, | 3454 | static int decode_attr_exclcreat_supported(struct xdr_stream *xdr, |
@@ -3526,13 +3480,13 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru | |||
3526 | if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) { | 3480 | if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) { |
3527 | p = xdr_inline_decode(xdr, 4); | 3481 | p = xdr_inline_decode(xdr, 4); |
3528 | if (unlikely(!p)) | 3482 | if (unlikely(!p)) |
3529 | goto out_overflow; | 3483 | return -EIO; |
3530 | len = be32_to_cpup(p); | 3484 | len = be32_to_cpup(p); |
3531 | if (len > NFS4_FHSIZE) | 3485 | if (len > NFS4_FHSIZE) |
3532 | return -EIO; | 3486 | return -EIO; |
3533 | p = xdr_inline_decode(xdr, len); | 3487 | p = xdr_inline_decode(xdr, len); |
3534 | if (unlikely(!p)) | 3488 | if (unlikely(!p)) |
3535 | goto out_overflow; | 3489 | return -EIO; |
3536 | if (fh != NULL) { | 3490 | if (fh != NULL) { |
3537 | memcpy(fh->data, p, len); | 3491 | memcpy(fh->data, p, len); |
3538 | fh->size = len; | 3492 | fh->size = len; |
@@ -3540,9 +3494,6 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru | |||
3540 | bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE; | 3494 | bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE; |
3541 | } | 3495 | } |
3542 | return 0; | 3496 | return 0; |
3543 | out_overflow: | ||
3544 | print_overflow_msg(__func__, xdr); | ||
3545 | return -EIO; | ||
3546 | } | 3497 | } |
3547 | 3498 | ||
3548 | static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3499 | static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3555,15 +3506,12 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3555 | if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { | 3506 | if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { |
3556 | p = xdr_inline_decode(xdr, 4); | 3507 | p = xdr_inline_decode(xdr, 4); |
3557 | if (unlikely(!p)) | 3508 | if (unlikely(!p)) |
3558 | goto out_overflow; | 3509 | return -EIO; |
3559 | *res = be32_to_cpup(p); | 3510 | *res = be32_to_cpup(p); |
3560 | bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; | 3511 | bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; |
3561 | } | 3512 | } |
3562 | dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); | 3513 | dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); |
3563 | return 0; | 3514 | return 0; |
3564 | out_overflow: | ||
3565 | print_overflow_msg(__func__, xdr); | ||
3566 | return -EIO; | ||
3567 | } | 3515 | } |
3568 | 3516 | ||
3569 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) | 3517 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
@@ -3577,16 +3525,13 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
3577 | if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { | 3525 | if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { |
3578 | p = xdr_inline_decode(xdr, 8); | 3526 | p = xdr_inline_decode(xdr, 8); |
3579 | if (unlikely(!p)) | 3527 | if (unlikely(!p)) |
3580 | goto out_overflow; | 3528 | return -EIO; |
3581 | xdr_decode_hyper(p, fileid); | 3529 | xdr_decode_hyper(p, fileid); |
3582 | bitmap[0] &= ~FATTR4_WORD0_FILEID; | 3530 | bitmap[0] &= ~FATTR4_WORD0_FILEID; |
3583 | ret = NFS_ATTR_FATTR_FILEID; | 3531 | ret = NFS_ATTR_FATTR_FILEID; |
3584 | } | 3532 | } |
3585 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); | 3533 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); |
3586 | return ret; | 3534 | return ret; |
3587 | out_overflow: | ||
3588 | print_overflow_msg(__func__, xdr); | ||
3589 | return -EIO; | ||
3590 | } | 3535 | } |
3591 | 3536 | ||
3592 | static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) | 3537 | static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
@@ -3600,16 +3545,13 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma | |||
3600 | if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { | 3545 | if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { |
3601 | p = xdr_inline_decode(xdr, 8); | 3546 | p = xdr_inline_decode(xdr, 8); |
3602 | if (unlikely(!p)) | 3547 | if (unlikely(!p)) |
3603 | goto out_overflow; | 3548 | return -EIO; |
3604 | xdr_decode_hyper(p, fileid); | 3549 | xdr_decode_hyper(p, fileid); |
3605 | bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; | 3550 | bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; |
3606 | ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; | 3551 | ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; |
3607 | } | 3552 | } |
3608 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); | 3553 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); |
3609 | return ret; | 3554 | return ret; |
3610 | out_overflow: | ||
3611 | print_overflow_msg(__func__, xdr); | ||
3612 | return -EIO; | ||
3613 | } | 3555 | } |
3614 | 3556 | ||
3615 | static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3557 | static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3623,15 +3565,12 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3623 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { | 3565 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { |
3624 | p = xdr_inline_decode(xdr, 8); | 3566 | p = xdr_inline_decode(xdr, 8); |
3625 | if (unlikely(!p)) | 3567 | if (unlikely(!p)) |
3626 | goto out_overflow; | 3568 | return -EIO; |
3627 | xdr_decode_hyper(p, res); | 3569 | xdr_decode_hyper(p, res); |
3628 | bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; | 3570 | bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; |
3629 | } | 3571 | } |
3630 | dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); | 3572 | dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); |
3631 | return status; | 3573 | return status; |
3632 | out_overflow: | ||
3633 | print_overflow_msg(__func__, xdr); | ||
3634 | return -EIO; | ||
3635 | } | 3574 | } |
3636 | 3575 | ||
3637 | static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3576 | static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3645,15 +3584,12 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3645 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { | 3584 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { |
3646 | p = xdr_inline_decode(xdr, 8); | 3585 | p = xdr_inline_decode(xdr, 8); |
3647 | if (unlikely(!p)) | 3586 | if (unlikely(!p)) |
3648 | goto out_overflow; | 3587 | return -EIO; |
3649 | xdr_decode_hyper(p, res); | 3588 | xdr_decode_hyper(p, res); |
3650 | bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; | 3589 | bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; |
3651 | } | 3590 | } |
3652 | dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); | 3591 | dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); |
3653 | return status; | 3592 | return status; |
3654 | out_overflow: | ||
3655 | print_overflow_msg(__func__, xdr); | ||
3656 | return -EIO; | ||
3657 | } | 3593 | } |
3658 | 3594 | ||
3659 | static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3595 | static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3667,15 +3603,12 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3667 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { | 3603 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { |
3668 | p = xdr_inline_decode(xdr, 8); | 3604 | p = xdr_inline_decode(xdr, 8); |
3669 | if (unlikely(!p)) | 3605 | if (unlikely(!p)) |
3670 | goto out_overflow; | 3606 | return -EIO; |
3671 | xdr_decode_hyper(p, res); | 3607 | xdr_decode_hyper(p, res); |
3672 | bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; | 3608 | bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; |
3673 | } | 3609 | } |
3674 | dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); | 3610 | dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); |
3675 | return status; | 3611 | return status; |
3676 | out_overflow: | ||
3677 | print_overflow_msg(__func__, xdr); | ||
3678 | return -EIO; | ||
3679 | } | 3612 | } |
3680 | 3613 | ||
3681 | static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | 3614 | static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) |
@@ -3686,7 +3619,7 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
3686 | 3619 | ||
3687 | p = xdr_inline_decode(xdr, 4); | 3620 | p = xdr_inline_decode(xdr, 4); |
3688 | if (unlikely(!p)) | 3621 | if (unlikely(!p)) |
3689 | goto out_overflow; | 3622 | return -EIO; |
3690 | n = be32_to_cpup(p); | 3623 | n = be32_to_cpup(p); |
3691 | if (n == 0) | 3624 | if (n == 0) |
3692 | goto root_path; | 3625 | goto root_path; |
@@ -3718,9 +3651,6 @@ out_eio: | |||
3718 | dprintk(" status %d", status); | 3651 | dprintk(" status %d", status); |
3719 | status = -EIO; | 3652 | status = -EIO; |
3720 | goto out; | 3653 | goto out; |
3721 | out_overflow: | ||
3722 | print_overflow_msg(__func__, xdr); | ||
3723 | return -EIO; | ||
3724 | } | 3654 | } |
3725 | 3655 | ||
3726 | static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) | 3656 | static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) |
@@ -3745,7 +3675,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3745 | goto out; | 3675 | goto out; |
3746 | p = xdr_inline_decode(xdr, 4); | 3676 | p = xdr_inline_decode(xdr, 4); |
3747 | if (unlikely(!p)) | 3677 | if (unlikely(!p)) |
3748 | goto out_overflow; | 3678 | goto out_eio; |
3749 | n = be32_to_cpup(p); | 3679 | n = be32_to_cpup(p); |
3750 | if (n <= 0) | 3680 | if (n <= 0) |
3751 | goto out_eio; | 3681 | goto out_eio; |
@@ -3758,7 +3688,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3758 | loc = &res->locations[res->nlocations]; | 3688 | loc = &res->locations[res->nlocations]; |
3759 | p = xdr_inline_decode(xdr, 4); | 3689 | p = xdr_inline_decode(xdr, 4); |
3760 | if (unlikely(!p)) | 3690 | if (unlikely(!p)) |
3761 | goto out_overflow; | 3691 | goto out_eio; |
3762 | m = be32_to_cpup(p); | 3692 | m = be32_to_cpup(p); |
3763 | 3693 | ||
3764 | dprintk("%s: servers:\n", __func__); | 3694 | dprintk("%s: servers:\n", __func__); |
@@ -3796,8 +3726,6 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3796 | out: | 3726 | out: |
3797 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); | 3727 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); |
3798 | return status; | 3728 | return status; |
3799 | out_overflow: | ||
3800 | print_overflow_msg(__func__, xdr); | ||
3801 | out_eio: | 3729 | out_eio: |
3802 | status = -EIO; | 3730 | status = -EIO; |
3803 | goto out; | 3731 | goto out; |
@@ -3814,15 +3742,12 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3814 | if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { | 3742 | if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { |
3815 | p = xdr_inline_decode(xdr, 8); | 3743 | p = xdr_inline_decode(xdr, 8); |
3816 | if (unlikely(!p)) | 3744 | if (unlikely(!p)) |
3817 | goto out_overflow; | 3745 | return -EIO; |
3818 | xdr_decode_hyper(p, res); | 3746 | xdr_decode_hyper(p, res); |
3819 | bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; | 3747 | bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; |
3820 | } | 3748 | } |
3821 | dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); | 3749 | dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); |
3822 | return status; | 3750 | return status; |
3823 | out_overflow: | ||
3824 | print_overflow_msg(__func__, xdr); | ||
3825 | return -EIO; | ||
3826 | } | 3751 | } |
3827 | 3752 | ||
3828 | static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) | 3753 | static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) |
@@ -3836,15 +3761,12 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
3836 | if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { | 3761 | if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { |
3837 | p = xdr_inline_decode(xdr, 4); | 3762 | p = xdr_inline_decode(xdr, 4); |
3838 | if (unlikely(!p)) | 3763 | if (unlikely(!p)) |
3839 | goto out_overflow; | 3764 | return -EIO; |
3840 | *maxlink = be32_to_cpup(p); | 3765 | *maxlink = be32_to_cpup(p); |
3841 | bitmap[0] &= ~FATTR4_WORD0_MAXLINK; | 3766 | bitmap[0] &= ~FATTR4_WORD0_MAXLINK; |
3842 | } | 3767 | } |
3843 | dprintk("%s: maxlink=%u\n", __func__, *maxlink); | 3768 | dprintk("%s: maxlink=%u\n", __func__, *maxlink); |
3844 | return status; | 3769 | return status; |
3845 | out_overflow: | ||
3846 | print_overflow_msg(__func__, xdr); | ||
3847 | return -EIO; | ||
3848 | } | 3770 | } |
3849 | 3771 | ||
3850 | static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) | 3772 | static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) |
@@ -3858,15 +3780,12 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
3858 | if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { | 3780 | if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { |
3859 | p = xdr_inline_decode(xdr, 4); | 3781 | p = xdr_inline_decode(xdr, 4); |
3860 | if (unlikely(!p)) | 3782 | if (unlikely(!p)) |
3861 | goto out_overflow; | 3783 | return -EIO; |
3862 | *maxname = be32_to_cpup(p); | 3784 | *maxname = be32_to_cpup(p); |
3863 | bitmap[0] &= ~FATTR4_WORD0_MAXNAME; | 3785 | bitmap[0] &= ~FATTR4_WORD0_MAXNAME; |
3864 | } | 3786 | } |
3865 | dprintk("%s: maxname=%u\n", __func__, *maxname); | 3787 | dprintk("%s: maxname=%u\n", __func__, *maxname); |
3866 | return status; | 3788 | return status; |
3867 | out_overflow: | ||
3868 | print_overflow_msg(__func__, xdr); | ||
3869 | return -EIO; | ||
3870 | } | 3789 | } |
3871 | 3790 | ||
3872 | static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3791 | static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3881,7 +3800,7 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
3881 | uint64_t maxread; | 3800 | uint64_t maxread; |
3882 | p = xdr_inline_decode(xdr, 8); | 3801 | p = xdr_inline_decode(xdr, 8); |
3883 | if (unlikely(!p)) | 3802 | if (unlikely(!p)) |
3884 | goto out_overflow; | 3803 | return -EIO; |
3885 | xdr_decode_hyper(p, &maxread); | 3804 | xdr_decode_hyper(p, &maxread); |
3886 | if (maxread > 0x7FFFFFFF) | 3805 | if (maxread > 0x7FFFFFFF) |
3887 | maxread = 0x7FFFFFFF; | 3806 | maxread = 0x7FFFFFFF; |
@@ -3890,9 +3809,6 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
3890 | } | 3809 | } |
3891 | dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); | 3810 | dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); |
3892 | return status; | 3811 | return status; |
3893 | out_overflow: | ||
3894 | print_overflow_msg(__func__, xdr); | ||
3895 | return -EIO; | ||
3896 | } | 3812 | } |
3897 | 3813 | ||
3898 | static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3814 | static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -3907,7 +3823,7 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 | |||
3907 | uint64_t maxwrite; | 3823 | uint64_t maxwrite; |
3908 | p = xdr_inline_decode(xdr, 8); | 3824 | p = xdr_inline_decode(xdr, 8); |
3909 | if (unlikely(!p)) | 3825 | if (unlikely(!p)) |
3910 | goto out_overflow; | 3826 | return -EIO; |
3911 | xdr_decode_hyper(p, &maxwrite); | 3827 | xdr_decode_hyper(p, &maxwrite); |
3912 | if (maxwrite > 0x7FFFFFFF) | 3828 | if (maxwrite > 0x7FFFFFFF) |
3913 | maxwrite = 0x7FFFFFFF; | 3829 | maxwrite = 0x7FFFFFFF; |
@@ -3916,9 +3832,6 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 | |||
3916 | } | 3832 | } |
3917 | dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); | 3833 | dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); |
3918 | return status; | 3834 | return status; |
3919 | out_overflow: | ||
3920 | print_overflow_msg(__func__, xdr); | ||
3921 | return -EIO; | ||
3922 | } | 3835 | } |
3923 | 3836 | ||
3924 | static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) | 3837 | static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) |
@@ -3933,7 +3846,7 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m | |||
3933 | if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { | 3846 | if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { |
3934 | p = xdr_inline_decode(xdr, 4); | 3847 | p = xdr_inline_decode(xdr, 4); |
3935 | if (unlikely(!p)) | 3848 | if (unlikely(!p)) |
3936 | goto out_overflow; | 3849 | return -EIO; |
3937 | tmp = be32_to_cpup(p); | 3850 | tmp = be32_to_cpup(p); |
3938 | *mode = tmp & ~S_IFMT; | 3851 | *mode = tmp & ~S_IFMT; |
3939 | bitmap[1] &= ~FATTR4_WORD1_MODE; | 3852 | bitmap[1] &= ~FATTR4_WORD1_MODE; |
@@ -3941,9 +3854,6 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m | |||
3941 | } | 3854 | } |
3942 | dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); | 3855 | dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); |
3943 | return ret; | 3856 | return ret; |
3944 | out_overflow: | ||
3945 | print_overflow_msg(__func__, xdr); | ||
3946 | return -EIO; | ||
3947 | } | 3857 | } |
3948 | 3858 | ||
3949 | static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) | 3859 | static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) |
@@ -3957,16 +3867,13 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t | |||
3957 | if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { | 3867 | if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { |
3958 | p = xdr_inline_decode(xdr, 4); | 3868 | p = xdr_inline_decode(xdr, 4); |
3959 | if (unlikely(!p)) | 3869 | if (unlikely(!p)) |
3960 | goto out_overflow; | 3870 | return -EIO; |
3961 | *nlink = be32_to_cpup(p); | 3871 | *nlink = be32_to_cpup(p); |
3962 | bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; | 3872 | bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; |
3963 | ret = NFS_ATTR_FATTR_NLINK; | 3873 | ret = NFS_ATTR_FATTR_NLINK; |
3964 | } | 3874 | } |
3965 | dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); | 3875 | dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); |
3966 | return ret; | 3876 | return ret; |
3967 | out_overflow: | ||
3968 | print_overflow_msg(__func__, xdr); | ||
3969 | return -EIO; | ||
3970 | } | 3877 | } |
3971 | 3878 | ||
3972 | static ssize_t decode_nfs4_string(struct xdr_stream *xdr, | 3879 | static ssize_t decode_nfs4_string(struct xdr_stream *xdr, |
@@ -4011,10 +3918,9 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4011 | return NFS_ATTR_FATTR_OWNER; | 3918 | return NFS_ATTR_FATTR_OWNER; |
4012 | } | 3919 | } |
4013 | out: | 3920 | out: |
4014 | if (len != -EBADMSG) | 3921 | if (len == -EBADMSG) |
4015 | return 0; | 3922 | return -EIO; |
4016 | print_overflow_msg(__func__, xdr); | 3923 | return 0; |
4017 | return -EIO; | ||
4018 | } | 3924 | } |
4019 | 3925 | ||
4020 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | 3926 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, |
@@ -4046,10 +3952,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4046 | return NFS_ATTR_FATTR_GROUP; | 3952 | return NFS_ATTR_FATTR_GROUP; |
4047 | } | 3953 | } |
4048 | out: | 3954 | out: |
4049 | if (len != -EBADMSG) | 3955 | if (len == -EBADMSG) |
4050 | return 0; | 3956 | return -EIO; |
4051 | print_overflow_msg(__func__, xdr); | 3957 | return 0; |
4052 | return -EIO; | ||
4053 | } | 3958 | } |
4054 | 3959 | ||
4055 | static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) | 3960 | static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) |
@@ -4066,7 +3971,7 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde | |||
4066 | 3971 | ||
4067 | p = xdr_inline_decode(xdr, 8); | 3972 | p = xdr_inline_decode(xdr, 8); |
4068 | if (unlikely(!p)) | 3973 | if (unlikely(!p)) |
4069 | goto out_overflow; | 3974 | return -EIO; |
4070 | major = be32_to_cpup(p++); | 3975 | major = be32_to_cpup(p++); |
4071 | minor = be32_to_cpup(p); | 3976 | minor = be32_to_cpup(p); |
4072 | tmp = MKDEV(major, minor); | 3977 | tmp = MKDEV(major, minor); |
@@ -4077,9 +3982,6 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde | |||
4077 | } | 3982 | } |
4078 | dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); | 3983 | dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); |
4079 | return ret; | 3984 | return ret; |
4080 | out_overflow: | ||
4081 | print_overflow_msg(__func__, xdr); | ||
4082 | return -EIO; | ||
4083 | } | 3985 | } |
4084 | 3986 | ||
4085 | static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3987 | static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -4093,15 +3995,12 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
4093 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { | 3995 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { |
4094 | p = xdr_inline_decode(xdr, 8); | 3996 | p = xdr_inline_decode(xdr, 8); |
4095 | if (unlikely(!p)) | 3997 | if (unlikely(!p)) |
4096 | goto out_overflow; | 3998 | return -EIO; |
4097 | xdr_decode_hyper(p, res); | 3999 | xdr_decode_hyper(p, res); |
4098 | bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; | 4000 | bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; |
4099 | } | 4001 | } |
4100 | dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); | 4002 | dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); |
4101 | return status; | 4003 | return status; |
4102 | out_overflow: | ||
4103 | print_overflow_msg(__func__, xdr); | ||
4104 | return -EIO; | ||
4105 | } | 4004 | } |
4106 | 4005 | ||
4107 | static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 4006 | static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -4115,15 +4014,12 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
4115 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { | 4014 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { |
4116 | p = xdr_inline_decode(xdr, 8); | 4015 | p = xdr_inline_decode(xdr, 8); |
4117 | if (unlikely(!p)) | 4016 | if (unlikely(!p)) |
4118 | goto out_overflow; | 4017 | return -EIO; |
4119 | xdr_decode_hyper(p, res); | 4018 | xdr_decode_hyper(p, res); |
4120 | bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; | 4019 | bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; |
4121 | } | 4020 | } |
4122 | dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); | 4021 | dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); |
4123 | return status; | 4022 | return status; |
4124 | out_overflow: | ||
4125 | print_overflow_msg(__func__, xdr); | ||
4126 | return -EIO; | ||
4127 | } | 4023 | } |
4128 | 4024 | ||
4129 | static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 4025 | static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -4137,15 +4033,12 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
4137 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { | 4033 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { |
4138 | p = xdr_inline_decode(xdr, 8); | 4034 | p = xdr_inline_decode(xdr, 8); |
4139 | if (unlikely(!p)) | 4035 | if (unlikely(!p)) |
4140 | goto out_overflow; | 4036 | return -EIO; |
4141 | xdr_decode_hyper(p, res); | 4037 | xdr_decode_hyper(p, res); |
4142 | bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; | 4038 | bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; |
4143 | } | 4039 | } |
4144 | dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); | 4040 | dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); |
4145 | return status; | 4041 | return status; |
4146 | out_overflow: | ||
4147 | print_overflow_msg(__func__, xdr); | ||
4148 | return -EIO; | ||
4149 | } | 4042 | } |
4150 | 4043 | ||
4151 | static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) | 4044 | static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) |
@@ -4159,7 +4052,7 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
4159 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { | 4052 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { |
4160 | p = xdr_inline_decode(xdr, 8); | 4053 | p = xdr_inline_decode(xdr, 8); |
4161 | if (unlikely(!p)) | 4054 | if (unlikely(!p)) |
4162 | goto out_overflow; | 4055 | return -EIO; |
4163 | xdr_decode_hyper(p, used); | 4056 | xdr_decode_hyper(p, used); |
4164 | bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; | 4057 | bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; |
4165 | ret = NFS_ATTR_FATTR_SPACE_USED; | 4058 | ret = NFS_ATTR_FATTR_SPACE_USED; |
@@ -4167,9 +4060,6 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
4167 | dprintk("%s: space used=%Lu\n", __func__, | 4060 | dprintk("%s: space used=%Lu\n", __func__, |
4168 | (unsigned long long)*used); | 4061 | (unsigned long long)*used); |
4169 | return ret; | 4062 | return ret; |
4170 | out_overflow: | ||
4171 | print_overflow_msg(__func__, xdr); | ||
4172 | return -EIO; | ||
4173 | } | 4063 | } |
4174 | 4064 | ||
4175 | static __be32 * | 4065 | static __be32 * |
@@ -4189,12 +4079,9 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) | |||
4189 | 4079 | ||
4190 | p = xdr_inline_decode(xdr, nfstime4_maxsz << 2); | 4080 | p = xdr_inline_decode(xdr, nfstime4_maxsz << 2); |
4191 | if (unlikely(!p)) | 4081 | if (unlikely(!p)) |
4192 | goto out_overflow; | 4082 | return -EIO; |
4193 | xdr_decode_nfstime4(p, time); | 4083 | xdr_decode_nfstime4(p, time); |
4194 | return 0; | 4084 | return 0; |
4195 | out_overflow: | ||
4196 | print_overflow_msg(__func__, xdr); | ||
4197 | return -EIO; | ||
4198 | } | 4085 | } |
4199 | 4086 | ||
4200 | static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) | 4087 | static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) |
@@ -4265,19 +4152,19 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4265 | if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) { | 4152 | if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) { |
4266 | p = xdr_inline_decode(xdr, 4); | 4153 | p = xdr_inline_decode(xdr, 4); |
4267 | if (unlikely(!p)) | 4154 | if (unlikely(!p)) |
4268 | goto out_overflow; | 4155 | return -EIO; |
4269 | lfs = be32_to_cpup(p++); | 4156 | lfs = be32_to_cpup(p++); |
4270 | p = xdr_inline_decode(xdr, 4); | 4157 | p = xdr_inline_decode(xdr, 4); |
4271 | if (unlikely(!p)) | 4158 | if (unlikely(!p)) |
4272 | goto out_overflow; | 4159 | return -EIO; |
4273 | pi = be32_to_cpup(p++); | 4160 | pi = be32_to_cpup(p++); |
4274 | p = xdr_inline_decode(xdr, 4); | 4161 | p = xdr_inline_decode(xdr, 4); |
4275 | if (unlikely(!p)) | 4162 | if (unlikely(!p)) |
4276 | goto out_overflow; | 4163 | return -EIO; |
4277 | len = be32_to_cpup(p++); | 4164 | len = be32_to_cpup(p++); |
4278 | p = xdr_inline_decode(xdr, len); | 4165 | p = xdr_inline_decode(xdr, len); |
4279 | if (unlikely(!p)) | 4166 | if (unlikely(!p)) |
4280 | goto out_overflow; | 4167 | return -EIO; |
4281 | if (len < NFS4_MAXLABELLEN) { | 4168 | if (len < NFS4_MAXLABELLEN) { |
4282 | if (label) { | 4169 | if (label) { |
4283 | memcpy(label->label, p, len); | 4170 | memcpy(label->label, p, len); |
@@ -4295,10 +4182,6 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4295 | dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__, | 4182 | dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__, |
4296 | (char *)label->label, label->len, label->pi, label->lfs); | 4183 | (char *)label->label, label->len, label->pi, label->lfs); |
4297 | return status; | 4184 | return status; |
4298 | |||
4299 | out_overflow: | ||
4300 | print_overflow_msg(__func__, xdr); | ||
4301 | return -EIO; | ||
4302 | } | 4185 | } |
4303 | 4186 | ||
4304 | static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) | 4187 | static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) |
@@ -4342,14 +4225,11 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c | |||
4342 | 4225 | ||
4343 | p = xdr_inline_decode(xdr, 20); | 4226 | p = xdr_inline_decode(xdr, 20); |
4344 | if (unlikely(!p)) | 4227 | if (unlikely(!p)) |
4345 | goto out_overflow; | 4228 | return -EIO; |
4346 | cinfo->atomic = be32_to_cpup(p++); | 4229 | cinfo->atomic = be32_to_cpup(p++); |
4347 | p = xdr_decode_hyper(p, &cinfo->before); | 4230 | p = xdr_decode_hyper(p, &cinfo->before); |
4348 | xdr_decode_hyper(p, &cinfo->after); | 4231 | xdr_decode_hyper(p, &cinfo->after); |
4349 | return 0; | 4232 | return 0; |
4350 | out_overflow: | ||
4351 | print_overflow_msg(__func__, xdr); | ||
4352 | return -EIO; | ||
4353 | } | 4233 | } |
4354 | 4234 | ||
4355 | static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) | 4235 | static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) |
@@ -4363,24 +4243,19 @@ static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) | |||
4363 | return status; | 4243 | return status; |
4364 | p = xdr_inline_decode(xdr, 8); | 4244 | p = xdr_inline_decode(xdr, 8); |
4365 | if (unlikely(!p)) | 4245 | if (unlikely(!p)) |
4366 | goto out_overflow; | 4246 | return -EIO; |
4367 | supp = be32_to_cpup(p++); | 4247 | supp = be32_to_cpup(p++); |
4368 | acc = be32_to_cpup(p); | 4248 | acc = be32_to_cpup(p); |
4369 | *supported = supp; | 4249 | *supported = supp; |
4370 | *access = acc; | 4250 | *access = acc; |
4371 | return 0; | 4251 | return 0; |
4372 | out_overflow: | ||
4373 | print_overflow_msg(__func__, xdr); | ||
4374 | return -EIO; | ||
4375 | } | 4252 | } |
4376 | 4253 | ||
4377 | static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) | 4254 | static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) |
4378 | { | 4255 | { |
4379 | ssize_t ret = xdr_stream_decode_opaque_fixed(xdr, buf, len); | 4256 | ssize_t ret = xdr_stream_decode_opaque_fixed(xdr, buf, len); |
4380 | if (unlikely(ret < 0)) { | 4257 | if (unlikely(ret < 0)) |
4381 | print_overflow_msg(__func__, xdr); | ||
4382 | return -EIO; | 4258 | return -EIO; |
4383 | } | ||
4384 | return 0; | 4259 | return 0; |
4385 | } | 4260 | } |
4386 | 4261 | ||
@@ -4460,13 +4335,11 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | |||
4460 | return status; | 4335 | return status; |
4461 | p = xdr_inline_decode(xdr, 4); | 4336 | p = xdr_inline_decode(xdr, 4); |
4462 | if (unlikely(!p)) | 4337 | if (unlikely(!p)) |
4463 | goto out_overflow; | 4338 | return -EIO; |
4464 | bmlen = be32_to_cpup(p); | 4339 | bmlen = be32_to_cpup(p); |
4465 | p = xdr_inline_decode(xdr, bmlen << 2); | 4340 | p = xdr_inline_decode(xdr, bmlen << 2); |
4466 | if (likely(p)) | 4341 | if (likely(p)) |
4467 | return 0; | 4342 | return 0; |
4468 | out_overflow: | ||
4469 | print_overflow_msg(__func__, xdr); | ||
4470 | return -EIO; | 4343 | return -EIO; |
4471 | } | 4344 | } |
4472 | 4345 | ||
@@ -4574,13 +4447,10 @@ static int decode_threshold_hint(struct xdr_stream *xdr, | |||
4574 | if (likely(bitmap[0] & hint_bit)) { | 4447 | if (likely(bitmap[0] & hint_bit)) { |
4575 | p = xdr_inline_decode(xdr, 8); | 4448 | p = xdr_inline_decode(xdr, 8); |
4576 | if (unlikely(!p)) | 4449 | if (unlikely(!p)) |
4577 | goto out_overflow; | 4450 | return -EIO; |
4578 | xdr_decode_hyper(p, res); | 4451 | xdr_decode_hyper(p, res); |
4579 | } | 4452 | } |
4580 | return 0; | 4453 | return 0; |
4581 | out_overflow: | ||
4582 | print_overflow_msg(__func__, xdr); | ||
4583 | return -EIO; | ||
4584 | } | 4454 | } |
4585 | 4455 | ||
4586 | static int decode_first_threshold_item4(struct xdr_stream *xdr, | 4456 | static int decode_first_threshold_item4(struct xdr_stream *xdr, |
@@ -4593,10 +4463,8 @@ static int decode_first_threshold_item4(struct xdr_stream *xdr, | |||
4593 | 4463 | ||
4594 | /* layout type */ | 4464 | /* layout type */ |
4595 | p = xdr_inline_decode(xdr, 4); | 4465 | p = xdr_inline_decode(xdr, 4); |
4596 | if (unlikely(!p)) { | 4466 | if (unlikely(!p)) |
4597 | print_overflow_msg(__func__, xdr); | ||
4598 | return -EIO; | 4467 | return -EIO; |
4599 | } | ||
4600 | res->l_type = be32_to_cpup(p); | 4468 | res->l_type = be32_to_cpup(p); |
4601 | 4469 | ||
4602 | /* thi_hintset bitmap */ | 4470 | /* thi_hintset bitmap */ |
@@ -4654,7 +4522,7 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr, | |||
4654 | return -EREMOTEIO; | 4522 | return -EREMOTEIO; |
4655 | p = xdr_inline_decode(xdr, 4); | 4523 | p = xdr_inline_decode(xdr, 4); |
4656 | if (unlikely(!p)) | 4524 | if (unlikely(!p)) |
4657 | goto out_overflow; | 4525 | return -EIO; |
4658 | num = be32_to_cpup(p); | 4526 | num = be32_to_cpup(p); |
4659 | if (num == 0) | 4527 | if (num == 0) |
4660 | return 0; | 4528 | return 0; |
@@ -4667,9 +4535,6 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr, | |||
4667 | bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD; | 4535 | bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD; |
4668 | } | 4536 | } |
4669 | return status; | 4537 | return status; |
4670 | out_overflow: | ||
4671 | print_overflow_msg(__func__, xdr); | ||
4672 | return -EIO; | ||
4673 | } | 4538 | } |
4674 | 4539 | ||
4675 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | 4540 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, |
@@ -4857,7 +4722,7 @@ static int decode_pnfs_layout_types(struct xdr_stream *xdr, | |||
4857 | 4722 | ||
4858 | p = xdr_inline_decode(xdr, 4); | 4723 | p = xdr_inline_decode(xdr, 4); |
4859 | if (unlikely(!p)) | 4724 | if (unlikely(!p)) |
4860 | goto out_overflow; | 4725 | return -EIO; |
4861 | fsinfo->nlayouttypes = be32_to_cpup(p); | 4726 | fsinfo->nlayouttypes = be32_to_cpup(p); |
4862 | 4727 | ||
4863 | /* pNFS is not supported by the underlying file system */ | 4728 | /* pNFS is not supported by the underlying file system */ |
@@ -4867,7 +4732,7 @@ static int decode_pnfs_layout_types(struct xdr_stream *xdr, | |||
4867 | /* Decode and set first layout type, move xdr->p past unused types */ | 4732 | /* Decode and set first layout type, move xdr->p past unused types */ |
4868 | p = xdr_inline_decode(xdr, fsinfo->nlayouttypes * 4); | 4733 | p = xdr_inline_decode(xdr, fsinfo->nlayouttypes * 4); |
4869 | if (unlikely(!p)) | 4734 | if (unlikely(!p)) |
4870 | goto out_overflow; | 4735 | return -EIO; |
4871 | 4736 | ||
4872 | /* If we get too many, then just cap it at the max */ | 4737 | /* If we get too many, then just cap it at the max */ |
4873 | if (fsinfo->nlayouttypes > NFS_MAX_LAYOUT_TYPES) { | 4738 | if (fsinfo->nlayouttypes > NFS_MAX_LAYOUT_TYPES) { |
@@ -4879,9 +4744,6 @@ static int decode_pnfs_layout_types(struct xdr_stream *xdr, | |||
4879 | for(i = 0; i < fsinfo->nlayouttypes; ++i) | 4744 | for(i = 0; i < fsinfo->nlayouttypes; ++i) |
4880 | fsinfo->layouttype[i] = be32_to_cpup(p++); | 4745 | fsinfo->layouttype[i] = be32_to_cpup(p++); |
4881 | return 0; | 4746 | return 0; |
4882 | out_overflow: | ||
4883 | print_overflow_msg(__func__, xdr); | ||
4884 | return -EIO; | ||
4885 | } | 4747 | } |
4886 | 4748 | ||
4887 | /* | 4749 | /* |
@@ -4915,10 +4777,8 @@ static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4915 | *res = 0; | 4777 | *res = 0; |
4916 | if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) { | 4778 | if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) { |
4917 | p = xdr_inline_decode(xdr, 4); | 4779 | p = xdr_inline_decode(xdr, 4); |
4918 | if (unlikely(!p)) { | 4780 | if (unlikely(!p)) |
4919 | print_overflow_msg(__func__, xdr); | ||
4920 | return -EIO; | 4781 | return -EIO; |
4921 | } | ||
4922 | *res = be32_to_cpup(p); | 4782 | *res = be32_to_cpup(p); |
4923 | bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE; | 4783 | bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE; |
4924 | } | 4784 | } |
@@ -4937,10 +4797,8 @@ static int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4937 | *res = 0; | 4797 | *res = 0; |
4938 | if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) { | 4798 | if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) { |
4939 | p = xdr_inline_decode(xdr, 4); | 4799 | p = xdr_inline_decode(xdr, 4); |
4940 | if (unlikely(!p)) { | 4800 | if (unlikely(!p)) |
4941 | print_overflow_msg(__func__, xdr); | ||
4942 | return -EIO; | 4801 | return -EIO; |
4943 | } | ||
4944 | *res = be32_to_cpup(p); | 4802 | *res = be32_to_cpup(p); |
4945 | bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE; | 4803 | bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE; |
4946 | } | 4804 | } |
@@ -5016,19 +4874,16 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
5016 | 4874 | ||
5017 | p = xdr_inline_decode(xdr, 4); | 4875 | p = xdr_inline_decode(xdr, 4); |
5018 | if (unlikely(!p)) | 4876 | if (unlikely(!p)) |
5019 | goto out_overflow; | 4877 | return -EIO; |
5020 | len = be32_to_cpup(p); | 4878 | len = be32_to_cpup(p); |
5021 | if (len > NFS4_FHSIZE) | 4879 | if (len > NFS4_FHSIZE) |
5022 | return -EIO; | 4880 | return -EIO; |
5023 | fh->size = len; | 4881 | fh->size = len; |
5024 | p = xdr_inline_decode(xdr, len); | 4882 | p = xdr_inline_decode(xdr, len); |
5025 | if (unlikely(!p)) | 4883 | if (unlikely(!p)) |
5026 | goto out_overflow; | 4884 | return -EIO; |
5027 | memcpy(fh->data, p, len); | 4885 | memcpy(fh->data, p, len); |
5028 | return 0; | 4886 | return 0; |
5029 | out_overflow: | ||
5030 | print_overflow_msg(__func__, xdr); | ||
5031 | return -EIO; | ||
5032 | } | 4887 | } |
5033 | 4888 | ||
5034 | static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 4889 | static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -5052,7 +4907,7 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) | |||
5052 | 4907 | ||
5053 | p = xdr_inline_decode(xdr, 32); /* read 32 bytes */ | 4908 | p = xdr_inline_decode(xdr, 32); /* read 32 bytes */ |
5054 | if (unlikely(!p)) | 4909 | if (unlikely(!p)) |
5055 | goto out_overflow; | 4910 | return -EIO; |
5056 | p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */ | 4911 | p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */ |
5057 | p = xdr_decode_hyper(p, &length); | 4912 | p = xdr_decode_hyper(p, &length); |
5058 | type = be32_to_cpup(p++); /* 4 byte read */ | 4913 | type = be32_to_cpup(p++); /* 4 byte read */ |
@@ -5069,11 +4924,9 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) | |||
5069 | p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */ | 4924 | p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */ |
5070 | namelen = be32_to_cpup(p); /* read 4 bytes */ /* have read all 32 bytes now */ | 4925 | namelen = be32_to_cpup(p); /* read 4 bytes */ /* have read all 32 bytes now */ |
5071 | p = xdr_inline_decode(xdr, namelen); /* variable size field */ | 4926 | p = xdr_inline_decode(xdr, namelen); /* variable size field */ |
5072 | if (likely(p)) | 4927 | if (likely(!p)) |
5073 | return -NFS4ERR_DENIED; | 4928 | return -EIO; |
5074 | out_overflow: | 4929 | return -NFS4ERR_DENIED; |
5075 | print_overflow_msg(__func__, xdr); | ||
5076 | return -EIO; | ||
5077 | } | 4930 | } |
5078 | 4931 | ||
5079 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) | 4932 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) |
@@ -5142,7 +4995,7 @@ static int decode_space_limit(struct xdr_stream *xdr, | |||
5142 | 4995 | ||
5143 | p = xdr_inline_decode(xdr, 12); | 4996 | p = xdr_inline_decode(xdr, 12); |
5144 | if (unlikely(!p)) | 4997 | if (unlikely(!p)) |
5145 | goto out_overflow; | 4998 | return -EIO; |
5146 | limit_type = be32_to_cpup(p++); | 4999 | limit_type = be32_to_cpup(p++); |
5147 | switch (limit_type) { | 5000 | switch (limit_type) { |
5148 | case NFS4_LIMIT_SIZE: | 5001 | case NFS4_LIMIT_SIZE: |
@@ -5156,9 +5009,6 @@ static int decode_space_limit(struct xdr_stream *xdr, | |||
5156 | maxsize >>= PAGE_SHIFT; | 5009 | maxsize >>= PAGE_SHIFT; |
5157 | *pagemod_limit = min_t(u64, maxsize, ULONG_MAX); | 5010 | *pagemod_limit = min_t(u64, maxsize, ULONG_MAX); |
5158 | return 0; | 5011 | return 0; |
5159 | out_overflow: | ||
5160 | print_overflow_msg(__func__, xdr); | ||
5161 | return -EIO; | ||
5162 | } | 5012 | } |
5163 | 5013 | ||
5164 | static int decode_rw_delegation(struct xdr_stream *xdr, | 5014 | static int decode_rw_delegation(struct xdr_stream *xdr, |
@@ -5173,7 +5023,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr, | |||
5173 | return status; | 5023 | return status; |
5174 | p = xdr_inline_decode(xdr, 4); | 5024 | p = xdr_inline_decode(xdr, 4); |
5175 | if (unlikely(!p)) | 5025 | if (unlikely(!p)) |
5176 | goto out_overflow; | 5026 | return -EIO; |
5177 | res->do_recall = be32_to_cpup(p); | 5027 | res->do_recall = be32_to_cpup(p); |
5178 | 5028 | ||
5179 | switch (delegation_type) { | 5029 | switch (delegation_type) { |
@@ -5186,9 +5036,6 @@ static int decode_rw_delegation(struct xdr_stream *xdr, | |||
5186 | return -EIO; | 5036 | return -EIO; |
5187 | } | 5037 | } |
5188 | return decode_ace(xdr, NULL); | 5038 | return decode_ace(xdr, NULL); |
5189 | out_overflow: | ||
5190 | print_overflow_msg(__func__, xdr); | ||
5191 | return -EIO; | ||
5192 | } | 5039 | } |
5193 | 5040 | ||
5194 | static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | 5041 | static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) |
@@ -5198,7 +5045,7 @@ static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5198 | 5045 | ||
5199 | p = xdr_inline_decode(xdr, 4); | 5046 | p = xdr_inline_decode(xdr, 4); |
5200 | if (unlikely(!p)) | 5047 | if (unlikely(!p)) |
5201 | goto out_overflow; | 5048 | return -EIO; |
5202 | why_no_delegation = be32_to_cpup(p); | 5049 | why_no_delegation = be32_to_cpup(p); |
5203 | switch (why_no_delegation) { | 5050 | switch (why_no_delegation) { |
5204 | case WND4_CONTENTION: | 5051 | case WND4_CONTENTION: |
@@ -5207,9 +5054,6 @@ static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5207 | /* Ignore for now */ | 5054 | /* Ignore for now */ |
5208 | } | 5055 | } |
5209 | return 0; | 5056 | return 0; |
5210 | out_overflow: | ||
5211 | print_overflow_msg(__func__, xdr); | ||
5212 | return -EIO; | ||
5213 | } | 5057 | } |
5214 | 5058 | ||
5215 | static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | 5059 | static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) |
@@ -5219,7 +5063,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5219 | 5063 | ||
5220 | p = xdr_inline_decode(xdr, 4); | 5064 | p = xdr_inline_decode(xdr, 4); |
5221 | if (unlikely(!p)) | 5065 | if (unlikely(!p)) |
5222 | goto out_overflow; | 5066 | return -EIO; |
5223 | delegation_type = be32_to_cpup(p); | 5067 | delegation_type = be32_to_cpup(p); |
5224 | res->delegation_type = 0; | 5068 | res->delegation_type = 0; |
5225 | switch (delegation_type) { | 5069 | switch (delegation_type) { |
@@ -5232,9 +5076,6 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5232 | return decode_no_delegation(xdr, res); | 5076 | return decode_no_delegation(xdr, res); |
5233 | } | 5077 | } |
5234 | return -EIO; | 5078 | return -EIO; |
5235 | out_overflow: | ||
5236 | print_overflow_msg(__func__, xdr); | ||
5237 | return -EIO; | ||
5238 | } | 5079 | } |
5239 | 5080 | ||
5240 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | 5081 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) |
@@ -5256,7 +5097,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5256 | 5097 | ||
5257 | p = xdr_inline_decode(xdr, 8); | 5098 | p = xdr_inline_decode(xdr, 8); |
5258 | if (unlikely(!p)) | 5099 | if (unlikely(!p)) |
5259 | goto out_overflow; | 5100 | return -EIO; |
5260 | res->rflags = be32_to_cpup(p++); | 5101 | res->rflags = be32_to_cpup(p++); |
5261 | bmlen = be32_to_cpup(p); | 5102 | bmlen = be32_to_cpup(p); |
5262 | if (bmlen > 10) | 5103 | if (bmlen > 10) |
@@ -5264,7 +5105,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5264 | 5105 | ||
5265 | p = xdr_inline_decode(xdr, bmlen << 2); | 5106 | p = xdr_inline_decode(xdr, bmlen << 2); |
5266 | if (unlikely(!p)) | 5107 | if (unlikely(!p)) |
5267 | goto out_overflow; | 5108 | return -EIO; |
5268 | savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); | 5109 | savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); |
5269 | for (i = 0; i < savewords; ++i) | 5110 | for (i = 0; i < savewords; ++i) |
5270 | res->attrset[i] = be32_to_cpup(p++); | 5111 | res->attrset[i] = be32_to_cpup(p++); |
@@ -5275,9 +5116,6 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5275 | xdr_error: | 5116 | xdr_error: |
5276 | dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); | 5117 | dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); |
5277 | return -EIO; | 5118 | return -EIO; |
5278 | out_overflow: | ||
5279 | print_overflow_msg(__func__, xdr); | ||
5280 | return -EIO; | ||
5281 | } | 5119 | } |
5282 | 5120 | ||
5283 | static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) | 5121 | static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) |
@@ -5326,7 +5164,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
5326 | return status; | 5164 | return status; |
5327 | p = xdr_inline_decode(xdr, 8); | 5165 | p = xdr_inline_decode(xdr, 8); |
5328 | if (unlikely(!p)) | 5166 | if (unlikely(!p)) |
5329 | goto out_overflow; | 5167 | return -EIO; |
5330 | eof = be32_to_cpup(p++); | 5168 | eof = be32_to_cpup(p++); |
5331 | count = be32_to_cpup(p); | 5169 | count = be32_to_cpup(p); |
5332 | recvd = xdr_read_pages(xdr, count); | 5170 | recvd = xdr_read_pages(xdr, count); |
@@ -5339,9 +5177,6 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
5339 | res->eof = eof; | 5177 | res->eof = eof; |
5340 | res->count = count; | 5178 | res->count = count; |
5341 | return 0; | 5179 | return 0; |
5342 | out_overflow: | ||
5343 | print_overflow_msg(__func__, xdr); | ||
5344 | return -EIO; | ||
5345 | } | 5180 | } |
5346 | 5181 | ||
5347 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) | 5182 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) |
@@ -5374,7 +5209,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
5374 | /* Convert length of symlink */ | 5209 | /* Convert length of symlink */ |
5375 | p = xdr_inline_decode(xdr, 4); | 5210 | p = xdr_inline_decode(xdr, 4); |
5376 | if (unlikely(!p)) | 5211 | if (unlikely(!p)) |
5377 | goto out_overflow; | 5212 | return -EIO; |
5378 | len = be32_to_cpup(p); | 5213 | len = be32_to_cpup(p); |
5379 | if (len >= rcvbuf->page_len || len <= 0) { | 5214 | if (len >= rcvbuf->page_len || len <= 0) { |
5380 | dprintk("nfs: server returned giant symlink!\n"); | 5215 | dprintk("nfs: server returned giant symlink!\n"); |
@@ -5395,9 +5230,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
5395 | */ | 5230 | */ |
5396 | xdr_terminate_string(rcvbuf, len); | 5231 | xdr_terminate_string(rcvbuf, len); |
5397 | return 0; | 5232 | return 0; |
5398 | out_overflow: | ||
5399 | print_overflow_msg(__func__, xdr); | ||
5400 | return -EIO; | ||
5401 | } | 5233 | } |
5402 | 5234 | ||
5403 | static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 5235 | static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -5500,7 +5332,6 @@ static int decode_setattr(struct xdr_stream *xdr) | |||
5500 | return status; | 5332 | return status; |
5501 | if (decode_bitmap4(xdr, NULL, 0) >= 0) | 5333 | if (decode_bitmap4(xdr, NULL, 0) >= 0) |
5502 | return 0; | 5334 | return 0; |
5503 | print_overflow_msg(__func__, xdr); | ||
5504 | return -EIO; | 5335 | return -EIO; |
5505 | } | 5336 | } |
5506 | 5337 | ||
@@ -5512,7 +5343,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_re | |||
5512 | 5343 | ||
5513 | p = xdr_inline_decode(xdr, 8); | 5344 | p = xdr_inline_decode(xdr, 8); |
5514 | if (unlikely(!p)) | 5345 | if (unlikely(!p)) |
5515 | goto out_overflow; | 5346 | return -EIO; |
5516 | opnum = be32_to_cpup(p++); | 5347 | opnum = be32_to_cpup(p++); |
5517 | if (opnum != OP_SETCLIENTID) { | 5348 | if (opnum != OP_SETCLIENTID) { |
5518 | dprintk("nfs: decode_setclientid: Server returned operation" | 5349 | dprintk("nfs: decode_setclientid: Server returned operation" |
@@ -5523,7 +5354,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_re | |||
5523 | if (nfserr == NFS_OK) { | 5354 | if (nfserr == NFS_OK) { |
5524 | p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); | 5355 | p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); |
5525 | if (unlikely(!p)) | 5356 | if (unlikely(!p)) |
5526 | goto out_overflow; | 5357 | return -EIO; |
5527 | p = xdr_decode_hyper(p, &res->clientid); | 5358 | p = xdr_decode_hyper(p, &res->clientid); |
5528 | memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE); | 5359 | memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE); |
5529 | } else if (nfserr == NFSERR_CLID_INUSE) { | 5360 | } else if (nfserr == NFSERR_CLID_INUSE) { |
@@ -5532,28 +5363,25 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_re | |||
5532 | /* skip netid string */ | 5363 | /* skip netid string */ |
5533 | p = xdr_inline_decode(xdr, 4); | 5364 | p = xdr_inline_decode(xdr, 4); |
5534 | if (unlikely(!p)) | 5365 | if (unlikely(!p)) |
5535 | goto out_overflow; | 5366 | return -EIO; |
5536 | len = be32_to_cpup(p); | 5367 | len = be32_to_cpup(p); |
5537 | p = xdr_inline_decode(xdr, len); | 5368 | p = xdr_inline_decode(xdr, len); |
5538 | if (unlikely(!p)) | 5369 | if (unlikely(!p)) |
5539 | goto out_overflow; | 5370 | return -EIO; |
5540 | 5371 | ||
5541 | /* skip uaddr string */ | 5372 | /* skip uaddr string */ |
5542 | p = xdr_inline_decode(xdr, 4); | 5373 | p = xdr_inline_decode(xdr, 4); |
5543 | if (unlikely(!p)) | 5374 | if (unlikely(!p)) |
5544 | goto out_overflow; | 5375 | return -EIO; |
5545 | len = be32_to_cpup(p); | 5376 | len = be32_to_cpup(p); |
5546 | p = xdr_inline_decode(xdr, len); | 5377 | p = xdr_inline_decode(xdr, len); |
5547 | if (unlikely(!p)) | 5378 | if (unlikely(!p)) |
5548 | goto out_overflow; | 5379 | return -EIO; |
5549 | return -NFSERR_CLID_INUSE; | 5380 | return -NFSERR_CLID_INUSE; |
5550 | } else | 5381 | } else |
5551 | return nfs4_stat_to_errno(nfserr); | 5382 | return nfs4_stat_to_errno(nfserr); |
5552 | 5383 | ||
5553 | return 0; | 5384 | return 0; |
5554 | out_overflow: | ||
5555 | print_overflow_msg(__func__, xdr); | ||
5556 | return -EIO; | ||
5557 | } | 5385 | } |
5558 | 5386 | ||
5559 | static int decode_setclientid_confirm(struct xdr_stream *xdr) | 5387 | static int decode_setclientid_confirm(struct xdr_stream *xdr) |
@@ -5572,13 +5400,10 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_pgio_res *res) | |||
5572 | 5400 | ||
5573 | p = xdr_inline_decode(xdr, 8); | 5401 | p = xdr_inline_decode(xdr, 8); |
5574 | if (unlikely(!p)) | 5402 | if (unlikely(!p)) |
5575 | goto out_overflow; | 5403 | return -EIO; |
5576 | res->count = be32_to_cpup(p++); | 5404 | res->count = be32_to_cpup(p++); |
5577 | res->verf->committed = be32_to_cpup(p++); | 5405 | res->verf->committed = be32_to_cpup(p++); |
5578 | return decode_write_verifier(xdr, &res->verf->verifier); | 5406 | return decode_write_verifier(xdr, &res->verf->verifier); |
5579 | out_overflow: | ||
5580 | print_overflow_msg(__func__, xdr); | ||
5581 | return -EIO; | ||
5582 | } | 5407 | } |
5583 | 5408 | ||
5584 | static int decode_delegreturn(struct xdr_stream *xdr) | 5409 | static int decode_delegreturn(struct xdr_stream *xdr) |
@@ -5594,30 +5419,24 @@ static int decode_secinfo_gss(struct xdr_stream *xdr, | |||
5594 | 5419 | ||
5595 | p = xdr_inline_decode(xdr, 4); | 5420 | p = xdr_inline_decode(xdr, 4); |
5596 | if (unlikely(!p)) | 5421 | if (unlikely(!p)) |
5597 | goto out_overflow; | 5422 | return -EIO; |
5598 | oid_len = be32_to_cpup(p); | 5423 | oid_len = be32_to_cpup(p); |
5599 | if (oid_len > GSS_OID_MAX_LEN) | 5424 | if (oid_len > GSS_OID_MAX_LEN) |
5600 | goto out_err; | 5425 | return -EINVAL; |
5601 | 5426 | ||
5602 | p = xdr_inline_decode(xdr, oid_len); | 5427 | p = xdr_inline_decode(xdr, oid_len); |
5603 | if (unlikely(!p)) | 5428 | if (unlikely(!p)) |
5604 | goto out_overflow; | 5429 | return -EIO; |
5605 | memcpy(flavor->flavor_info.oid.data, p, oid_len); | 5430 | memcpy(flavor->flavor_info.oid.data, p, oid_len); |
5606 | flavor->flavor_info.oid.len = oid_len; | 5431 | flavor->flavor_info.oid.len = oid_len; |
5607 | 5432 | ||
5608 | p = xdr_inline_decode(xdr, 8); | 5433 | p = xdr_inline_decode(xdr, 8); |
5609 | if (unlikely(!p)) | 5434 | if (unlikely(!p)) |
5610 | goto out_overflow; | 5435 | return -EIO; |
5611 | flavor->flavor_info.qop = be32_to_cpup(p++); | 5436 | flavor->flavor_info.qop = be32_to_cpup(p++); |
5612 | flavor->flavor_info.service = be32_to_cpup(p); | 5437 | flavor->flavor_info.service = be32_to_cpup(p); |
5613 | 5438 | ||
5614 | return 0; | 5439 | return 0; |
5615 | |||
5616 | out_overflow: | ||
5617 | print_overflow_msg(__func__, xdr); | ||
5618 | return -EIO; | ||
5619 | out_err: | ||
5620 | return -EINVAL; | ||
5621 | } | 5440 | } |
5622 | 5441 | ||
5623 | static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) | 5442 | static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) |
@@ -5629,7 +5448,7 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res | |||
5629 | 5448 | ||
5630 | p = xdr_inline_decode(xdr, 4); | 5449 | p = xdr_inline_decode(xdr, 4); |
5631 | if (unlikely(!p)) | 5450 | if (unlikely(!p)) |
5632 | goto out_overflow; | 5451 | return -EIO; |
5633 | 5452 | ||
5634 | res->flavors->num_flavors = 0; | 5453 | res->flavors->num_flavors = 0; |
5635 | num_flavors = be32_to_cpup(p); | 5454 | num_flavors = be32_to_cpup(p); |
@@ -5641,7 +5460,7 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res | |||
5641 | 5460 | ||
5642 | p = xdr_inline_decode(xdr, 4); | 5461 | p = xdr_inline_decode(xdr, 4); |
5643 | if (unlikely(!p)) | 5462 | if (unlikely(!p)) |
5644 | goto out_overflow; | 5463 | return -EIO; |
5645 | sec_flavor->flavor = be32_to_cpup(p); | 5464 | sec_flavor->flavor = be32_to_cpup(p); |
5646 | 5465 | ||
5647 | if (sec_flavor->flavor == RPC_AUTH_GSS) { | 5466 | if (sec_flavor->flavor == RPC_AUTH_GSS) { |
@@ -5655,9 +5474,6 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res | |||
5655 | status = 0; | 5474 | status = 0; |
5656 | out: | 5475 | out: |
5657 | return status; | 5476 | return status; |
5658 | out_overflow: | ||
5659 | print_overflow_msg(__func__, xdr); | ||
5660 | return -EIO; | ||
5661 | } | 5477 | } |
5662 | 5478 | ||
5663 | static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) | 5479 | static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) |
@@ -5711,11 +5527,11 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
5711 | 5527 | ||
5712 | p = xdr_inline_decode(xdr, 8); | 5528 | p = xdr_inline_decode(xdr, 8); |
5713 | if (unlikely(!p)) | 5529 | if (unlikely(!p)) |
5714 | goto out_overflow; | 5530 | return -EIO; |
5715 | xdr_decode_hyper(p, &res->clientid); | 5531 | xdr_decode_hyper(p, &res->clientid); |
5716 | p = xdr_inline_decode(xdr, 12); | 5532 | p = xdr_inline_decode(xdr, 12); |
5717 | if (unlikely(!p)) | 5533 | if (unlikely(!p)) |
5718 | goto out_overflow; | 5534 | return -EIO; |
5719 | res->seqid = be32_to_cpup(p++); | 5535 | res->seqid = be32_to_cpup(p++); |
5720 | res->flags = be32_to_cpup(p++); | 5536 | res->flags = be32_to_cpup(p++); |
5721 | 5537 | ||
@@ -5739,7 +5555,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
5739 | /* server_owner4.so_minor_id */ | 5555 | /* server_owner4.so_minor_id */ |
5740 | p = xdr_inline_decode(xdr, 8); | 5556 | p = xdr_inline_decode(xdr, 8); |
5741 | if (unlikely(!p)) | 5557 | if (unlikely(!p)) |
5742 | goto out_overflow; | 5558 | return -EIO; |
5743 | p = xdr_decode_hyper(p, &res->server_owner->minor_id); | 5559 | p = xdr_decode_hyper(p, &res->server_owner->minor_id); |
5744 | 5560 | ||
5745 | /* server_owner4.so_major_id */ | 5561 | /* server_owner4.so_major_id */ |
@@ -5759,7 +5575,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
5759 | /* Implementation Id */ | 5575 | /* Implementation Id */ |
5760 | p = xdr_inline_decode(xdr, 4); | 5576 | p = xdr_inline_decode(xdr, 4); |
5761 | if (unlikely(!p)) | 5577 | if (unlikely(!p)) |
5762 | goto out_overflow; | 5578 | return -EIO; |
5763 | impl_id_count = be32_to_cpup(p++); | 5579 | impl_id_count = be32_to_cpup(p++); |
5764 | 5580 | ||
5765 | if (impl_id_count) { | 5581 | if (impl_id_count) { |
@@ -5778,16 +5594,13 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
5778 | /* nii_date */ | 5594 | /* nii_date */ |
5779 | p = xdr_inline_decode(xdr, 12); | 5595 | p = xdr_inline_decode(xdr, 12); |
5780 | if (unlikely(!p)) | 5596 | if (unlikely(!p)) |
5781 | goto out_overflow; | 5597 | return -EIO; |
5782 | p = xdr_decode_hyper(p, &res->impl_id->date.seconds); | 5598 | p = xdr_decode_hyper(p, &res->impl_id->date.seconds); |
5783 | res->impl_id->date.nseconds = be32_to_cpup(p); | 5599 | res->impl_id->date.nseconds = be32_to_cpup(p); |
5784 | 5600 | ||
5785 | /* if there's more than one entry, ignore the rest */ | 5601 | /* if there's more than one entry, ignore the rest */ |
5786 | } | 5602 | } |
5787 | return 0; | 5603 | return 0; |
5788 | out_overflow: | ||
5789 | print_overflow_msg(__func__, xdr); | ||
5790 | return -EIO; | ||
5791 | } | 5604 | } |
5792 | 5605 | ||
5793 | static int decode_chan_attrs(struct xdr_stream *xdr, | 5606 | static int decode_chan_attrs(struct xdr_stream *xdr, |
@@ -5798,7 +5611,7 @@ static int decode_chan_attrs(struct xdr_stream *xdr, | |||
5798 | 5611 | ||
5799 | p = xdr_inline_decode(xdr, 28); | 5612 | p = xdr_inline_decode(xdr, 28); |
5800 | if (unlikely(!p)) | 5613 | if (unlikely(!p)) |
5801 | goto out_overflow; | 5614 | return -EIO; |
5802 | val = be32_to_cpup(p++); /* headerpadsz */ | 5615 | val = be32_to_cpup(p++); /* headerpadsz */ |
5803 | if (val) | 5616 | if (val) |
5804 | return -EINVAL; /* no support for header padding yet */ | 5617 | return -EINVAL; /* no support for header padding yet */ |
@@ -5816,12 +5629,9 @@ static int decode_chan_attrs(struct xdr_stream *xdr, | |||
5816 | if (nr_attrs == 1) { | 5629 | if (nr_attrs == 1) { |
5817 | p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */ | 5630 | p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */ |
5818 | if (unlikely(!p)) | 5631 | if (unlikely(!p)) |
5819 | goto out_overflow; | 5632 | return -EIO; |
5820 | } | 5633 | } |
5821 | return 0; | 5634 | return 0; |
5822 | out_overflow: | ||
5823 | print_overflow_msg(__func__, xdr); | ||
5824 | return -EIO; | ||
5825 | } | 5635 | } |
5826 | 5636 | ||
5827 | static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) | 5637 | static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) |
@@ -5844,7 +5654,7 @@ static int decode_bind_conn_to_session(struct xdr_stream *xdr, | |||
5844 | /* dir flags, rdma mode bool */ | 5654 | /* dir flags, rdma mode bool */ |
5845 | p = xdr_inline_decode(xdr, 8); | 5655 | p = xdr_inline_decode(xdr, 8); |
5846 | if (unlikely(!p)) | 5656 | if (unlikely(!p)) |
5847 | goto out_overflow; | 5657 | return -EIO; |
5848 | 5658 | ||
5849 | res->dir = be32_to_cpup(p++); | 5659 | res->dir = be32_to_cpup(p++); |
5850 | if (res->dir == 0 || res->dir > NFS4_CDFS4_BOTH) | 5660 | if (res->dir == 0 || res->dir > NFS4_CDFS4_BOTH) |
@@ -5855,9 +5665,6 @@ static int decode_bind_conn_to_session(struct xdr_stream *xdr, | |||
5855 | res->use_conn_in_rdma_mode = true; | 5665 | res->use_conn_in_rdma_mode = true; |
5856 | 5666 | ||
5857 | return 0; | 5667 | return 0; |
5858 | out_overflow: | ||
5859 | print_overflow_msg(__func__, xdr); | ||
5860 | return -EIO; | ||
5861 | } | 5668 | } |
5862 | 5669 | ||
5863 | static int decode_create_session(struct xdr_stream *xdr, | 5670 | static int decode_create_session(struct xdr_stream *xdr, |
@@ -5875,7 +5682,7 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
5875 | /* seqid, flags */ | 5682 | /* seqid, flags */ |
5876 | p = xdr_inline_decode(xdr, 8); | 5683 | p = xdr_inline_decode(xdr, 8); |
5877 | if (unlikely(!p)) | 5684 | if (unlikely(!p)) |
5878 | goto out_overflow; | 5685 | return -EIO; |
5879 | res->seqid = be32_to_cpup(p++); | 5686 | res->seqid = be32_to_cpup(p++); |
5880 | res->flags = be32_to_cpup(p); | 5687 | res->flags = be32_to_cpup(p); |
5881 | 5688 | ||
@@ -5884,9 +5691,6 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
5884 | if (!status) | 5691 | if (!status) |
5885 | status = decode_chan_attrs(xdr, &res->bc_attrs); | 5692 | status = decode_chan_attrs(xdr, &res->bc_attrs); |
5886 | return status; | 5693 | return status; |
5887 | out_overflow: | ||
5888 | print_overflow_msg(__func__, xdr); | ||
5889 | return -EIO; | ||
5890 | } | 5694 | } |
5891 | 5695 | ||
5892 | static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) | 5696 | static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) |
@@ -5967,7 +5771,6 @@ out_err: | |||
5967 | res->sr_status = status; | 5771 | res->sr_status = status; |
5968 | return status; | 5772 | return status; |
5969 | out_overflow: | 5773 | out_overflow: |
5970 | print_overflow_msg(__func__, xdr); | ||
5971 | status = -EIO; | 5774 | status = -EIO; |
5972 | goto out_err; | 5775 | goto out_err; |
5973 | #else /* CONFIG_NFS_V4_1 */ | 5776 | #else /* CONFIG_NFS_V4_1 */ |
@@ -5995,7 +5798,7 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, | |||
5995 | if (status == -ETOOSMALL) { | 5798 | if (status == -ETOOSMALL) { |
5996 | p = xdr_inline_decode(xdr, 4); | 5799 | p = xdr_inline_decode(xdr, 4); |
5997 | if (unlikely(!p)) | 5800 | if (unlikely(!p)) |
5998 | goto out_overflow; | 5801 | return -EIO; |
5999 | pdev->mincount = be32_to_cpup(p); | 5802 | pdev->mincount = be32_to_cpup(p); |
6000 | dprintk("%s: Min count too small. mincnt = %u\n", | 5803 | dprintk("%s: Min count too small. mincnt = %u\n", |
6001 | __func__, pdev->mincount); | 5804 | __func__, pdev->mincount); |
@@ -6005,7 +5808,7 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, | |||
6005 | 5808 | ||
6006 | p = xdr_inline_decode(xdr, 8); | 5809 | p = xdr_inline_decode(xdr, 8); |
6007 | if (unlikely(!p)) | 5810 | if (unlikely(!p)) |
6008 | goto out_overflow; | 5811 | return -EIO; |
6009 | type = be32_to_cpup(p++); | 5812 | type = be32_to_cpup(p++); |
6010 | if (type != pdev->layout_type) { | 5813 | if (type != pdev->layout_type) { |
6011 | dprintk("%s: layout mismatch req: %u pdev: %u\n", | 5814 | dprintk("%s: layout mismatch req: %u pdev: %u\n", |
@@ -6019,19 +5822,19 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, | |||
6019 | */ | 5822 | */ |
6020 | pdev->mincount = be32_to_cpup(p); | 5823 | pdev->mincount = be32_to_cpup(p); |
6021 | if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount) | 5824 | if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount) |
6022 | goto out_overflow; | 5825 | return -EIO; |
6023 | 5826 | ||
6024 | /* Parse notification bitmap, verifying that it is zero. */ | 5827 | /* Parse notification bitmap, verifying that it is zero. */ |
6025 | p = xdr_inline_decode(xdr, 4); | 5828 | p = xdr_inline_decode(xdr, 4); |
6026 | if (unlikely(!p)) | 5829 | if (unlikely(!p)) |
6027 | goto out_overflow; | 5830 | return -EIO; |
6028 | len = be32_to_cpup(p); | 5831 | len = be32_to_cpup(p); |
6029 | if (len) { | 5832 | if (len) { |
6030 | uint32_t i; | 5833 | uint32_t i; |
6031 | 5834 | ||
6032 | p = xdr_inline_decode(xdr, 4 * len); | 5835 | p = xdr_inline_decode(xdr, 4 * len); |
6033 | if (unlikely(!p)) | 5836 | if (unlikely(!p)) |
6034 | goto out_overflow; | 5837 | return -EIO; |
6035 | 5838 | ||
6036 | res->notification = be32_to_cpup(p++); | 5839 | res->notification = be32_to_cpup(p++); |
6037 | for (i = 1; i < len; i++) { | 5840 | for (i = 1; i < len; i++) { |
@@ -6043,9 +5846,6 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, | |||
6043 | } | 5846 | } |
6044 | } | 5847 | } |
6045 | return 0; | 5848 | return 0; |
6046 | out_overflow: | ||
6047 | print_overflow_msg(__func__, xdr); | ||
6048 | return -EIO; | ||
6049 | } | 5849 | } |
6050 | 5850 | ||
6051 | static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, | 5851 | static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, |
@@ -6115,7 +5915,6 @@ out: | |||
6115 | res->status = status; | 5915 | res->status = status; |
6116 | return status; | 5916 | return status; |
6117 | out_overflow: | 5917 | out_overflow: |
6118 | print_overflow_msg(__func__, xdr); | ||
6119 | status = -EIO; | 5918 | status = -EIO; |
6120 | goto out; | 5919 | goto out; |
6121 | } | 5920 | } |
@@ -6131,16 +5930,13 @@ static int decode_layoutreturn(struct xdr_stream *xdr, | |||
6131 | return status; | 5930 | return status; |
6132 | p = xdr_inline_decode(xdr, 4); | 5931 | p = xdr_inline_decode(xdr, 4); |
6133 | if (unlikely(!p)) | 5932 | if (unlikely(!p)) |
6134 | goto out_overflow; | 5933 | return -EIO; |
6135 | res->lrs_present = be32_to_cpup(p); | 5934 | res->lrs_present = be32_to_cpup(p); |
6136 | if (res->lrs_present) | 5935 | if (res->lrs_present) |
6137 | status = decode_layout_stateid(xdr, &res->stateid); | 5936 | status = decode_layout_stateid(xdr, &res->stateid); |
6138 | else | 5937 | else |
6139 | nfs4_stateid_copy(&res->stateid, &invalid_stateid); | 5938 | nfs4_stateid_copy(&res->stateid, &invalid_stateid); |
6140 | return status; | 5939 | return status; |
6141 | out_overflow: | ||
6142 | print_overflow_msg(__func__, xdr); | ||
6143 | return -EIO; | ||
6144 | } | 5940 | } |
6145 | 5941 | ||
6146 | static int decode_layoutcommit(struct xdr_stream *xdr, | 5942 | static int decode_layoutcommit(struct xdr_stream *xdr, |
@@ -6158,19 +5954,16 @@ static int decode_layoutcommit(struct xdr_stream *xdr, | |||
6158 | 5954 | ||
6159 | p = xdr_inline_decode(xdr, 4); | 5955 | p = xdr_inline_decode(xdr, 4); |
6160 | if (unlikely(!p)) | 5956 | if (unlikely(!p)) |
6161 | goto out_overflow; | 5957 | return -EIO; |
6162 | sizechanged = be32_to_cpup(p); | 5958 | sizechanged = be32_to_cpup(p); |
6163 | 5959 | ||
6164 | if (sizechanged) { | 5960 | if (sizechanged) { |
6165 | /* throw away new size */ | 5961 | /* throw away new size */ |
6166 | p = xdr_inline_decode(xdr, 8); | 5962 | p = xdr_inline_decode(xdr, 8); |
6167 | if (unlikely(!p)) | 5963 | if (unlikely(!p)) |
6168 | goto out_overflow; | 5964 | return -EIO; |
6169 | } | 5965 | } |
6170 | return 0; | 5966 | return 0; |
6171 | out_overflow: | ||
6172 | print_overflow_msg(__func__, xdr); | ||
6173 | return -EIO; | ||
6174 | } | 5967 | } |
6175 | 5968 | ||
6176 | static int decode_test_stateid(struct xdr_stream *xdr, | 5969 | static int decode_test_stateid(struct xdr_stream *xdr, |
@@ -6186,21 +5979,17 @@ static int decode_test_stateid(struct xdr_stream *xdr, | |||
6186 | 5979 | ||
6187 | p = xdr_inline_decode(xdr, 4); | 5980 | p = xdr_inline_decode(xdr, 4); |
6188 | if (unlikely(!p)) | 5981 | if (unlikely(!p)) |
6189 | goto out_overflow; | 5982 | return -EIO; |
6190 | num_res = be32_to_cpup(p++); | 5983 | num_res = be32_to_cpup(p++); |
6191 | if (num_res != 1) | 5984 | if (num_res != 1) |
6192 | goto out; | 5985 | return -EIO; |
6193 | 5986 | ||
6194 | p = xdr_inline_decode(xdr, 4); | 5987 | p = xdr_inline_decode(xdr, 4); |
6195 | if (unlikely(!p)) | 5988 | if (unlikely(!p)) |
6196 | goto out_overflow; | 5989 | return -EIO; |
6197 | res->status = be32_to_cpup(p++); | 5990 | res->status = be32_to_cpup(p++); |
6198 | 5991 | ||
6199 | return status; | 5992 | return status; |
6200 | out_overflow: | ||
6201 | print_overflow_msg(__func__, xdr); | ||
6202 | out: | ||
6203 | return -EIO; | ||
6204 | } | 5993 | } |
6205 | 5994 | ||
6206 | static int decode_free_stateid(struct xdr_stream *xdr, | 5995 | static int decode_free_stateid(struct xdr_stream *xdr, |
@@ -7570,11 +7359,11 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
7570 | uint64_t new_cookie; | 7359 | uint64_t new_cookie; |
7571 | __be32 *p = xdr_inline_decode(xdr, 4); | 7360 | __be32 *p = xdr_inline_decode(xdr, 4); |
7572 | if (unlikely(!p)) | 7361 | if (unlikely(!p)) |
7573 | goto out_overflow; | 7362 | return -EAGAIN; |
7574 | if (*p == xdr_zero) { | 7363 | if (*p == xdr_zero) { |
7575 | p = xdr_inline_decode(xdr, 4); | 7364 | p = xdr_inline_decode(xdr, 4); |
7576 | if (unlikely(!p)) | 7365 | if (unlikely(!p)) |
7577 | goto out_overflow; | 7366 | return -EAGAIN; |
7578 | if (*p == xdr_zero) | 7367 | if (*p == xdr_zero) |
7579 | return -EAGAIN; | 7368 | return -EAGAIN; |
7580 | entry->eof = 1; | 7369 | entry->eof = 1; |
@@ -7583,13 +7372,13 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
7583 | 7372 | ||
7584 | p = xdr_inline_decode(xdr, 12); | 7373 | p = xdr_inline_decode(xdr, 12); |
7585 | if (unlikely(!p)) | 7374 | if (unlikely(!p)) |
7586 | goto out_overflow; | 7375 | return -EAGAIN; |
7587 | p = xdr_decode_hyper(p, &new_cookie); | 7376 | p = xdr_decode_hyper(p, &new_cookie); |
7588 | entry->len = be32_to_cpup(p); | 7377 | entry->len = be32_to_cpup(p); |
7589 | 7378 | ||
7590 | p = xdr_inline_decode(xdr, entry->len); | 7379 | p = xdr_inline_decode(xdr, entry->len); |
7591 | if (unlikely(!p)) | 7380 | if (unlikely(!p)) |
7592 | goto out_overflow; | 7381 | return -EAGAIN; |
7593 | entry->name = (const char *) p; | 7382 | entry->name = (const char *) p; |
7594 | 7383 | ||
7595 | /* | 7384 | /* |
@@ -7601,14 +7390,14 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
7601 | entry->fattr->valid = 0; | 7390 | entry->fattr->valid = 0; |
7602 | 7391 | ||
7603 | if (decode_attr_bitmap(xdr, bitmap) < 0) | 7392 | if (decode_attr_bitmap(xdr, bitmap) < 0) |
7604 | goto out_overflow; | 7393 | return -EAGAIN; |
7605 | 7394 | ||
7606 | if (decode_attr_length(xdr, &len, &savep) < 0) | 7395 | if (decode_attr_length(xdr, &len, &savep) < 0) |
7607 | goto out_overflow; | 7396 | return -EAGAIN; |
7608 | 7397 | ||
7609 | if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, | 7398 | if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, |
7610 | NULL, entry->label, entry->server) < 0) | 7399 | NULL, entry->label, entry->server) < 0) |
7611 | goto out_overflow; | 7400 | return -EAGAIN; |
7612 | if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | 7401 | if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) |
7613 | entry->ino = entry->fattr->mounted_on_fileid; | 7402 | entry->ino = entry->fattr->mounted_on_fileid; |
7614 | else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) | 7403 | else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) |
@@ -7622,10 +7411,6 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
7622 | entry->cookie = new_cookie; | 7411 | entry->cookie = new_cookie; |
7623 | 7412 | ||
7624 | return 0; | 7413 | return 0; |
7625 | |||
7626 | out_overflow: | ||
7627 | print_overflow_msg(__func__, xdr); | ||
7628 | return -EAGAIN; | ||
7629 | } | 7414 | } |
7630 | 7415 | ||
7631 | /* | 7416 | /* |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index c74e4538d0eb..a9d24d5a967c 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -60,16 +60,6 @@ struct nfs4_cb_compound_hdr { | |||
60 | int status; | 60 | int status; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* | ||
64 | * Handle decode buffer overflows out-of-line. | ||
65 | */ | ||
66 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | ||
67 | { | ||
68 | dprintk("NFS: %s prematurely hit the end of our receive buffer. " | ||
69 | "Remaining buffer length is %tu words.\n", | ||
70 | func, xdr->end - xdr->p); | ||
71 | } | ||
72 | |||
73 | static __be32 *xdr_encode_empty_array(__be32 *p) | 63 | static __be32 *xdr_encode_empty_array(__be32 *p) |
74 | { | 64 | { |
75 | *p++ = xdr_zero; | 65 | *p++ = xdr_zero; |
@@ -240,7 +230,6 @@ static int decode_cb_op_status(struct xdr_stream *xdr, | |||
240 | *status = nfs_cb_stat_to_errno(be32_to_cpup(p)); | 230 | *status = nfs_cb_stat_to_errno(be32_to_cpup(p)); |
241 | return 0; | 231 | return 0; |
242 | out_overflow: | 232 | out_overflow: |
243 | print_overflow_msg(__func__, xdr); | ||
244 | return -EIO; | 233 | return -EIO; |
245 | out_unexpected: | 234 | out_unexpected: |
246 | dprintk("NFSD: Callback server returned operation %d but " | 235 | dprintk("NFSD: Callback server returned operation %d but " |
@@ -309,7 +298,6 @@ static int decode_cb_compound4res(struct xdr_stream *xdr, | |||
309 | hdr->nops = be32_to_cpup(p); | 298 | hdr->nops = be32_to_cpup(p); |
310 | return 0; | 299 | return 0; |
311 | out_overflow: | 300 | out_overflow: |
312 | print_overflow_msg(__func__, xdr); | ||
313 | return -EIO; | 301 | return -EIO; |
314 | } | 302 | } |
315 | 303 | ||
@@ -437,7 +425,6 @@ out: | |||
437 | cb->cb_seq_status = status; | 425 | cb->cb_seq_status = status; |
438 | return status; | 426 | return status; |
439 | out_overflow: | 427 | out_overflow: |
440 | print_overflow_msg(__func__, xdr); | ||
441 | status = -EIO; | 428 | status = -EIO; |
442 | goto out; | 429 | goto out; |
443 | } | 430 | } |