diff options
author | Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | 2013-09-11 17:23:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-11 18:58:18 -0400 |
commit | 3ddc5b46a8e90f3c9251338b60191d0a804b0d92 (patch) | |
tree | 5c76cd730cb94e75f30953d6cd1aed9386fcee37 /arch/sparc | |
parent | 20d0e57017b69e7e4ae7166c43f3a3f023ab9702 (diff) |
kernel-wide: fix missing validations on __get/__put/__copy_to/__copy_from_user()
I found the following pattern that leads in to interesting findings:
grep -r "ret.*|=.*__put_user" *
grep -r "ret.*|=.*__get_user" *
grep -r "ret.*|=.*__copy" *
The __put_user() calls in compat_ioctl.c, ptrace compat, signal compat,
since those appear in compat code, we could probably expect the kernel
addresses not to be reachable in the lower 32-bit range, so I think they
might not be exploitable.
For the "__get_user" cases, I don't think those are exploitable: the worse
that can happen is that the kernel will copy kernel memory into in-kernel
buffers, and will fail immediately afterward.
The alpha csum_partial_copy_from_user() seems to be missing the
access_ok() check entirely. The fix is inspired from x86. This could
lead to information leak on alpha. I also noticed that many architectures
map csum_partial_copy_from_user() to csum_partial_copy_generic(), but I
wonder if the latter is performing the access checks on every
architectures.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/kernel/sys_sparc32.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 3d0ddbc005fe..71368850dfc0 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
@@ -169,10 +169,10 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, | |||
169 | new_ka.ka_restorer = restorer; | 169 | new_ka.ka_restorer = restorer; |
170 | ret = get_user(u_handler, &act->sa_handler); | 170 | ret = get_user(u_handler, &act->sa_handler); |
171 | new_ka.sa.sa_handler = compat_ptr(u_handler); | 171 | new_ka.sa.sa_handler = compat_ptr(u_handler); |
172 | ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); | 172 | ret |= copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); |
173 | sigset_from_compat(&new_ka.sa.sa_mask, &set32); | 173 | sigset_from_compat(&new_ka.sa.sa_mask, &set32); |
174 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); | 174 | ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags); |
175 | ret |= __get_user(u_restorer, &act->sa_restorer); | 175 | ret |= get_user(u_restorer, &act->sa_restorer); |
176 | new_ka.sa.sa_restorer = compat_ptr(u_restorer); | 176 | new_ka.sa.sa_restorer = compat_ptr(u_restorer); |
177 | if (ret) | 177 | if (ret) |
178 | return -EFAULT; | 178 | return -EFAULT; |
@@ -183,9 +183,9 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, | |||
183 | if (!ret && oact) { | 183 | if (!ret && oact) { |
184 | sigset_to_compat(&set32, &old_ka.sa.sa_mask); | 184 | sigset_to_compat(&set32, &old_ka.sa.sa_mask); |
185 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); | 185 | ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); |
186 | ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); | 186 | ret |= copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); |
187 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | 187 | ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); |
188 | ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer); | 188 | ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer); |
189 | if (ret) | 189 | if (ret) |
190 | ret = -EFAULT; | 190 | ret = -EFAULT; |
191 | } | 191 | } |