diff options
author | Bodo Stroesser <bstroesser@ts.fujitsu.com> | 2014-11-12 09:43:29 -0500 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2014-11-12 13:46:59 -0500 |
commit | e4569a0961ff9f059b9ae71327d291cf95399597 (patch) | |
tree | 294e024037fcf031dbb295b928787500a25c78d7 | |
parent | aba23f36c4dbc22d0d6d4afe6896bc5bf7f1caa6 (diff) | |
download | nfs-utils-e4569a0961ff9f059b9ae71327d291cf95399597.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.c | 17 |
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", |