diff options
| -rw-r--r-- | fs/nfsd/Kconfig | 2 | ||||
| -rw-r--r-- | fs/nfsd/export.c | 24 | ||||
| -rw-r--r-- | fs/nfsd/nfs4state.c | 26 | ||||
| -rw-r--r-- | fs/nfsd/nfs4xdr.c | 132 | ||||
| -rw-r--r-- | fs/nfsd/nfsfh.c | 8 | ||||
| -rw-r--r-- | include/linux/nfs4.h | 3 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_unseal.c | 8 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_wrap.c | 10 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_upcall.c | 3 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_xdr.c | 29 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 4 | ||||
| -rw-r--r-- | net/sunrpc/svc.c | 2 |
12 files changed, 146 insertions, 105 deletions
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index dc8f1ef665ce..f994e750e0d1 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig | |||
| @@ -95,7 +95,7 @@ config NFSD_V4_SECURITY_LABEL | |||
| 95 | Smack policies on NFSv4 files, say N. | 95 | Smack policies on NFSv4 files, say N. |
| 96 | 96 | ||
| 97 | WARNING: there is still a chance of backwards-incompatible protocol changes. | 97 | WARNING: there is still a chance of backwards-incompatible protocol changes. |
| 98 | For now we recommend "Y" only for developers and testers." | 98 | For now we recommend "Y" only for developers and testers. |
| 99 | 99 | ||
| 100 | config NFSD_FAULT_INJECTION | 100 | config NFSD_FAULT_INJECTION |
| 101 | bool "NFS server manual fault injection" | 101 | bool "NFS server manual fault injection" |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 5f38ea36e266..8513c598fabf 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
| @@ -536,16 +536,12 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
| 536 | if (err) | 536 | if (err) |
| 537 | goto out3; | 537 | goto out3; |
| 538 | exp.ex_anon_uid= make_kuid(&init_user_ns, an_int); | 538 | exp.ex_anon_uid= make_kuid(&init_user_ns, an_int); |
| 539 | if (!uid_valid(exp.ex_anon_uid)) | ||
| 540 | goto out3; | ||
| 541 | 539 | ||
| 542 | /* anon gid */ | 540 | /* anon gid */ |
| 543 | err = get_int(&mesg, &an_int); | 541 | err = get_int(&mesg, &an_int); |
| 544 | if (err) | 542 | if (err) |
| 545 | goto out3; | 543 | goto out3; |
| 546 | exp.ex_anon_gid= make_kgid(&init_user_ns, an_int); | 544 | exp.ex_anon_gid= make_kgid(&init_user_ns, an_int); |
| 547 | if (!gid_valid(exp.ex_anon_gid)) | ||
| 548 | goto out3; | ||
| 549 | 545 | ||
| 550 | /* fsid */ | 546 | /* fsid */ |
| 551 | err = get_int(&mesg, &an_int); | 547 | err = get_int(&mesg, &an_int); |
| @@ -583,6 +579,26 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
| 583 | exp.ex_uuid); | 579 | exp.ex_uuid); |
| 584 | if (err) | 580 | if (err) |
| 585 | goto out4; | 581 | goto out4; |
| 582 | /* | ||
| 583 | * No point caching this if it would immediately expire. | ||
| 584 | * Also, this protects exportfs's dummy export from the | ||
| 585 | * anon_uid/anon_gid checks: | ||
| 586 | */ | ||
| 587 | if (exp.h.expiry_time < seconds_since_boot()) | ||
| 588 | goto out4; | ||
| 589 | /* | ||
| 590 | * For some reason exportfs has been passing down an | ||
| 591 | * invalid (-1) uid & gid on the "dummy" export which it | ||
| 592 | * uses to test export support. To make sure exportfs | ||
| 593 | * sees errors from check_export we therefore need to | ||
| 594 | * delay these checks till after check_export: | ||
| 595 | */ | ||
| 596 | err = -EINVAL; | ||
| 597 | if (!uid_valid(exp.ex_anon_uid)) | ||
| 598 | goto out4; | ||
| 599 | if (!gid_valid(exp.ex_anon_gid)) | ||
| 600 | goto out4; | ||
| 601 | err = 0; | ||
| 586 | } | 602 | } |
| 587 | 603 | ||
| 588 | expp = svc_export_lookup(&exp); | 604 | expp = svc_export_lookup(&exp); |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f36a30a9f2d1..105d6fa7c514 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -402,11 +402,16 @@ static void remove_stid(struct nfs4_stid *s) | |||
| 402 | idr_remove(stateids, s->sc_stateid.si_opaque.so_id); | 402 | idr_remove(stateids, s->sc_stateid.si_opaque.so_id); |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | static void nfs4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s) | ||
| 406 | { | ||
| 407 | kmem_cache_free(slab, s); | ||
| 408 | } | ||
| 409 | |||
| 405 | void | 410 | void |
| 406 | nfs4_put_delegation(struct nfs4_delegation *dp) | 411 | nfs4_put_delegation(struct nfs4_delegation *dp) |
| 407 | { | 412 | { |
| 408 | if (atomic_dec_and_test(&dp->dl_count)) { | 413 | if (atomic_dec_and_test(&dp->dl_count)) { |
| 409 | kmem_cache_free(deleg_slab, dp); | 414 | nfs4_free_stid(deleg_slab, &dp->dl_stid); |
| 410 | num_delegations--; | 415 | num_delegations--; |
| 411 | } | 416 | } |
| 412 | } | 417 | } |
| @@ -610,7 +615,7 @@ static void close_generic_stateid(struct nfs4_ol_stateid *stp) | |||
| 610 | static void free_generic_stateid(struct nfs4_ol_stateid *stp) | 615 | static void free_generic_stateid(struct nfs4_ol_stateid *stp) |
| 611 | { | 616 | { |
| 612 | remove_stid(&stp->st_stid); | 617 | remove_stid(&stp->st_stid); |
| 613 | kmem_cache_free(stateid_slab, stp); | 618 | nfs4_free_stid(stateid_slab, &stp->st_stid); |
| 614 | } | 619 | } |
| 615 | 620 | ||
| 616 | static void release_lock_stateid(struct nfs4_ol_stateid *stp) | 621 | static void release_lock_stateid(struct nfs4_ol_stateid *stp) |
| @@ -668,7 +673,6 @@ static void unhash_open_stateid(struct nfs4_ol_stateid *stp) | |||
| 668 | static void release_open_stateid(struct nfs4_ol_stateid *stp) | 673 | static void release_open_stateid(struct nfs4_ol_stateid *stp) |
| 669 | { | 674 | { |
| 670 | unhash_open_stateid(stp); | 675 | unhash_open_stateid(stp); |
| 671 | unhash_stid(&stp->st_stid); | ||
| 672 | free_generic_stateid(stp); | 676 | free_generic_stateid(stp); |
| 673 | } | 677 | } |
| 674 | 678 | ||
| @@ -690,7 +694,6 @@ static void release_last_closed_stateid(struct nfs4_openowner *oo) | |||
| 690 | struct nfs4_ol_stateid *s = oo->oo_last_closed_stid; | 694 | struct nfs4_ol_stateid *s = oo->oo_last_closed_stid; |
| 691 | 695 | ||
| 692 | if (s) { | 696 | if (s) { |
| 693 | unhash_stid(&s->st_stid); | ||
| 694 | free_generic_stateid(s); | 697 | free_generic_stateid(s); |
| 695 | oo->oo_last_closed_stid = NULL; | 698 | oo->oo_last_closed_stid = NULL; |
| 696 | } | 699 | } |
| @@ -1127,6 +1130,11 @@ destroy_client(struct nfs4_client *clp) | |||
| 1127 | dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); | 1130 | dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); |
| 1128 | destroy_delegation(dp); | 1131 | destroy_delegation(dp); |
| 1129 | } | 1132 | } |
| 1133 | list_splice_init(&clp->cl_revoked, &reaplist); | ||
| 1134 | while (!list_empty(&reaplist)) { | ||
| 1135 | dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); | ||
| 1136 | destroy_revoked_delegation(dp); | ||
| 1137 | } | ||
| 1130 | while (!list_empty(&clp->cl_openowners)) { | 1138 | while (!list_empty(&clp->cl_openowners)) { |
| 1131 | oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); | 1139 | oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); |
| 1132 | release_openowner(oo); | 1140 | release_openowner(oo); |
| @@ -3154,7 +3162,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh, | |||
| 3154 | open->op_delegate_type = NFS4_OPEN_DELEGATE_READ; | 3162 | open->op_delegate_type = NFS4_OPEN_DELEGATE_READ; |
| 3155 | return; | 3163 | return; |
| 3156 | out_free: | 3164 | out_free: |
| 3157 | unhash_stid(&dp->dl_stid); | 3165 | remove_stid(&dp->dl_stid); |
| 3158 | nfs4_put_delegation(dp); | 3166 | nfs4_put_delegation(dp); |
| 3159 | out_no_deleg: | 3167 | out_no_deleg: |
| 3160 | open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE; | 3168 | open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE; |
| @@ -3995,10 +4003,9 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
| 3995 | 4003 | ||
| 3996 | nfsd4_close_open_stateid(stp); | 4004 | nfsd4_close_open_stateid(stp); |
| 3997 | 4005 | ||
| 3998 | if (cstate->minorversion) { | 4006 | if (cstate->minorversion) |
| 3999 | unhash_stid(&stp->st_stid); | ||
| 4000 | free_generic_stateid(stp); | 4007 | free_generic_stateid(stp); |
| 4001 | } else | 4008 | else |
| 4002 | oo->oo_last_closed_stid = stp; | 4009 | oo->oo_last_closed_stid = stp; |
| 4003 | 4010 | ||
| 4004 | if (list_empty(&oo->oo_owner.so_stateids)) { | 4011 | if (list_empty(&oo->oo_owner.so_stateids)) { |
| @@ -5119,7 +5126,6 @@ out_recovery: | |||
| 5119 | return ret; | 5126 | return ret; |
| 5120 | } | 5127 | } |
| 5121 | 5128 | ||
| 5122 | /* should be called with the state lock held */ | ||
| 5123 | void | 5129 | void |
| 5124 | nfs4_state_shutdown_net(struct net *net) | 5130 | nfs4_state_shutdown_net(struct net *net) |
| 5125 | { | 5131 | { |
| @@ -5130,6 +5136,7 @@ nfs4_state_shutdown_net(struct net *net) | |||
| 5130 | cancel_delayed_work_sync(&nn->laundromat_work); | 5136 | cancel_delayed_work_sync(&nn->laundromat_work); |
| 5131 | locks_end_grace(&nn->nfsd4_manager); | 5137 | locks_end_grace(&nn->nfsd4_manager); |
| 5132 | 5138 | ||
| 5139 | nfs4_lock_state(); | ||
| 5133 | INIT_LIST_HEAD(&reaplist); | 5140 | INIT_LIST_HEAD(&reaplist); |
| 5134 | spin_lock(&recall_lock); | 5141 | spin_lock(&recall_lock); |
| 5135 | list_for_each_safe(pos, next, &nn->del_recall_lru) { | 5142 | list_for_each_safe(pos, next, &nn->del_recall_lru) { |
| @@ -5144,6 +5151,7 @@ nfs4_state_shutdown_net(struct net *net) | |||
| 5144 | 5151 | ||
| 5145 | nfsd4_client_tracking_exit(net); | 5152 | nfsd4_client_tracking_exit(net); |
| 5146 | nfs4_state_destroy_net(net); | 5153 | nfs4_state_destroy_net(net); |
| 5154 | nfs4_unlock_state(); | ||
| 5147 | } | 5155 | } |
| 5148 | 5156 | ||
| 5149 | void | 5157 | void |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index d9454fe5653f..088de1355e93 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -411,6 +411,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, | |||
| 411 | label->data = kzalloc(dummy32 + 1, GFP_KERNEL); | 411 | label->data = kzalloc(dummy32 + 1, GFP_KERNEL); |
| 412 | if (!label->data) | 412 | if (!label->data) |
| 413 | return nfserr_jukebox; | 413 | return nfserr_jukebox; |
| 414 | label->len = dummy32; | ||
| 414 | defer_free(argp, kfree, label->data); | 415 | defer_free(argp, kfree, label->data); |
| 415 | memcpy(label->data, buf, dummy32); | 416 | memcpy(label->data, buf, dummy32); |
| 416 | } | 417 | } |
| @@ -945,13 +946,16 @@ static __be32 | |||
| 945 | nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) | 946 | nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) |
| 946 | { | 947 | { |
| 947 | DECODE_HEAD; | 948 | DECODE_HEAD; |
| 948 | 949 | ||
| 950 | if (argp->minorversion >= 1) | ||
| 951 | return nfserr_notsupp; | ||
| 952 | |||
| 949 | status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); | 953 | status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); |
| 950 | if (status) | 954 | if (status) |
| 951 | return status; | 955 | return status; |
| 952 | READ_BUF(4); | 956 | READ_BUF(4); |
| 953 | READ32(open_conf->oc_seqid); | 957 | READ32(open_conf->oc_seqid); |
| 954 | 958 | ||
| 955 | DECODE_TAIL; | 959 | DECODE_TAIL; |
| 956 | } | 960 | } |
| 957 | 961 | ||
| @@ -991,6 +995,14 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) | |||
| 991 | } | 995 | } |
| 992 | 996 | ||
| 993 | static __be32 | 997 | static __be32 |
| 998 | nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p) | ||
| 999 | { | ||
| 1000 | if (argp->minorversion == 0) | ||
| 1001 | return nfs_ok; | ||
| 1002 | return nfserr_notsupp; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | static __be32 | ||
| 994 | nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) | 1006 | nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) |
| 995 | { | 1007 | { |
| 996 | DECODE_HEAD; | 1008 | DECODE_HEAD; |
| @@ -1061,6 +1073,9 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) | |||
| 1061 | { | 1073 | { |
| 1062 | DECODE_HEAD; | 1074 | DECODE_HEAD; |
| 1063 | 1075 | ||
| 1076 | if (argp->minorversion >= 1) | ||
| 1077 | return nfserr_notsupp; | ||
| 1078 | |||
| 1064 | READ_BUF(sizeof(clientid_t)); | 1079 | READ_BUF(sizeof(clientid_t)); |
| 1065 | COPYMEM(clientid, sizeof(clientid_t)); | 1080 | COPYMEM(clientid, sizeof(clientid_t)); |
| 1066 | 1081 | ||
| @@ -1111,6 +1126,9 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient | |||
| 1111 | { | 1126 | { |
| 1112 | DECODE_HEAD; | 1127 | DECODE_HEAD; |
| 1113 | 1128 | ||
| 1129 | if (argp->minorversion >= 1) | ||
| 1130 | return nfserr_notsupp; | ||
| 1131 | |||
| 1114 | READ_BUF(NFS4_VERIFIER_SIZE); | 1132 | READ_BUF(NFS4_VERIFIER_SIZE); |
| 1115 | COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE); | 1133 | COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE); |
| 1116 | 1134 | ||
| @@ -1137,6 +1155,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s | |||
| 1137 | { | 1155 | { |
| 1138 | DECODE_HEAD; | 1156 | DECODE_HEAD; |
| 1139 | 1157 | ||
| 1158 | if (argp->minorversion >= 1) | ||
| 1159 | return nfserr_notsupp; | ||
| 1160 | |||
| 1140 | READ_BUF(8 + NFS4_VERIFIER_SIZE); | 1161 | READ_BUF(8 + NFS4_VERIFIER_SIZE); |
| 1141 | COPYMEM(&scd_c->sc_clientid, 8); | 1162 | COPYMEM(&scd_c->sc_clientid, 8); |
| 1142 | COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE); | 1163 | COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE); |
| @@ -1220,6 +1241,9 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel | |||
| 1220 | { | 1241 | { |
| 1221 | DECODE_HEAD; | 1242 | DECODE_HEAD; |
| 1222 | 1243 | ||
| 1244 | if (argp->minorversion >= 1) | ||
| 1245 | return nfserr_notsupp; | ||
| 1246 | |||
| 1223 | READ_BUF(12); | 1247 | READ_BUF(12); |
| 1224 | COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); | 1248 | COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); |
| 1225 | READ32(rlockowner->rl_owner.len); | 1249 | READ32(rlockowner->rl_owner.len); |
| @@ -1519,7 +1543,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { | |||
| 1519 | [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, | 1543 | [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, |
| 1520 | [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, | 1544 | [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, |
| 1521 | [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, | 1545 | [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, |
| 1522 | [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop, | 1546 | [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh, |
| 1523 | [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, | 1547 | [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, |
| 1524 | [OP_READ] = (nfsd4_dec)nfsd4_decode_read, | 1548 | [OP_READ] = (nfsd4_dec)nfsd4_decode_read, |
| 1525 | [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, | 1549 | [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, |
| @@ -1536,46 +1560,6 @@ static nfsd4_dec nfsd4_dec_ops[] = { | |||
| 1536 | [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, | 1560 | [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, |
| 1537 | [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, | 1561 | [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, |
| 1538 | [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, | 1562 | [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, |
| 1539 | }; | ||
| 1540 | |||
| 1541 | static nfsd4_dec nfsd41_dec_ops[] = { | ||
| 1542 | [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, | ||
| 1543 | [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, | ||
| 1544 | [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, | ||
| 1545 | [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, | ||
| 1546 | [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1547 | [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, | ||
| 1548 | [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, | ||
| 1549 | [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
| 1550 | [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, | ||
| 1551 | [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, | ||
| 1552 | [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, | ||
| 1553 | [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, | ||
| 1554 | [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, | ||
| 1555 | [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, | ||
| 1556 | [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, | ||
| 1557 | [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, | ||
| 1558 | [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1559 | [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1560 | [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, | ||
| 1561 | [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, | ||
| 1562 | [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1563 | [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
| 1564 | [OP_READ] = (nfsd4_dec)nfsd4_decode_read, | ||
| 1565 | [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, | ||
| 1566 | [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, | ||
| 1567 | [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, | ||
| 1568 | [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, | ||
| 1569 | [OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1570 | [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
| 1571 | [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
| 1572 | [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, | ||
| 1573 | [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, | ||
| 1574 | [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1575 | [OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1576 | [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, | ||
| 1577 | [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, | ||
| 1578 | [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
| 1579 | 1563 | ||
| 1580 | /* new operations for NFSv4.1 */ | 1564 | /* new operations for NFSv4.1 */ |
| 1581 | [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, | 1565 | [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, |
| @@ -1599,24 +1583,53 @@ static nfsd4_dec nfsd41_dec_ops[] = { | |||
| 1599 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, | 1583 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, |
| 1600 | }; | 1584 | }; |
| 1601 | 1585 | ||
| 1602 | struct nfsd4_minorversion_ops { | 1586 | static inline bool |
| 1603 | nfsd4_dec *decoders; | 1587 | nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op) |
| 1604 | int nops; | 1588 | { |
| 1605 | }; | 1589 | if (op->opnum < FIRST_NFS4_OP) |
| 1590 | return false; | ||
| 1591 | else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP) | ||
| 1592 | return false; | ||
| 1593 | else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP) | ||
| 1594 | return false; | ||
| 1595 | else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP) | ||
| 1596 | return false; | ||
| 1597 | return true; | ||
| 1598 | } | ||
| 1606 | 1599 | ||
| 1607 | static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { | 1600 | /* |
| 1608 | [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, | 1601 | * Return a rough estimate of the maximum possible reply size. Note the |
| 1609 | [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, | 1602 | * estimate includes rpc headers so is meant to be passed to |
| 1610 | [2] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, | 1603 | * svc_reserve, not svc_reserve_auth. |
| 1611 | }; | 1604 | * |
| 1605 | * Also note the current compound encoding permits only one operation to | ||
| 1606 | * use pages beyond the first one, so the maximum possible length is the | ||
| 1607 | * maximum over these values, not the sum. | ||
| 1608 | */ | ||
| 1609 | static int nfsd4_max_reply(u32 opnum) | ||
| 1610 | { | ||
| 1611 | switch (opnum) { | ||
| 1612 | case OP_READLINK: | ||
| 1613 | case OP_READDIR: | ||
| 1614 | /* | ||
| 1615 | * Both of these ops take a single page for data and put | ||
| 1616 | * the head and tail in another page: | ||
| 1617 | */ | ||
| 1618 | return 2 * PAGE_SIZE; | ||
| 1619 | case OP_READ: | ||
| 1620 | return INT_MAX; | ||
| 1621 | default: | ||
| 1622 | return PAGE_SIZE; | ||
| 1623 | } | ||
| 1624 | } | ||
| 1612 | 1625 | ||
| 1613 | static __be32 | 1626 | static __be32 |
| 1614 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | 1627 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) |
| 1615 | { | 1628 | { |
| 1616 | DECODE_HEAD; | 1629 | DECODE_HEAD; |
| 1617 | struct nfsd4_op *op; | 1630 | struct nfsd4_op *op; |
| 1618 | struct nfsd4_minorversion_ops *ops; | ||
| 1619 | bool cachethis = false; | 1631 | bool cachethis = false; |
| 1632 | int max_reply = PAGE_SIZE; | ||
| 1620 | int i; | 1633 | int i; |
| 1621 | 1634 | ||
| 1622 | READ_BUF(4); | 1635 | READ_BUF(4); |
| @@ -1640,10 +1653,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
| 1640 | } | 1653 | } |
| 1641 | } | 1654 | } |
| 1642 | 1655 | ||
| 1643 | if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion)) | 1656 | if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION) |
| 1644 | argp->opcnt = 0; | 1657 | argp->opcnt = 0; |
| 1645 | 1658 | ||
| 1646 | ops = &nfsd4_minorversion[argp->minorversion]; | ||
| 1647 | for (i = 0; i < argp->opcnt; i++) { | 1659 | for (i = 0; i < argp->opcnt; i++) { |
| 1648 | op = &argp->ops[i]; | 1660 | op = &argp->ops[i]; |
| 1649 | op->replay = NULL; | 1661 | op->replay = NULL; |
| @@ -1651,8 +1663,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
| 1651 | READ_BUF(4); | 1663 | READ_BUF(4); |
| 1652 | READ32(op->opnum); | 1664 | READ32(op->opnum); |
| 1653 | 1665 | ||
| 1654 | if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP) | 1666 | if (nfsd4_opnum_in_range(argp, op)) |
| 1655 | op->status = ops->decoders[op->opnum](argp, &op->u); | 1667 | op->status = nfsd4_dec_ops[op->opnum](argp, &op->u); |
| 1656 | else { | 1668 | else { |
| 1657 | op->opnum = OP_ILLEGAL; | 1669 | op->opnum = OP_ILLEGAL; |
| 1658 | op->status = nfserr_op_illegal; | 1670 | op->status = nfserr_op_illegal; |
| @@ -1667,10 +1679,14 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
| 1667 | * op in the compound wants to be cached: | 1679 | * op in the compound wants to be cached: |
| 1668 | */ | 1680 | */ |
| 1669 | cachethis |= nfsd4_cache_this_op(op); | 1681 | cachethis |= nfsd4_cache_this_op(op); |
| 1682 | |||
| 1683 | max_reply = max(max_reply, nfsd4_max_reply(op->opnum)); | ||
| 1670 | } | 1684 | } |
| 1671 | /* Sessions make the DRC unnecessary: */ | 1685 | /* Sessions make the DRC unnecessary: */ |
| 1672 | if (argp->minorversion) | 1686 | if (argp->minorversion) |
| 1673 | cachethis = false; | 1687 | cachethis = false; |
| 1688 | if (max_reply != INT_MAX) | ||
| 1689 | svc_reserve(argp->rqstp, max_reply); | ||
| 1674 | argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; | 1690 | argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; |
| 1675 | 1691 | ||
| 1676 | DECODE_TAIL; | 1692 | DECODE_TAIL; |
| @@ -2375,7 +2391,7 @@ out_acl: | |||
| 2375 | if (bmval0 & FATTR4_WORD0_MAXFILESIZE) { | 2391 | if (bmval0 & FATTR4_WORD0_MAXFILESIZE) { |
| 2376 | if ((buflen -= 8) < 0) | 2392 | if ((buflen -= 8) < 0) |
| 2377 | goto out_resource; | 2393 | goto out_resource; |
| 2378 | WRITE64(~(u64)0); | 2394 | WRITE64(exp->ex_path.mnt->mnt_sb->s_maxbytes); |
| 2379 | } | 2395 | } |
| 2380 | if (bmval0 & FATTR4_WORD0_MAXLINK) { | 2396 | if (bmval0 & FATTR4_WORD0_MAXLINK) { |
| 2381 | if ((buflen -= 4) < 0) | 2397 | if ((buflen -= 4) < 0) |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 3d0e15ae6f72..3c37b160dcad 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
| @@ -598,22 +598,20 @@ fh_update(struct svc_fh *fhp) | |||
| 598 | _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); | 598 | _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); |
| 599 | } else { | 599 | } else { |
| 600 | if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) | 600 | if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) |
| 601 | goto out; | 601 | return 0; |
| 602 | 602 | ||
| 603 | _fh_update(fhp, fhp->fh_export, dentry); | 603 | _fh_update(fhp, fhp->fh_export, dentry); |
| 604 | if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) | 604 | if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) |
| 605 | return nfserr_opnotsupp; | 605 | return nfserr_opnotsupp; |
| 606 | } | 606 | } |
| 607 | out: | ||
| 608 | return 0; | 607 | return 0; |
| 609 | |||
| 610 | out_bad: | 608 | out_bad: |
| 611 | printk(KERN_ERR "fh_update: fh not verified!\n"); | 609 | printk(KERN_ERR "fh_update: fh not verified!\n"); |
| 612 | goto out; | 610 | return nfserr_serverfault; |
| 613 | out_negative: | 611 | out_negative: |
| 614 | printk(KERN_ERR "fh_update: %pd2 still negative!\n", | 612 | printk(KERN_ERR "fh_update: %pd2 still negative!\n", |
| 615 | dentry); | 613 | dentry); |
| 616 | goto out; | 614 | return nfserr_serverfault; |
| 617 | } | 615 | } |
| 618 | 616 | ||
| 619 | /* | 617 | /* |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index c6f41b616965..c1637062c1ce 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
| @@ -118,6 +118,9 @@ Needs to be updated if more operations are defined in future.*/ | |||
| 118 | 118 | ||
| 119 | #define FIRST_NFS4_OP OP_ACCESS | 119 | #define FIRST_NFS4_OP OP_ACCESS |
| 120 | #define LAST_NFS4_OP OP_RECLAIM_COMPLETE | 120 | #define LAST_NFS4_OP OP_RECLAIM_COMPLETE |
| 121 | #define LAST_NFS40_OP OP_RELEASE_LOCKOWNER | ||
| 122 | #define LAST_NFS41_OP OP_RECLAIM_COMPLETE | ||
| 123 | #define LAST_NFS42_OP OP_RECLAIM_COMPLETE | ||
| 121 | 124 | ||
| 122 | enum nfsstat4 { | 125 | enum nfsstat4 { |
| 123 | NFS4_OK = 0, | 126 | NFS4_OK = 0, |
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index 6cd930f3678f..6c981ddc19f8 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c | |||
| @@ -150,7 +150,6 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, | |||
| 150 | struct xdr_netobj cksumobj = {.len = sizeof(cksumdata), | 150 | struct xdr_netobj cksumobj = {.len = sizeof(cksumdata), |
| 151 | .data = cksumdata}; | 151 | .data = cksumdata}; |
| 152 | s32 now; | 152 | s32 now; |
| 153 | u64 seqnum; | ||
| 154 | u8 *ptr = read_token->data; | 153 | u8 *ptr = read_token->data; |
| 155 | u8 *cksumkey; | 154 | u8 *cksumkey; |
| 156 | u8 flags; | 155 | u8 flags; |
| @@ -197,9 +196,10 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, | |||
| 197 | if (now > ctx->endtime) | 196 | if (now > ctx->endtime) |
| 198 | return GSS_S_CONTEXT_EXPIRED; | 197 | return GSS_S_CONTEXT_EXPIRED; |
| 199 | 198 | ||
| 200 | /* do sequencing checks */ | 199 | /* |
| 201 | 200 | * NOTE: the sequence number at ptr + 8 is skipped, rpcsec_gss | |
| 202 | seqnum = be64_to_cpup((__be64 *)ptr + 8); | 201 | * doesn't want it checked; see page 6 of rfc 2203. |
| 202 | */ | ||
| 203 | 203 | ||
| 204 | return GSS_S_COMPLETE; | 204 | return GSS_S_COMPLETE; |
| 205 | } | 205 | } |
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 1da52d1406fc..42560e55d978 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c | |||
| @@ -489,7 +489,6 @@ static u32 | |||
| 489 | gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) | 489 | gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) |
| 490 | { | 490 | { |
| 491 | s32 now; | 491 | s32 now; |
| 492 | u64 seqnum; | ||
| 493 | u8 *ptr; | 492 | u8 *ptr; |
| 494 | u8 flags = 0x00; | 493 | u8 flags = 0x00; |
| 495 | u16 ec, rrc; | 494 | u16 ec, rrc; |
| @@ -525,7 +524,10 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) | |||
| 525 | ec = be16_to_cpup((__be16 *)(ptr + 4)); | 524 | ec = be16_to_cpup((__be16 *)(ptr + 4)); |
| 526 | rrc = be16_to_cpup((__be16 *)(ptr + 6)); | 525 | rrc = be16_to_cpup((__be16 *)(ptr + 6)); |
| 527 | 526 | ||
| 528 | seqnum = be64_to_cpup((__be64 *)(ptr + 8)); | 527 | /* |
| 528 | * NOTE: the sequence number at ptr + 8 is skipped, rpcsec_gss | ||
| 529 | * doesn't want it checked; see page 6 of rfc 2203. | ||
| 530 | */ | ||
| 529 | 531 | ||
| 530 | if (rrc != 0) | 532 | if (rrc != 0) |
| 531 | rotate_left(offset + 16, buf, rrc); | 533 | rotate_left(offset + 16, buf, rrc); |
| @@ -574,8 +576,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) | |||
| 574 | buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; | 576 | buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; |
| 575 | buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip; | 577 | buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip; |
| 576 | 578 | ||
| 577 | /* Trim off the checksum blob */ | 579 | /* Trim off the trailing "extra count" and checksum blob */ |
| 578 | xdr_buf_trim(buf, GSS_KRB5_TOK_HDR_LEN + tailskip); | 580 | xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip); |
| 579 | return GSS_S_COMPLETE; | 581 | return GSS_S_COMPLETE; |
| 580 | } | 582 | } |
| 581 | 583 | ||
diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index f1eb0d16666c..458f85e9b0ba 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c | |||
| @@ -298,7 +298,8 @@ int gssp_accept_sec_context_upcall(struct net *net, | |||
| 298 | if (res.context_handle) { | 298 | if (res.context_handle) { |
| 299 | data->out_handle = rctxh.exported_context_token; | 299 | data->out_handle = rctxh.exported_context_token; |
| 300 | data->mech_oid.len = rctxh.mech.len; | 300 | data->mech_oid.len = rctxh.mech.len; |
| 301 | memcpy(data->mech_oid.data, rctxh.mech.data, | 301 | if (rctxh.mech.data) |
| 302 | memcpy(data->mech_oid.data, rctxh.mech.data, | ||
| 302 | data->mech_oid.len); | 303 | data->mech_oid.len); |
| 303 | client_name = rctxh.src_name.display_name; | 304 | client_name = rctxh.src_name.display_name; |
| 304 | } | 305 | } |
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index f0f78c5f1c7d..1ec19f6f0c2b 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c | |||
| @@ -559,6 +559,8 @@ static int gssx_enc_cred(struct xdr_stream *xdr, | |||
| 559 | 559 | ||
| 560 | /* cred->elements */ | 560 | /* cred->elements */ |
| 561 | err = dummy_enc_credel_array(xdr, &cred->elements); | 561 | err = dummy_enc_credel_array(xdr, &cred->elements); |
| 562 | if (err) | ||
| 563 | return err; | ||
| 562 | 564 | ||
| 563 | /* cred->cred_handle_reference */ | 565 | /* cred->cred_handle_reference */ |
| 564 | err = gssx_enc_buffer(xdr, &cred->cred_handle_reference); | 566 | err = gssx_enc_buffer(xdr, &cred->cred_handle_reference); |
| @@ -740,22 +742,20 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req, | |||
| 740 | goto done; | 742 | goto done; |
| 741 | 743 | ||
| 742 | /* arg->context_handle */ | 744 | /* arg->context_handle */ |
| 743 | if (arg->context_handle) { | 745 | if (arg->context_handle) |
| 744 | err = gssx_enc_ctx(xdr, arg->context_handle); | 746 | err = gssx_enc_ctx(xdr, arg->context_handle); |
| 745 | if (err) | 747 | else |
| 746 | goto done; | ||
| 747 | } else { | ||
| 748 | err = gssx_enc_bool(xdr, 0); | 748 | err = gssx_enc_bool(xdr, 0); |
| 749 | } | 749 | if (err) |
| 750 | goto done; | ||
| 750 | 751 | ||
| 751 | /* arg->cred_handle */ | 752 | /* arg->cred_handle */ |
| 752 | if (arg->cred_handle) { | 753 | if (arg->cred_handle) |
| 753 | err = gssx_enc_cred(xdr, arg->cred_handle); | 754 | err = gssx_enc_cred(xdr, arg->cred_handle); |
| 754 | if (err) | 755 | else |
| 755 | goto done; | ||
| 756 | } else { | ||
| 757 | err = gssx_enc_bool(xdr, 0); | 756 | err = gssx_enc_bool(xdr, 0); |
| 758 | } | 757 | if (err) |
| 758 | goto done; | ||
| 759 | 759 | ||
| 760 | /* arg->input_token */ | 760 | /* arg->input_token */ |
| 761 | err = gssx_enc_in_token(xdr, &arg->input_token); | 761 | err = gssx_enc_in_token(xdr, &arg->input_token); |
| @@ -763,13 +763,12 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req, | |||
| 763 | goto done; | 763 | goto done; |
| 764 | 764 | ||
| 765 | /* arg->input_cb */ | 765 | /* arg->input_cb */ |
| 766 | if (arg->input_cb) { | 766 | if (arg->input_cb) |
| 767 | err = gssx_enc_cb(xdr, arg->input_cb); | 767 | err = gssx_enc_cb(xdr, arg->input_cb); |
| 768 | if (err) | 768 | else |
| 769 | goto done; | ||
| 770 | } else { | ||
| 771 | err = gssx_enc_bool(xdr, 0); | 769 | err = gssx_enc_bool(xdr, 0); |
| 772 | } | 770 | if (err) |
| 771 | goto done; | ||
| 773 | 772 | ||
| 774 | err = gssx_enc_bool(xdr, arg->ret_deleg_cred); | 773 | err = gssx_enc_bool(xdr, arg->ret_deleg_cred); |
| 775 | if (err) | 774 | if (err) |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 09fb638bcaa4..008cdade5aae 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -1167,8 +1167,8 @@ static int gss_proxy_save_rsc(struct cache_detail *cd, | |||
| 1167 | if (!ud->found_creds) { | 1167 | if (!ud->found_creds) { |
| 1168 | /* userspace seem buggy, we should always get at least a | 1168 | /* userspace seem buggy, we should always get at least a |
| 1169 | * mapping to nobody */ | 1169 | * mapping to nobody */ |
| 1170 | dprintk("RPC: No creds found, marking Negative!\n"); | 1170 | dprintk("RPC: No creds found!\n"); |
| 1171 | set_bit(CACHE_NEGATIVE, &rsci.h.flags); | 1171 | goto out; |
| 1172 | } else { | 1172 | } else { |
| 1173 | 1173 | ||
| 1174 | /* steal creds */ | 1174 | /* steal creds */ |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index b974571126fe..e7fbe368b4a3 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -1104,8 +1104,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
| 1104 | rqstp->rq_vers = vers = svc_getnl(argv); /* version number */ | 1104 | rqstp->rq_vers = vers = svc_getnl(argv); /* version number */ |
| 1105 | rqstp->rq_proc = proc = svc_getnl(argv); /* procedure number */ | 1105 | rqstp->rq_proc = proc = svc_getnl(argv); /* procedure number */ |
| 1106 | 1106 | ||
| 1107 | progp = serv->sv_program; | ||
| 1108 | |||
| 1109 | for (progp = serv->sv_program; progp; progp = progp->pg_next) | 1107 | for (progp = serv->sv_program; progp; progp = progp->pg_next) |
| 1110 | if (prog == progp->pg_prog) | 1108 | if (prog == progp->pg_prog) |
| 1111 | break; | 1109 | break; |
