]> code.ossystems Code Review - openembedded-core.git/blob
d444a0728a08f242f9a39b52488b78e57bb20c4b
[openembedded-core.git] /
1 From c1af5643e0df56b92481f7a7bc4110a58e4e5abb Mon Sep 17 00:00:00 2001
2 From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 Date: Fri, 21 Jul 2017 08:22:04 -0400
4 Subject: [PATCH 3/8] Fix: Sleeping function called from invalid context
5 Organization: O.S. Systems Software LTDA.
6
7 It affects system call instrumentation for accept, accept4 and connect,
8 only on the x86-64 architecture.
9
10 We need to use the LTTng accessing functions to touch user-space memory,
11 which take care of disabling the page fault handler, so we don't preempt
12 while in preempt-off context (tracepoints disable preemption).
13
14 Fixes #1111
15
16 Upstream-Status: Backport [2.9.4]
17
18 Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
19 ---
20  .../x86-64-syscalls-3.10.0-rc7_pointers_override.h | 47 ++++++++++++++--------
21  1 file changed, 31 insertions(+), 16 deletions(-)
22
23 diff --git a/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h b/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h
24 index 5e91004..6bf5291 100644
25 --- a/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h
26 +++ b/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h
27 @@ -2,7 +2,7 @@
28  
29  #define OVERRIDE_64_connect
30  SC_LTTNG_TRACEPOINT_EVENT_CODE(connect,
31 -       TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr * uservaddr, int addrlen),
32 +       TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr __user * uservaddr, int addrlen),
33         TP_ARGS(sc_exit(ret,) fd, uservaddr, addrlen),
34         TP_locvar(
35                 __typeof__(uservaddr->sa_family) sa_family;
36 @@ -16,21 +16,28 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(connect,
37                         memset(tp_locvar, 0, sizeof(*tp_locvar));
38                         if (addrlen < sizeof(tp_locvar->sa_family))
39                                 goto skip_code;
40 -                       (void) get_user(tp_locvar->sa_family, &uservaddr->sa_family);
41 +                       (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sa_family,
42 +                                       &uservaddr->sa_family, sizeof(tp_locvar->sa_family));
43                         switch (tp_locvar->sa_family) {
44                         case AF_INET:
45                                 if (addrlen < sizeof(struct sockaddr_in))
46                                         goto skip_code;
47 -                               (void) get_user(tp_locvar->dport, &((struct sockaddr_in *) uservaddr)->sin_port);
48 -                               (void) get_user(tp_locvar->v4addr, &((struct sockaddr_in *) uservaddr)->sin_addr.s_addr);
49 +                               (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->dport,
50 +                                               &((struct sockaddr_in __user *) uservaddr)->sin_port,
51 +                                               sizeof(tp_locvar->dport));
52 +                               (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->v4addr,
53 +                                               &((struct sockaddr_in __user *) uservaddr)->sin_addr.s_addr,
54 +                                               sizeof(tp_locvar->v4addr));
55                                 tp_locvar->v4addr_len = 4;
56                                 break;
57                         case AF_INET6:
58                                 if (addrlen < sizeof(struct sockaddr_in6))
59                                         goto skip_code;
60 -                               (void) get_user(tp_locvar->dport, &((struct sockaddr_in6 *) uservaddr)->sin6_port);
61 -                               if (copy_from_user(tp_locvar->v6addr,
62 -                                               &((struct sockaddr_in6 *) uservaddr)->sin6_addr.in6_u.u6_addr8,
63 +                               (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->dport,
64 +                                               &((struct sockaddr_in6 __user *) uservaddr)->sin6_port,
65 +                                               sizeof(tp_locvar->dport));
66 +                               if (lib_ring_buffer_copy_from_user_check_nofault(tp_locvar->v6addr,
67 +                                               &((struct sockaddr_in6 __user *) uservaddr)->sin6_addr.in6_u.u6_addr8,
68                                                 sizeof(tp_locvar->v6addr)))
69                                         memset(tp_locvar->v6addr, 0, sizeof(tp_locvar->v6addr));
70                                 tp_locvar->v6addr_len = 8;
71 @@ -63,26 +70,34 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(connect,
72  #define LTTNG_SYSCALL_ACCEPT_code_pre                                                                                  \
73         sc_inout(                                                                                                       \
74                 memset(tp_locvar, 0, sizeof(*tp_locvar));                                                               \
75 -               (void) get_user(tp_locvar->uaddr_len, upeer_addrlen);                                                   \
76 +               (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->uaddr_len,                              \
77 +                               upeer_addrlen, sizeof(tp_locvar->uaddr_len));                                           \
78         )                                                                                                               \
79         sc_out(                                                                                                         \
80                 if (tp_locvar->uaddr_len < sizeof(tp_locvar->sa_family))                                                \
81                         goto skip_code;                                                                                 \
82 -               (void) get_user(tp_locvar->sa_family, &upeer_sockaddr->sa_family);                                      \
83 +               (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sa_family,                              \
84 +                               &upeer_sockaddr->sa_family, sizeof(tp_locvar->sa_family));                              \
85                 switch (tp_locvar->sa_family) {                                                                         \
86                 case AF_INET:                                                                                           \
87                         if (tp_locvar->uaddr_len < sizeof(struct sockaddr_in))                                          \
88                                 goto skip_code;                                                                         \
89 -                       (void) get_user(tp_locvar->sport, &((struct sockaddr_in *) upeer_sockaddr)->sin_port);          \
90 -                       (void) get_user(tp_locvar->v4addr, &((struct sockaddr_in *) upeer_sockaddr)->sin_addr.s_addr);  \
91 +                       (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sport,                          \
92 +                                       &((struct sockaddr_in __user *) upeer_sockaddr)->sin_port,                      \
93 +                                       sizeof(tp_locvar->sport));                                                      \
94 +                       (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->v4addr,                         \
95 +                                       &((struct sockaddr_in __user *) upeer_sockaddr)->sin_addr.s_addr,               \
96 +                                       sizeof(tp_locvar->v4addr));                                                     \
97                         tp_locvar->v4addr_len = 4;                                                                      \
98                         break;                                                                                          \
99                 case AF_INET6:                                                                                          \
100                         if (tp_locvar->uaddr_len < sizeof(struct sockaddr_in6))                                         \
101                                 goto skip_code;                                                                         \
102 -                       (void) get_user(tp_locvar->sport, &((struct sockaddr_in6 *) upeer_sockaddr)->sin6_port);        \
103 -                       if (copy_from_user(tp_locvar->v6addr,                                                           \
104 -                                       &((struct sockaddr_in6 *) upeer_sockaddr)->sin6_addr.in6_u.u6_addr8,            \
105 +                       (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sport,                          \
106 +                                       &((struct sockaddr_in6 __user *) upeer_sockaddr)->sin6_port,                    \
107 +                                       sizeof(tp_locvar->sport));                                                      \
108 +                       if (lib_ring_buffer_copy_from_user_check_nofault(tp_locvar->v6addr,                             \
109 +                                       &((struct sockaddr_in6 __user *) upeer_sockaddr)->sin6_addr.in6_u.u6_addr8,     \
110                                         sizeof(tp_locvar->v6addr)))                                                     \
111                                 memset(tp_locvar->v6addr, 0, sizeof(tp_locvar->v6addr));                                \
112                         tp_locvar->v6addr_len = 8;                                                                      \
113 @@ -93,7 +108,7 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(connect,
114  
115  #define OVERRIDE_64_accept
116  SC_LTTNG_TRACEPOINT_EVENT_CODE(accept,
117 -       TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen),
118 +       TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr __user * upeer_sockaddr, int __user * upeer_addrlen),
119         TP_ARGS(sc_exit(ret,) fd, upeer_sockaddr, upeer_addrlen),
120         TP_locvar(
121                 LTTNG_SYSCALL_ACCEPT_locvar
122 @@ -116,7 +131,7 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(accept,
123  
124  #define OVERRIDE_64_accept4
125  SC_LTTNG_TRACEPOINT_EVENT_CODE(accept4,
126 -       TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen, int flags),
127 +       TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr __user * upeer_sockaddr, int __user * upeer_addrlen, int flags),
128         TP_ARGS(sc_exit(ret,) fd, upeer_sockaddr, upeer_addrlen, flags),
129         TP_locvar(
130                 LTTNG_SYSCALL_ACCEPT_locvar
131 -- 
132 2.14.1
133