|
@@ -600,7 +600,18 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
|
|
|
READ_BUF(4);
|
|
|
create->cr_linklen = be32_to_cpup(p++);
|
|
|
READ_BUF(create->cr_linklen);
|
|
|
- SAVEMEM(create->cr_linkname, create->cr_linklen);
|
|
|
+ /*
|
|
|
+ * The VFS will want a null-terminated string, and
|
|
|
+ * null-terminating in place isn't safe since this might
|
|
|
+ * end on a page boundary:
|
|
|
+ */
|
|
|
+ create->cr_linkname =
|
|
|
+ kmalloc(create->cr_linklen + 1, GFP_KERNEL);
|
|
|
+ if (!create->cr_linkname)
|
|
|
+ return nfserr_jukebox;
|
|
|
+ memcpy(create->cr_linkname, p, create->cr_linklen);
|
|
|
+ create->cr_linkname[create->cr_linklen] = '\0';
|
|
|
+ defer_free(argp, kfree, create->cr_linkname);
|
|
|
break;
|
|
|
case NF4BLK:
|
|
|
case NF4CHR:
|
|
@@ -3267,7 +3278,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
|
|
|
|
|
|
wire_count = htonl(maxcount);
|
|
|
write_bytes_to_xdr_buf(xdr->buf, length_offset, &wire_count, 4);
|
|
|
- xdr_truncate_encode(xdr, length_offset + 4 + maxcount);
|
|
|
+ xdr_truncate_encode(xdr, length_offset + 4 + ALIGN(maxcount, 4));
|
|
|
if (maxcount & 3)
|
|
|
write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount,
|
|
|
&zero, 4 - (maxcount&3));
|