Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8db1592 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

lockd: fix decoding of TEST results



We fail to advance the read pointer when reading the stat.oh field that
identifies the lock-holder in a TEST result.

This turns out not to matter if the server is knfsd, which always
returns a zero-length field.  But other servers (Ganesha is an example)
may not do this.  The result is bad values in fcntl F_GETLK results.

Fix this.

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 0d4d6720
Loading
Loading
Loading
Loading
+6 −16
Original line number Diff line number Diff line
@@ -128,24 +128,14 @@ static void encode_netobj(struct xdr_stream *xdr,
static int decode_netobj(struct xdr_stream *xdr,
			 struct xdr_netobj *obj)
{
	u32 length;
	__be32 *p;
	ssize_t ret;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(p == NULL))
		goto out_overflow;
	length = be32_to_cpup(p++);
	if (unlikely(length > XDR_MAX_NETOBJ))
		goto out_size;
	obj->len = length;
	obj->data = (u8 *)p;
	return 0;
out_size:
	dprintk("NFS: returned netobj was too long: %u\n", length);
	return -EIO;
out_overflow:
	print_overflow_msg(__func__, xdr);
	ret = xdr_stream_decode_opaque_inline(xdr, (void *)&obj->data,
						XDR_MAX_NETOBJ);
	if (unlikely(ret < 0))
		return -EIO;
	obj->len = ret;
	return 0;
}

/*
+6 −16
Original line number Diff line number Diff line
@@ -125,24 +125,14 @@ static void encode_netobj(struct xdr_stream *xdr,
static int decode_netobj(struct xdr_stream *xdr,
			 struct xdr_netobj *obj)
{
	u32 length;
	__be32 *p;
	ssize_t ret;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(p == NULL))
		goto out_overflow;
	length = be32_to_cpup(p++);
	if (unlikely(length > XDR_MAX_NETOBJ))
		goto out_size;
	obj->len = length;
	obj->data = (u8 *)p;
	return 0;
out_size:
	dprintk("NFS: returned netobj was too long: %u\n", length);
	return -EIO;
out_overflow:
	print_overflow_msg(__func__, xdr);
	ret = xdr_stream_decode_opaque_inline(xdr, (void *)&obj->data,
			XDR_MAX_NETOBJ);
	if (unlikely(ret < 0))
		return -EIO;
	obj->len = ret;
	return 0;
}

/*