summaryrefslogtreecommitdiffstats
path: root/vsftpd/10-remote-dos.patch
diff options
context:
space:
mode:
Diffstat (limited to 'vsftpd/10-remote-dos.patch')
-rw-r--r--vsftpd/10-remote-dos.patch69
1 files changed, 69 insertions, 0 deletions
diff --git a/vsftpd/10-remote-dos.patch b/vsftpd/10-remote-dos.patch
new file mode 100644
index 0000000000..fee3ebe3ef
--- /dev/null
+++ b/vsftpd/10-remote-dos.patch
@@ -0,0 +1,69 @@
1Author: Ben Hutchings <ben@decadent.org.uk>
2Description: Remote DoS on Linux 2.6.32 (Closes: #629373).
3
4diff -Naurp vsftpd.orig/sysdeputil.c vsftpd/sysdeputil.c
5--- vsftpd.orig/sysdeputil.c 2010-03-26 04:25:33.000000000 +0100
6+++ vsftpd/sysdeputil.c 2011-09-05 15:16:05.347070790 +0200
7@@ -25,6 +25,11 @@
8 #define _LARGEFILE64_SOURCE 1
9 #endif
10
11+#ifdef __linux__
12+ #include <stdio.h>
13+ #include <sys/utsname.h>
14+#endif
15+
16 /* For INT_MAX */
17 #include <limits.h>
18
19@@ -1259,11 +1264,36 @@ vsf_set_term_if_parent_dies()
20 #endif
21 }
22
23+#ifdef VSF_SYSDEP_HAVE_LINUX_CLONE
24+/* On Linux versions <2.6.35, netns cleanup may be so slow that
25+ * creating a netns per connection allows a remote denial-of-service.
26+ * We therefore do not use CLONE_NEWNET on these versions.
27+ */
28+static int
29+vsf_sysutil_netns_cleanup_is_fast(void)
30+{
31+#ifdef __linux__
32+ struct utsname utsname;
33+ int r1, r2, r3 = 0;
34+ return (uname(&utsname) == 0 &&
35+ sscanf(utsname.release, "%d.%d.%d", &r1, &r2, &r3) >= 2 &&
36+ ((r1 << 16) | (r2 << 8) | r3) >= ((2 << 16) | (6 << 8) | 35));
37+#else
38+ /* Assume any other kernel that has the feature don't have this problem */
39+ return 1;
40+#endif
41+}
42+#endif
43+
44 int
45 vsf_sysutil_fork_isolate_all_failok()
46 {
47 #ifdef VSF_SYSDEP_HAVE_LINUX_CLONE
48- static int cloneflags_work = 1;
49+ static int cloneflags_work = -1;
50+ if (cloneflags_work < 0)
51+ {
52+ cloneflags_work = vsf_sysutil_netns_cleanup_is_fast();
53+ }
54 if (cloneflags_work)
55 {
56 int ret = syscall(__NR_clone,
57@@ -1309,7 +1339,11 @@ int
58 vsf_sysutil_fork_newnet()
59 {
60 #ifdef VSF_SYSDEP_HAVE_LINUX_CLONE
61- static int cloneflags_work = 1;
62+ static int cloneflags_work = -1;
63+ if (cloneflags_work < 0)
64+ {
65+ cloneflags_work = vsf_sysutil_netns_cleanup_is_fast();
66+ }
67 if (cloneflags_work)
68 {
69 int ret = syscall(__NR_clone, CLONE_NEWNET | SIGCHLD, NULL);