diff options
-rw-r--r-- | fs/nfs/nfs4xdr.c | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 650fa322b903..0b744895b9e1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -3496,8 +3496,11 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
3496 | if (n == 0) | 3496 | if (n == 0) |
3497 | goto root_path; | 3497 | goto root_path; |
3498 | dprintk("pathname4: "); | 3498 | dprintk("pathname4: "); |
3499 | path->ncomponents = 0; | 3499 | if (n > NFS4_PATHNAME_MAXCOMPONENTS) { |
3500 | while (path->ncomponents < n) { | 3500 | dprintk("cannot parse %d components in path\n", n); |
3501 | goto out_eio; | ||
3502 | } | ||
3503 | for (path->ncomponents = 0; path->ncomponents < n; path->ncomponents++) { | ||
3501 | struct nfs4_string *component = &path->components[path->ncomponents]; | 3504 | struct nfs4_string *component = &path->components[path->ncomponents]; |
3502 | status = decode_opaque_inline(xdr, &component->len, &component->data); | 3505 | status = decode_opaque_inline(xdr, &component->len, &component->data); |
3503 | if (unlikely(status != 0)) | 3506 | if (unlikely(status != 0)) |
@@ -3506,12 +3509,6 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
3506 | pr_cont("%s%.*s ", | 3509 | pr_cont("%s%.*s ", |
3507 | (path->ncomponents != n ? "/ " : ""), | 3510 | (path->ncomponents != n ? "/ " : ""), |
3508 | component->len, component->data); | 3511 | component->len, component->data); |
3509 | if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS) | ||
3510 | path->ncomponents++; | ||
3511 | else { | ||
3512 | dprintk("cannot parse %d components in path\n", n); | ||
3513 | goto out_eio; | ||
3514 | } | ||
3515 | } | 3512 | } |
3516 | out: | 3513 | out: |
3517 | return status; | 3514 | return status; |
@@ -3556,27 +3553,23 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3556 | n = be32_to_cpup(p); | 3553 | n = be32_to_cpup(p); |
3557 | if (n <= 0) | 3554 | if (n <= 0) |
3558 | goto out_eio; | 3555 | goto out_eio; |
3559 | res->nlocations = 0; | 3556 | for (res->nlocations = 0; res->nlocations < n; res->nlocations++) { |
3560 | while (res->nlocations < n) { | ||
3561 | u32 m; | 3557 | u32 m; |
3562 | struct nfs4_fs_location *loc = &res->locations[res->nlocations]; | 3558 | struct nfs4_fs_location *loc; |
3563 | 3559 | ||
3560 | if (res->nlocations == NFS4_FS_LOCATIONS_MAXENTRIES) | ||
3561 | break; | ||
3562 | loc = &res->locations[res->nlocations]; | ||
3564 | p = xdr_inline_decode(xdr, 4); | 3563 | p = xdr_inline_decode(xdr, 4); |
3565 | if (unlikely(!p)) | 3564 | if (unlikely(!p)) |
3566 | goto out_overflow; | 3565 | goto out_overflow; |
3567 | m = be32_to_cpup(p); | 3566 | m = be32_to_cpup(p); |
3568 | 3567 | ||
3569 | loc->nservers = 0; | ||
3570 | dprintk("%s: servers:\n", __func__); | 3568 | dprintk("%s: servers:\n", __func__); |
3571 | while (loc->nservers < m) { | 3569 | for (loc->nservers = 0; loc->nservers < m; loc->nservers++) { |
3572 | struct nfs4_string *server = &loc->servers[loc->nservers]; | 3570 | struct nfs4_string *server; |
3573 | status = decode_opaque_inline(xdr, &server->len, &server->data); | 3571 | |
3574 | if (unlikely(status != 0)) | 3572 | if (loc->nservers == NFS4_FS_LOCATION_MAXSERVERS) { |
3575 | goto out_eio; | ||
3576 | dprintk("%s ", server->data); | ||
3577 | if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS) | ||
3578 | loc->nservers++; | ||
3579 | else { | ||
3580 | unsigned int i; | 3573 | unsigned int i; |
3581 | dprintk("%s: using first %u of %u servers " | 3574 | dprintk("%s: using first %u of %u servers " |
3582 | "returned for location %u\n", | 3575 | "returned for location %u\n", |
@@ -3590,13 +3583,17 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
3590 | if (unlikely(status != 0)) | 3583 | if (unlikely(status != 0)) |
3591 | goto out_eio; | 3584 | goto out_eio; |
3592 | } | 3585 | } |
3586 | break; | ||
3593 | } | 3587 | } |
3588 | server = &loc->servers[loc->nservers]; | ||
3589 | status = decode_opaque_inline(xdr, &server->len, &server->data); | ||
3590 | if (unlikely(status != 0)) | ||
3591 | goto out_eio; | ||
3592 | dprintk("%s ", server->data); | ||
3594 | } | 3593 | } |
3595 | status = decode_pathname(xdr, &loc->rootpath); | 3594 | status = decode_pathname(xdr, &loc->rootpath); |
3596 | if (unlikely(status != 0)) | 3595 | if (unlikely(status != 0)) |
3597 | goto out_eio; | 3596 | goto out_eio; |
3598 | if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES) | ||
3599 | res->nlocations++; | ||
3600 | } | 3597 | } |
3601 | if (res->nlocations != 0) | 3598 | if (res->nlocations != 0) |
3602 | status = NFS_ATTR_FATTR_V4_LOCATIONS; | 3599 | status = NFS_ATTR_FATTR_V4_LOCATIONS; |