From: Chuck Lever Date: Thu, 20 Dec 2007 14:54:27 -0500 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 Signed-off-by: Trond Myklebust --- 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 1f2d85e..6dac387 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;