aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-12-20 14:54:27 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:06:00 -0500
commit7df089952fca41cb336733e1167c0a25e5a025d8 (patch)
tree8258f098e1b43cc15fa4c6299d77b6d69a7f45ff
parent59dca3b28cb915745019d4f4c27d97b6b6ab12c6 (diff)
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 <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c13
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 1f2d85e869c0..6dac38792288 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,
472 char __user *dst, size_t buflen) 472 char __user *dst, size_t buflen)
473{ 473{
474 char *data = (char *)msg->data + msg->copied; 474 char *data = (char *)msg->data + msg->copied;
475 ssize_t mlen = msg->len; 475 size_t mlen = min(msg->len, buflen);
476 ssize_t left; 476 unsigned long left;
477 477
478 if (mlen > buflen)
479 mlen = buflen;
480 left = copy_to_user(dst, data, mlen); 478 left = copy_to_user(dst, data, mlen);
481 if (left < 0) { 479 if (left == mlen) {
482 msg->errno = left; 480 msg->errno = -EFAULT;
483 return left; 481 return -EFAULT;
484 } 482 }
483
485 mlen -= left; 484 mlen -= left;
486 msg->copied += mlen; 485 msg->copied += mlen;
487 msg->errno = 0; 486 msg->errno = 0;