nfs: fix nfs4d readlink truncated packet
Subsystems (2)
PATCH 1/1 nfs: fix nfs4d readlink truncated packet
XDR requires 4-byte alignment; nfs4d READLINK reply writes out the padding, but truncates the packet to the padding-less size.
Fix by taking the padding into consideration when truncating the packet.
--- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
@@ -3267,7 +3267,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 ));
Signature · 1 line
1.9.3
Quoted 5 lines · Avi Kivity
XDR requires 4-byte alignment; nfs4d READLINK reply writes out the padding, but truncates the packet to the padding-less size.
Fix by taking the padding into consideration when truncating the packet.
Ping. I should have mentioned that without this, readlink() returns an I/O error on the client.
Quoted 18 lines
Signed-off-by Avi Kivity <[email protected]>--- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)fs/nfsd/nfs4xdr.c +1
-1@@ -3267,7 +3267,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 ));
Kinglong Mee
Reviewed-byQuoted 8 lines · Avi Kivity
Quoted 5 lines · Avi Kivity
XDR requires 4-byte alignment; nfs4d READLINK reply writes out the padding, but truncates the packet to the padding-less size.
Fix by taking the padding into consideration when truncating the packet.
Ping. I should have mentioned that without this,
readlink()returns an I/O error on the client.
Yes, I got
[root@localhost ~]# ll /mnt/
ls: cannot read symbolic link /mnt/test: Input/output error total 4
-rw-r--r--. 1 root root 0 Jun 14 01:21 123456 lrwxrwxrwx. 1 root root 6 Jul 2 03:33 test drwxr-xr-x. 1 root root 0 Jul 2 23:50 tmp
drwxr-xr-x. 1 root root 60 Jul 2 23:44 tree [root@localhost ~]#
It's introduced by commit 476a7b1f4b2c (nfsd4: don't treat readlink like a zero-copy operation).
Quoted 6 lines
Quoted 6 lines
Signed-off-by Avi Kivity <[email protected]>--- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 9 lines
fs/nfsd/nfs4xdr.c nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd · line 3269
Quoted 9 lines
fs/nfsd/nfs4xdr.c +1
-1@@ -3267,7 +3267,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 ));
NFSD uses (XDR_QUADLEN(maxcount) << 2)) usually. Anyway, it's a nice fix.
thanks,
Kinglong Mee
Quoted 10 lines · Kinglong Mee
Quoted 8 lines · Avi Kivity
Quoted 5 lines · Avi Kivity
XDR requires 4-byte alignment; nfs4d READLINK reply writes out the padding, but truncates the packet to the padding-less size.
Fix by taking the padding into consideration when truncating the packet.
Ping. I should have mentioned that without this,
readlink()returns an I/O error on the client.
Thanks, queueing up for 3.16.
Quoted 11 lines
Yes, I got
[root@localhost ~]# ll/mnt/
ls: cannot read symbolic link/mnt/test: Input/output error total 4-rw-r--r--. 1 root root 0 Jun 14 01:21 123456 lrwxrwxrwx. 1 root root 6 Jul 2 03:33 test drwxr-xr-x. 1 root root 0 Jul 2 23:50 tmpdrwxr-xr-x. 1 root root 60 Jul 2 23:44 tree [root@localhost ~]#
It's introduced by commit
476a7b1f4b2c(nfsd4: don't treat readlink like a zero-copy operation).
...
Quoted 3 lines
Quoted 1 line
Quoted 1 line
+
xdr_truncate_encode(xdr, length_offset + 4 + ALIGN(maxcount, 4));NFSD uses (
XDR_QUADLEN(maxcount)<< 2)) usually.
Eh, I didn't know about ALIGN()--I think I prefer it.
Quoted 3 lines
Anyway, it's a nice fix.
Reviewed-by Kinglong Mee <[email protected]>
Thanks! I've also added your symptoms and the problematic commit to the changelog.
--b.