nfsd: fix rare symlink decoding bug
[firefly-linux-kernel-4.4.55.git] / fs / nfsd / nfs4proc.c
index 16e71d033ea5d7393d8b2342e4076ea326dd1265..8f029db5d271d6c77e6bf22a3cf3e3924ce27f08 100644 (file)
@@ -430,12 +430,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                                goto out;
                        break;
                case NFS4_OPEN_CLAIM_PREVIOUS:
-                       open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
                        status = nfs4_check_open_reclaim(&open->op_clientid,
                                                         cstate->minorversion,
                                                         nn);
                        if (status)
                                goto out;
+                       open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
                case NFS4_OPEN_CLAIM_FH:
                case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
                        status = do_open_fhandle(rqstp, cstate, open);
@@ -445,7 +445,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        break;
                case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
                case NFS4_OPEN_CLAIM_DELEGATE_PREV:
-                       open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
                        dprintk("NFSD: unsupported OPEN claim type %d\n",
                                open->op_claim_type);
                        status = nfserr_notsupp;
@@ -618,15 +617,6 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        switch (create->cr_type) {
        case NF4LNK:
-               /* ugh! we have to null-terminate the linktext, or
-                * vfs_symlink() will choke.  it is always safe to
-                * null-terminate by brute force, since at worst we
-                * will overwrite the first byte of the create namelen
-                * in the XDR buffer, which has already been extracted
-                * during XDR decode.
-                */
-               create->cr_linkname[create->cr_linklen] = 0;
-
                status = nfsd_symlink(rqstp, &cstate->current_fh,
                                      create->cr_name, create->cr_namelen,
                                      create->cr_linkname, create->cr_linklen,
@@ -1265,7 +1255,7 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,
        /* Tail and page_len should be zero at this point: */
        buf->len = buf->head[0].iov_len;
        xdr->scratch.iov_len = 0;
-       xdr->page_ptr = buf->pages;
+       xdr->page_ptr = buf->pages - 1;
        buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages)
                - rqstp->rq_auth_slack;
 }
@@ -1291,11 +1281,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
        xdr_reserve_space(&resp->xdr, 8 + args->taglen);
        resp->taglen = args->taglen;
        resp->tag = args->tag;
-       resp->opcnt = 0;
        resp->rqstp = rqstp;
        cstate->minorversion = args->minorversion;
-       cstate->replay_owner = NULL;
-       cstate->session = NULL;
        fh_init(current_fh, NFS4_FHSIZE);
        fh_init(save_fh, NFS4_FHSIZE);
        /*