You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.7 KiB
168 lines
5.7 KiB
diff -up nfs-utils-1.3.0/support/include/nfslib.h.orig nfs-utils-1.3.0/support/include/nfslib.h |
|
--- nfs-utils-1.3.0/support/include/nfslib.h.orig 2014-03-25 11:12:07.000000000 -0400 |
|
+++ nfs-utils-1.3.0/support/include/nfslib.h 2014-11-14 11:16:06.785633197 -0500 |
|
@@ -174,6 +174,7 @@ void closeall(int min); |
|
|
|
int svctcp_socket (u_long __number, int __reuse); |
|
int svcudp_socket (u_long __number); |
|
+int svcsock_nonblock (int __sock); |
|
|
|
/* Misc shared code prototypes */ |
|
size_t strlcat(char *, const char *, size_t); |
|
diff -up nfs-utils-1.3.0/support/nfs/rpcmisc.c.orig nfs-utils-1.3.0/support/nfs/rpcmisc.c |
|
--- nfs-utils-1.3.0/support/nfs/rpcmisc.c.orig 2014-03-25 11:12:07.000000000 -0400 |
|
+++ nfs-utils-1.3.0/support/nfs/rpcmisc.c 2014-11-14 11:16:06.785633197 -0500 |
|
@@ -104,7 +104,7 @@ makesock(int port, int proto) |
|
return -1; |
|
} |
|
|
|
- return sock; |
|
+ return svcsock_nonblock(sock); |
|
} |
|
|
|
void |
|
diff -up nfs-utils-1.3.0/support/nfs/svc_create.c.orig nfs-utils-1.3.0/support/nfs/svc_create.c |
|
--- nfs-utils-1.3.0/support/nfs/svc_create.c.orig 2014-03-25 11:12:07.000000000 -0400 |
|
+++ nfs-utils-1.3.0/support/nfs/svc_create.c 2014-11-14 11:16:06.785633197 -0500 |
|
@@ -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, }; |
|
|
|
@@ -277,6 +279,12 @@ svc_create_nconf_rand_port(const char *n |
|
"(%s, %u, %s)", name, version, nconf->nc_netid); |
|
return 0; |
|
} |
|
+ if (svcsock_nonblock(xprt->xp_fd) < 0) { |
|
+ /* close() already done by svcsock_nonblock() */ |
|
+ xprt->xp_fd = RPC_ANYFD; |
|
+ SVC_DESTROY(xprt); |
|
+ return 0; |
|
+ } |
|
|
|
if (!svc_reg(xprt, program, version, dispatch, nconf)) { |
|
/* svc_reg(3) destroys @xprt in this case */ |
|
@@ -332,6 +340,7 @@ svc_create_nconf_fixed_port(const char * |
|
int fd; |
|
|
|
fd = svc_create_sock(ai->ai_addr, ai->ai_addrlen, nconf); |
|
+ fd = svcsock_nonblock(fd); |
|
if (fd == -1) |
|
goto out_free; |
|
|
|
@@ -394,6 +403,7 @@ nfs_svc_create(char *name, const rpcprog |
|
const struct sigaction create_sigaction = { |
|
.sa_handler = SIG_IGN, |
|
}; |
|
+ int maxrec = RPC_MAXDATASIZE; |
|
unsigned int visible, up, servport; |
|
struct netconfig *nconf; |
|
void *handlep; |
|
@@ -405,6 +415,20 @@ nfs_svc_create(char *name, const rpcprog |
|
*/ |
|
(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", |
|
diff -up nfs-utils-1.3.0/support/nfs/svc_socket.c.orig nfs-utils-1.3.0/support/nfs/svc_socket.c |
|
--- nfs-utils-1.3.0/support/nfs/svc_socket.c.orig 2014-03-25 11:12:07.000000000 -0400 |
|
+++ nfs-utils-1.3.0/support/nfs/svc_socket.c 2014-11-14 11:16:06.785633197 -0500 |
|
@@ -67,6 +67,39 @@ int getservport(u_long number, const cha |
|
return 0; |
|
} |
|
|
|
+int |
|
+svcsock_nonblock(int sock) |
|
+{ |
|
+ int flags; |
|
+ |
|
+ if (sock < 0) |
|
+ return sock; |
|
+ |
|
+ /* This socket might be shared among multiple processes |
|
+ * if mountd is run multi-threaded. So it is safest to |
|
+ * make it non-blocking, else all threads might wake |
|
+ * one will get the data, and the others will block |
|
+ * indefinitely. |
|
+ * In all cases, transaction on this socket are atomic |
|
+ * (accept for TCP, packet-read and packet-write for UDP) |
|
+ * so O_NONBLOCK will not confuse unprepared code causing |
|
+ * it to corrupt messages. |
|
+ * It generally safest to have O_NONBLOCK when doing an accept |
|
+ * as if we get a RST after the SYN and before accept runs, |
|
+ * we can block despite being told there was an acceptable |
|
+ * connection. |
|
+ */ |
|
+ if ((flags = fcntl(sock, F_GETFL)) < 0) |
|
+ perror(_("svc_socket: can't get socket flags")); |
|
+ else if (fcntl(sock, F_SETFL, flags|O_NONBLOCK) < 0) |
|
+ perror(_("svc_socket: can't set socket flags")); |
|
+ else |
|
+ return sock; |
|
+ |
|
+ (void) __close(sock); |
|
+ return -1; |
|
+} |
|
+ |
|
static int |
|
svc_socket (u_long number, int type, int protocol, int reuse) |
|
{ |
|
@@ -104,38 +137,7 @@ svc_socket (u_long number, int type, int |
|
sock = -1; |
|
} |
|
|
|
- if (sock >= 0) |
|
- { |
|
- /* This socket might be shared among multiple processes |
|
- * if mountd is run multi-threaded. So it is safest to |
|
- * make it non-blocking, else all threads might wake |
|
- * one will get the data, and the others will block |
|
- * indefinitely. |
|
- * In all cases, transaction on this socket are atomic |
|
- * (accept for TCP, packet-read and packet-write for UDP) |
|
- * so O_NONBLOCK will not confuse unprepared code causing |
|
- * it to corrupt messages. |
|
- * It generally safest to have O_NONBLOCK when doing an accept |
|
- * as if we get a RST after the SYN and before accept runs, |
|
- * we can block despite being told there was an acceptable |
|
- * connection. |
|
- */ |
|
- int flags; |
|
- if ((flags = fcntl(sock, F_GETFL)) < 0) |
|
- { |
|
- perror (_("svc_socket: can't get socket flags")); |
|
- (void) __close (sock); |
|
- sock = -1; |
|
- } |
|
- else if (fcntl(sock, F_SETFL, flags|O_NONBLOCK) < 0) |
|
- { |
|
- perror (_("svc_socket: can't set socket flags")); |
|
- (void) __close (sock); |
|
- sock = -1; |
|
- } |
|
- } |
|
- |
|
- return sock; |
|
+ return svcsock_nonblock(sock); |
|
} |
|
|
|
/*
|
|
|