Fix: ctf_user_integer should not trigger page fault
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 20 Apr 2016 21:58:33 +0000 (17:58 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 20 Apr 2016 22:19:58 +0000 (18:19 -0400)
It is not used by the instrumentation currently, but fix it
nevertheless.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/ringbuffer/backend.h
probes/lttng-tracepoint-event-impl.h

index b908ed06e92665e127bac42e19d57ffbb7ec9670..8f6d7d04d8a8ed76d86ed694c44e1864cc05d509 100644 (file)
@@ -478,4 +478,29 @@ unsigned long lib_ring_buffer_get_records_unread(
        return records_unread;
 }
 
+/*
+ * We use __copy_from_user_inatomic to copy userspace data after
+ * checking with access_ok() and disabling page faults.
+ *
+ * Return 0 if OK, nonzero on error.
+ */
+static inline
+unsigned long lib_ring_buffer_copy_from_user_check_nofault(void *dest,
+                                               const void __user *src,
+                                               unsigned long len)
+{
+       unsigned long ret;
+       mm_segment_t old_fs;
+
+       if (!access_ok(VERIFY_READ, src, len))
+               return 1;
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       pagefault_disable();
+       ret = __copy_from_user_inatomic(dest, src, len);
+       pagefault_enable();
+       set_fs(old_fs);
+       return ret;
+}
+
 #endif /* _LIB_RING_BUFFER_BACKEND_H */
index f774dff5594c6fb8998b808fdd3bfe851908d63b..a87d146af23e701349f5fa259f4fe0b823ae2168 100644 (file)
@@ -29,6 +29,7 @@
 #include <probes/lttng-probe-user.h>
 #include <wrapper/vmalloc.h>   /* for wrapper_vmalloc_sync_all() */
 #include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/ringbuffer/backend.h>
 #include <wrapper/rcu.h>
 #include <lttng-events.h>
 #include <lttng-tracer-core.h>
@@ -515,11 +516,15 @@ static inline size_t __event_get_size__##_name(size_t *__dynamic_len,           \
 
 #undef _ctf_integer_ext_isuser1
 #define _ctf_integer_ext_isuser1(_type, _item, _user_src, _byte_order, _base, _nowrite) \
-{                                                                             \
-       __typeof__(_user_src) _src;                                            \
-       if (get_user(_src, &(_user_src)))                                      \
-               _src = 0;                                                      \
-       _ctf_integer_ext_fetched(_type, _item, _src, _byte_order, _base, _nowrite) \
+{                                                                                      \
+       union {                                                                         \
+               char __array[sizeof(_user_src)];                                        \
+               __typeof__(_user_src) __v;                                              \
+       } __tmp_fetch;                                                                  \
+       if (lib_ring_buffer_copy_from_user_check_nofault(__tmp_fetch.__array,           \
+                               &(_user_src), sizeof(_user_src)))                       \
+               memset(__tmp_fetch.__array, 0, sizeof(__tmp_fetch.__array));            \
+       _ctf_integer_ext_fetched(_type, _item, __tmp_fetch.__v, _byte_order, _base, _nowrite) \
 }
 
 #undef _ctf_integer_ext
@@ -698,10 +703,14 @@ static inline size_t __event_get_align__##_name(void *__tp_locvar)              \
 #undef _ctf_integer_ext_isuser1
 #define _ctf_integer_ext_isuser1(_type, _item, _user_src, _byte_order, _base, _nowrite) \
 {                                                                             \
-       __typeof__(_user_src) _src;                                            \
-       if (get_user(_src, &(_user_src)))                                      \
-               _src = 0;                                                      \
-       _ctf_integer_ext_fetched(_type, _item, _src, _byte_order, _base, _nowrite) \
+       union {                                                                         \
+               char __array[sizeof(_user_src)];                                        \
+               __typeof__(_user_src) __v;                                              \
+       } __tmp_fetch;                                                                  \
+       if (lib_ring_buffer_copy_from_user_check_nofault(__tmp_fetch.__array,           \
+                               &(_user_src), sizeof(_user_src)))                       \
+               memset(__tmp_fetch.__array, 0, sizeof(__tmp_fetch.__array));            \
+       _ctf_integer_ext_fetched(_type, _item, __tmp_fetch.__v, _byte_order, _base, _nowrite) \
 }
 
 #undef _ctf_integer_ext
This page took 0.027958 seconds and 4 git commands to generate.