| From: |
| Trond Myklebust <trond.myklebust@fys.uio.no> |
| To: |
| Linus Torvalds <torvalds@transmeta.com>,
NFS maillist <nfs@lists.sourceforge.net>,nfsv4-wg@citi.umich.edu |
| Subject: |
| [NFS] [PATCH] Secure user authentication using RPCSEC_GSS [4/7] |
| Date: |
| Thu, 31 Oct 2002 21:21:21 +0100 |
The RPCSEC_GSS user context defines a 'sequence number' in the AUTH header
fields in order to provide protection against replay attacks. This
number needs to lie within a given 'window', and is required to be updated
even when retransmitting dropped UDP requests.
In order to allow this update to occur we move the XDR 'encode' phase
so that it is done immediately before we write the data to the socket.
Cheers,
Trond
diff -u --recursive --new-file linux-2.5.44-01-rpc_msg/include/linux/sunrpc/xprt.h linux-2.5.44-02-rpc_encode/include/linux/sunrpc/xprt.h
--- linux-2.5.44-01-rpc_msg/include/linux/sunrpc/xprt.h 2002-10-08 21:37:46.000000000 -0400
+++ linux-2.5.44-02-rpc_encode/include/linux/sunrpc/xprt.h 2002-10-28 17:19:48.000000000 -0500
@@ -187,6 +187,7 @@
unsigned long);
void xprt_reserve(struct rpc_task *);
+int xprt_prepare_transmit(struct rpc_task *);
void xprt_transmit(struct rpc_task *);
void xprt_receive(struct rpc_task *);
int xprt_adjust_timeout(struct rpc_timeout *);
diff -u --recursive --new-file linux-2.5.44-01-rpc_msg/net/sunrpc/clnt.c linux-2.5.44-02-rpc_encode/net/sunrpc/clnt.c
--- linux-2.5.44-01-rpc_msg/net/sunrpc/clnt.c 2002-10-28 17:05:26.000000000 -0500
+++ linux-2.5.44-02-rpc_encode/net/sunrpc/clnt.c 2002-10-28 18:37:27.000000000 -0500
@@ -487,7 +487,7 @@
dprintk("RPC: %4d call_allocate (status %d)\n",
task->tk_pid, task->tk_status);
- task->tk_action = call_encode;
+ task->tk_action = call_bind;
if (task->tk_buffer)
return;
@@ -527,8 +527,6 @@
dprintk("RPC: %4d call_encode (status %d)\n",
task->tk_pid, task->tk_status);
- task->tk_action = call_bind;
-
/* Default buffer setup */
bufsiz = rpcproc_bufsiz(clnt, task->tk_msg.rpc_proc)+RPC_SLACK_SPACE;
sndbuf->head[0].iov_base = (void *)task->tk_buffer;
@@ -628,16 +626,23 @@
static void
call_transmit(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
-
dprintk("RPC: %4d call_transmit (status %d)\n",
task->tk_pid, task->tk_status);
task->tk_action = call_status;
if (task->tk_status < 0)
return;
+ task->tk_status = xprt_prepare_transmit(task);
+ if (task->tk_status < 0)
+ return;
+ /* Encode here so that rpcsec_gss can use correct sequence number. */
+ call_encode(task);
+ if (task->tk_status < 0)
+ return;
xprt_transmit(task);
- if (!task->tk_msg.xdr_decode && task->tk_status >= 0) {
+ if (task->tk_status < 0)
+ return;
+ if (!task->tk_msg.xdr_decode) {
task->tk_action = NULL;
rpc_wake_up_task(task);
}
@@ -777,7 +782,7 @@
if (RPC_IS_SETUID(task) && task->tk_suid_retry) {
dprintk("RPC: %4d retry squashed uid\n", task->tk_pid);
task->tk_flags ^= RPC_CALL_REALUID;
- task->tk_action = call_encode;
+ task->tk_action = call_bind;
task->tk_suid_retry--;
return;
}
@@ -883,7 +888,7 @@
task->tk_garb_retry--;
dprintk("RPC: %4d call_verify: retry garbled creds\n",
task->tk_pid);
- task->tk_action = call_encode;
+ task->tk_action = call_bind;
return NULL;
case RPC_AUTH_TOOWEAK:
printk(KERN_NOTICE "call_verify: server requires stronger "
@@ -918,7 +923,7 @@
if (task->tk_garb_retry) {
task->tk_garb_retry--;
dprintk(KERN_WARNING "RPC: garbage, retrying %4d\n", task->tk_pid);
- task->tk_action = call_encode;
+ task->tk_action = call_bind;
return NULL;
}
printk(KERN_WARNING "RPC: garbage, exit EIO\n");
diff -u --recursive --new-file linux-2.5.44-01-rpc_msg/net/sunrpc/xprt.c linux-2.5.44-02-rpc_encode/net/sunrpc/xprt.c
--- linux-2.5.44-01-rpc_msg/net/sunrpc/xprt.c 2002-10-08 07:06:15.000000000 -0400
+++ linux-2.5.44-02-rpc_encode/net/sunrpc/xprt.c 2002-10-28 17:29:21.000000000 -0500
@@ -83,7 +83,6 @@
* Local functions
*/
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
-static void do_xprt_transmit(struct rpc_task *);
static inline void do_xprt_reserve(struct rpc_task *);
static void xprt_disconnect(struct rpc_xprt *);
static void xprt_conn_status(struct rpc_task *task);
@@ -1090,51 +1089,40 @@
* Place the actual RPC call.
* We have to copy the iovec because sendmsg fiddles with its contents.
*/
-void
-xprt_transmit(struct rpc_task *task)
+int
+xprt_prepare_transmit(struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
+ int err = 0;
- dprintk("RPC: %4d xprt_transmit(%x)\n", task->tk_pid,
- *(u32 *)(req->rq_svec[0].iov_base));
+ dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid);
if (xprt->shutdown)
- task->tk_status = -EIO;
+ return -EIO;
if (!xprt_connected(xprt))
- task->tk_status = -ENOTCONN;
-
- if (task->tk_status < 0)
- return;
+ return -ENOTCONN;
if (task->tk_rpcwait)
rpc_remove_wait_queue(task);
- /* set up everything as needed. */
- /* Write the record marker */
- if (xprt->stream) {
- u32 *marker = req->rq_svec[0].iov_base;
-
- *marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
- }
-
spin_lock_bh(&xprt->sock_lock);
if (!__xprt_lock_write(xprt, task)) {
- spin_unlock_bh(&xprt->sock_lock);
- return;
+ err = -EAGAIN;
+ goto out_unlock;
}
if (list_empty(&req->rq_list)) {
list_add_tail(&req->rq_list, &xprt->recv);
req->rq_received = 0;
}
+out_unlock:
spin_unlock_bh(&xprt->sock_lock);
-
- do_xprt_transmit(task);
+ return err;
}
-static void
-do_xprt_transmit(struct rpc_task *task)
+void
+xprt_transmit(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
@@ -1142,6 +1130,16 @@
int status, retry = 0;
+ dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
+
+ /* set up everything as needed. */
+ /* Write the record marker */
+ if (xprt->stream) {
+ u32 *marker = req->rq_svec[0].iov_base;
+
+ *marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
+ }
+
/* Continue transmitting the packet/record. We must be careful
* to cope with writespace callbacks arriving _after_ we have
* called xprt_sendmsg().
-------------------------------------------------------
This sf.net email is sponsored by: Influence the future
of Java(TM) technology. Join the Java Community
Process(SM) (JCP(SM)) program now.
http://ads.sourceforge.net/cgi-bin/redirect.pl?sunm0004en
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs