2007-12-20 19:54:46

by Chuck Lever

[permalink] [raw]
Subject: [PATCH 1/8] SUNRPC: Fix use of copy_to_user() in gss_pipe_upcall()

The gss_pipe_upcall() function expects the copy_to_user() function to
return a negative error value if the call fails, but copy_to_user()
returns an unsigned long number of bytes that couldn't be copied.

Can rpc_pipefs actually retry a partially completed upcall read? If
not, then gss_pipe_upcall() should punt any partial read, just like the
upcall logic in net/sunrpc/cache.c.

Signed-off-by: Chuck Lever <[email protected]>
---

net/sunrpc/auth_gss/auth_gss.c | 13 ++++++-------
1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index a6e57d1..1fa7e76 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -472,16 +472,15 @@ gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
char __user *dst, size_t buflen)
{
char *data = (char *)msg->data + msg->copied;
- ssize_t mlen = msg->len;
- ssize_t left;
+ size_t mlen = min(msg->len, buflen);
+ unsigned long left;

- if (mlen > buflen)
- mlen = buflen;
left = copy_to_user(dst, data, mlen);
- if (left < 0) {
- msg->errno = left;
- return left;
+ if (left == mlen) {
+ msg->errno = -EFAULT;
+ return -EFAULT;
}
+
mlen -= left;
msg->copied += mlen;
msg->errno = 0;