summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBodo Stroesser <bstroesser@ts.fujitsu.com>2014-11-12 09:43:29 -0500
committerSteve Dickson <steved@redhat.com>2014-11-12 13:46:59 -0500
commite4569a0961ff9f059b9ae71327d291cf95399597 (patch)
tree294e024037fcf031dbb295b928787500a25c78d7
parentaba23f36c4dbc22d0d6d4afe6896bc5bf7f1caa6 (diff)
downloadnfs-utils-1-3-2-rc2.tar.gz
rpc.mountd: set libtirpc nonblocking mode to avoid DOSnfs-utils-1-3-2-rc2
This patch is experimental. In works fine in that it removes the vulnerability against a DOS attack. rpc.mountd can be blocked by a bad client, that sends many RPC requests but never reads the responses. This might happen intentionally or caused by a wrong network config (MTU). The patch switches on the nonblocking mode of libtirpc. In that mode writes can block for a max of 2 seconds. Attackers are forced to send requests slower, as libtirpc will close a connection if it finds two requests to read at the same time. Reviewed-by: NeilBrown <neilb@suse.de> Signed-off-by: Bodo Stroesser <bstroesser@ts.fujitsu.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--support/nfs/svc_create.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/support/nfs/svc_create.c b/support/nfs/svc_create.c
index 5291921..5cb5ff6 100644
--- a/support/nfs/svc_create.c
+++ b/support/nfs/svc_create.c
@@ -49,6 +49,8 @@
#ifdef HAVE_LIBTIRPC
+#include <rpc/rpc_com.h>
+
#define SVC_CREATE_XPRT_CACHE_SIZE (8)
static SVCXPRT *svc_create_xprt_cache[SVC_CREATE_XPRT_CACHE_SIZE] = { NULL, };
@@ -401,6 +403,7 @@ nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
const struct sigaction create_sigaction = {
.sa_handler = SIG_IGN,
};
+ int maxrec = RPC_MAXDATASIZE;
unsigned int visible, up, servport;
struct netconfig *nconf;
void *handlep;
@@ -412,6 +415,20 @@ nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
*/
(void)sigaction(SIGPIPE, &create_sigaction, NULL);
+ /*
+ * Setting MAXREC also enables non-blocking mode for tcp connections.
+ * This avoids DOS attacks by a client sending many requests but never
+ * reading the reply:
+ * - if a second request already is present for reading in the socket,
+ * after the first request just was read, libtirpc will break the
+ * connection. Thus an attacker can't simply send requests as fast as
+ * he can without waiting for the response.
+ * - if the write buffer of the socket is full, the next write() will
+ * fail with EAGAIN. libtirpc will retry the write in a loop for max.
+ * 2 seconds. If write still fails, the connection will be closed.
+ */
+ rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
+
handlep = setnetconfig();
if (handlep == NULL) {
xlog(L_ERROR, "Failed to access local netconfig database: %s",