Skip to contentSkip to conversation

nfs: fix nfs4d readlink truncated packet

PATCH In review Avi Kivity 3 participants 4 messages Jun 26, 2014 – Jul 2, 2014

Subsystems (2)
lore
Share & tools
lore

Avi Kivity

author
#0 lore raw

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
index 83baf2b..cba93ea 100644
@@ -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
author
#1 lore raw
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
---
  fs/nfsd/nfs4xdr.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
index 83baf2b..cba93ea 100644
@@ -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));
Reviewed-by
#2 lore raw
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.

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
---
  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
index 83baf2b..cba93ea 100644
@@ -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

#3 lore raw
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 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 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.

Thanks! I've also added your symptoms and the problematic commit to the changelog.

--b.