aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs2xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs2xdr.c')
-rw-r--r--fs/nfs/nfs2xdr.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 79c74387a2fe..0210c752e743 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -500,25 +500,56 @@ err_unmap:
500 goto out; 500 goto out;
501} 501}
502 502
503static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
504{
505 dprintk("nfs: %s: prematurely hit end of receive buffer. "
506 "Remaining buffer length is %tu words.\n",
507 func, xdr->end - xdr->p);
508}
509
503__be32 * 510__be32 *
504nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) 511nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, int plus)
505{ 512{
506 if (!*p++) { 513 __be32 *p;
507 if (!*p) 514 p = xdr_inline_decode(xdr, 4);
515 if (unlikely(!p))
516 goto out_overflow;
517 if (!ntohl(*p++)) {
518 p = xdr_inline_decode(xdr, 4);
519 if (unlikely(!p))
520 goto out_overflow;
521 if (!ntohl(*p++))
508 return ERR_PTR(-EAGAIN); 522 return ERR_PTR(-EAGAIN);
509 entry->eof = 1; 523 entry->eof = 1;
510 return ERR_PTR(-EBADCOOKIE); 524 return ERR_PTR(-EBADCOOKIE);
511 } 525 }
512 526
527 p = xdr_inline_decode(xdr, 8);
528 if (unlikely(!p))
529 goto out_overflow;
530
513 entry->ino = ntohl(*p++); 531 entry->ino = ntohl(*p++);
514 entry->len = ntohl(*p++); 532 entry->len = ntohl(*p++);
533
534 p = xdr_inline_decode(xdr, entry->len + 4);
535 if (unlikely(!p))
536 goto out_overflow;
515 entry->name = (const char *) p; 537 entry->name = (const char *) p;
516 p += XDR_QUADLEN(entry->len); 538 p += XDR_QUADLEN(entry->len);
517 entry->prev_cookie = entry->cookie; 539 entry->prev_cookie = entry->cookie;
518 entry->cookie = ntohl(*p++); 540 entry->cookie = ntohl(*p++);
519 entry->eof = !p[0] && p[1]; 541
542 p = xdr_inline_peek(xdr, 8);
543 if (p != NULL)
544 entry->eof = !p[0] && p[1];
545 else
546 entry->eof = 0;
520 547
521 return p; 548 return p;
549
550out_overflow:
551 print_overflow_msg(__func__, xdr);
552 return ERR_PTR(-EIO);
522} 553}
523 554
524/* 555/*