Mitigate DOS with large argument lists.
This commit is contained in:
parent
a1aa854d8c
commit
f63cfaf93a
|
@ -0,0 +1,36 @@
|
|||
From: Roland McGrath <roland@redhat.com>
|
||||
Date: Wed, 8 Sep 2010 02:36:28 +0000 (-0700)
|
||||
Subject: execve: improve interactivity with large arguments
|
||||
X-Git-Tag: v2.6.36-rc4~13
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7993bc1f4663c0db67bb8f0d98e6678145b387cd
|
||||
|
||||
execve: improve interactivity with large arguments
|
||||
|
||||
This adds a preemption point during the copying of the argument and
|
||||
environment strings for execve, in copy_strings(). There is already
|
||||
a preemption point in the count() loop, so this doesn't add any new
|
||||
points in the abstract sense.
|
||||
|
||||
When the total argument+environment strings are very large, the time
|
||||
spent copying them can be much more than a normal user time slice.
|
||||
So this change improves the interactivity of the rest of the system
|
||||
when one process is doing an execve with very large arguments.
|
||||
|
||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 1b63237..6f2d777 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -419,6 +419,8 @@ static int copy_strings(int argc, const char __user *const __user *argv,
|
||||
while (len > 0) {
|
||||
int offset, bytes_to_copy;
|
||||
|
||||
+ cond_resched();
|
||||
+
|
||||
offset = pos % PAGE_SIZE;
|
||||
if (offset == 0)
|
||||
offset = PAGE_SIZE;
|
|
@ -0,0 +1,51 @@
|
|||
From: Roland McGrath <roland@redhat.com>
|
||||
Date: Wed, 8 Sep 2010 02:37:06 +0000 (-0700)
|
||||
Subject: execve: make responsive to SIGKILL with large arguments
|
||||
X-Git-Tag: v2.6.36-rc4~12
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9aea5a65aa7a1af9a4236dfaeb0088f1624f9919
|
||||
|
||||
execve: make responsive to SIGKILL with large arguments
|
||||
|
||||
An execve with a very large total of argument/environment strings
|
||||
can take a really long time in the execve system call. It runs
|
||||
uninterruptibly to count and copy all the strings. This change
|
||||
makes it abort the exec quickly if sent a SIGKILL.
|
||||
|
||||
Note that this is the conservative change, to interrupt only for
|
||||
SIGKILL, by using fatal_signal_pending(). It would be perfectly
|
||||
correct semantics to let any signal interrupt the string-copying in
|
||||
execve, i.e. use signal_pending() instead of fatal_signal_pending().
|
||||
We'll save that change for later, since it could have user-visible
|
||||
consequences, such as having a timer set too quickly make it so that
|
||||
an execve can never complete, though it always happened to work before.
|
||||
|
||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 6f2d777..828dd24 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -376,6 +376,9 @@ static int count(const char __user * const __user * argv, int max)
|
||||
argv++;
|
||||
if (i++ >= max)
|
||||
return -E2BIG;
|
||||
+
|
||||
+ if (fatal_signal_pending(current))
|
||||
+ return -ERESTARTNOHAND;
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
@@ -419,6 +422,10 @@ static int copy_strings(int argc, const char __user *const __user *argv,
|
||||
while (len > 0) {
|
||||
int offset, bytes_to_copy;
|
||||
|
||||
+ if (fatal_signal_pending(current)) {
|
||||
+ ret = -ERESTARTNOHAND;
|
||||
+ goto out;
|
||||
+ }
|
||||
cond_resched();
|
||||
|
||||
offset = pos % PAGE_SIZE;
|
17
kernel.spec
17
kernel.spec
|
@ -794,6 +794,11 @@ Patch12530: pci-msi-remove-unsafe-and-unnecessary-hardware-access.patch
|
|||
Patch12531: pci-msi-restore-read_msi_msg_desc-add-get_cached_msi_msg_desc.patch
|
||||
Patch12532: x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
|
||||
|
||||
# Mitigate DOS with large argument lists.
|
||||
Patch12540: execve-improve-interactivity-with-large-arguments.patch
|
||||
Patch12541: execve-make-responsive-to-sigkill-with-large-arguments.patch
|
||||
Patch12542: setup_arg_pages-diagnose-excessive-argument-size.patch
|
||||
|
||||
%endif
|
||||
|
||||
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
|
||||
|
@ -1498,6 +1503,11 @@ ApplyPatch pci-msi-restore-read_msi_msg_desc-add-get_cached_msi_msg_desc.patch
|
|||
# Fix scheduler load balancing after suspend/resume cycle
|
||||
ApplyPatch x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
|
||||
|
||||
# Mitigate DOS with large argument lists.
|
||||
ApplyPatch execve-improve-interactivity-with-large-arguments.patch
|
||||
ApplyPatch execve-make-responsive-to-sigkill-with-large-arguments.patch
|
||||
ApplyPatch setup_arg_pages-diagnose-excessive-argument-size.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
|
@ -2119,10 +2129,13 @@ fi
|
|||
|
||||
|
||||
%changelog
|
||||
* Tue Sep 14 2010 Kyle McMartin <kyle@redhat.com> 2.6.34.7-57
|
||||
* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.34.7-57
|
||||
- Mitigate DOS with large argument lists.
|
||||
|
||||
* Tue Sep 14 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- x86_64: plug compat syscalls holes. (CVE-2010-3081, CVE-2010-3301)
|
||||
upgrading is highly recommended.
|
||||
- aio: check for multiplication overflow in do_io_submit.
|
||||
- aio: check for multiplication overflow in do_io_submit. (CVE-2010-3067)
|
||||
|
||||
* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.34.7-56
|
||||
- Linux 2.6.34.7
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
From: Roland McGrath <roland@redhat.com>
|
||||
Date: Wed, 8 Sep 2010 02:35:49 +0000 (-0700)
|
||||
Subject: setup_arg_pages: diagnose excessive argument size
|
||||
X-Git-Tag: v2.6.36-rc4~14
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=1b528181b2ffa14721fb28ad1bd539fe1732c583
|
||||
|
||||
setup_arg_pages: diagnose excessive argument size
|
||||
|
||||
The CONFIG_STACK_GROWSDOWN variant of setup_arg_pages() does not
|
||||
check the size of the argument/environment area on the stack.
|
||||
When it is unworkably large, shift_arg_pages() hits its BUG_ON.
|
||||
This is exploitable with a very large RLIMIT_STACK limit, to
|
||||
create a crash pretty easily.
|
||||
|
||||
Check that the initial stack is not too large to make it possible
|
||||
to map in any executable. We're not checking that the actual
|
||||
executable (or intepreter, for binfmt_elf) will fit. So those
|
||||
mappings might clobber part of the initial stack mapping. But
|
||||
that is just userland lossage that userland made happen, not a
|
||||
kernel problem.
|
||||
|
||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 2d94552..1b63237 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -594,6 +594,11 @@ int setup_arg_pages(struct linux_binprm *bprm,
|
||||
#else
|
||||
stack_top = arch_align_stack(stack_top);
|
||||
stack_top = PAGE_ALIGN(stack_top);
|
||||
+
|
||||
+ if (unlikely(stack_top < mmap_min_addr) ||
|
||||
+ unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
stack_shift = vma->vm_end - stack_top;
|
||||
|
||||
bprm->p -= stack_shift;
|
Loading…
Reference in New Issue