[RFC v3 1/5] introduce config RUNTIME_USER_COPY_CHECK

From: Vasiliy Kulikov
Date: Thu Jul 21 2011 - 08:53:45 EST

RUNTIME_USER_COPY_CHECK defines a set of checks length parameter of
usercopy functions. Currently there are some very simple and cheap
comparisons of supplied size and the size of a copied object known at
the compile time in copy_* functions. This patch enhances these checks
to check against stack frame boundaries and against SL*B object sizes.
The option does nothing with other memory areas like vmalloc'ed areas,
modules' data and code sections, etc. It can be an area for

The slowdown is negligible - for most cases it is reduced to integer
comparison (in fstat, getrlimit, ipc) for some cases the whole syscall
time and the time of a check are not comparable (in write, path
traversal functions - openat, stat), for programs with not intensive
syscalls usage. One of the most significant slowdowns is gethostname(),
the penalty is 0,9%. For 'find /usr', 'git log -Sredirect' in kernel
tree, kernel compilation the slowdown is less than 0,1% (couldn't
measure it more precisely). However, as a buffer overflow may be not a
threat and/or even such slowdown may be not acceptable, the check can be
disabled via config option.

The option is a forward-port of the PAX_USERCOPY feature from the PaX
patch. Most code was copied from the PaX patch with minor cosmetic
changes. Also PaX' version of the patch has additional restrictions:

a) some slab caches has SLAB_USERCOPY flag set and copies to/from the
slab caches without the flag are denied. Rare cases where some bytes
needed from the caches missing in the white list are handled by copying
the bytes into temporary area on the stack/heap.

b) if a malformed copy request is spotted, the event is logged and
SIGKILL signal is sent to the current task.

Examples of overflows, which become non-exploitable with RUNTIME_USER_COPY_CHECK:
DCCP getsockopt copy_to_user() overflow (fixed in 39ebc0276bada),
L2TP memcpy_fromiovec() overflow (fixed in 253eacc070b),
64kb iwconfig infoleak (fixed in 42da2f948d, was found by PAX_USERCOPY).

Signed-off-by: Vasiliy Kulikov <segoon@xxxxxxxxxxxx>
lib/Kconfig.debug | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index dd373c8..ed266b6 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -679,6 +679,28 @@ config DEBUG_STACK_USAGE

This option will slow down process creation somewhat.

+ bool "Runtime usercopy size checks"
+ default n
+ depends on DEBUG_KERNEL && X86
+ ---help---
+ Enabling this option adds additional runtime checks into copy_from_user()
+ and similar functions.
+ Specifically, if the data touches the stack, it checks whether a copied
+ memory chunk fully fits in the stack. If CONFIG_FRAME_POINTER=y, also
+ checks whether it fully fits in a single stack frame. It limits
+ infoleaks/overwrites to a single frame and local variables
+ only, and prevents saved return instruction pointer overwriting.
+ If the data is from the SL*B cache, checks whether it fully fits in a
+ slab page and whether it overflows a slab object. E.g. if the memory
+ was allocated as kmalloc(64, GFP_KERNEL) and one tries to copy 150
+ bytes, the copy would fail.
+ The option has a minimal performance drawback (up to 1% on tiny syscalls
+ like gethostname).
bool "kobject debugging"
depends on DEBUG_KERNEL
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/