]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.130/tracing-silence-gcc-9-array-bounds-warning.patch
Linux 4.14.130
[thirdparty/kernel/stable-queue.git] / releases / 4.14.130 / tracing-silence-gcc-9-array-bounds-warning.patch
1 From 0c97bf863efce63d6ab7971dad811601e6171d2f Mon Sep 17 00:00:00 2001
2 From: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
3 Date: Thu, 23 May 2019 14:45:35 +0200
4 Subject: tracing: Silence GCC 9 array bounds warning
5
6 From: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
7
8 commit 0c97bf863efce63d6ab7971dad811601e6171d2f upstream.
9
10 Starting with GCC 9, -Warray-bounds detects cases when memset is called
11 starting on a member of a struct but the size to be cleared ends up
12 writing over further members.
13
14 Such a call happens in the trace code to clear, at once, all members
15 after and including `seq` on struct trace_iterator:
16
17 In function 'memset',
18 inlined from 'ftrace_dump' at kernel/trace/trace.c:8914:3:
19 ./include/linux/string.h:344:9: warning: '__builtin_memset' offset
20 [8505, 8560] from the object at 'iter' is out of the bounds of
21 referenced subobject 'seq' with type 'struct trace_seq' at offset
22 4368 [-Warray-bounds]
23 344 | return __builtin_memset(p, c, size);
24 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
26 In order to avoid GCC complaining about it, we compute the address
27 ourselves by adding the offsetof distance instead of referring
28 directly to the member.
29
30 Since there are two places doing this clear (trace.c and trace_kdb.c),
31 take the chance to move the workaround into a single place in
32 the internal header.
33
34 Link: http://lkml.kernel.org/r/20190523124535.GA12931@gmail.com
35
36 Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
37 [ Removed unnecessary parenthesis around "iter" ]
38 Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
39 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
40
41 ---
42 kernel/trace/trace.c | 6 +-----
43 kernel/trace/trace.h | 18 ++++++++++++++++++
44 kernel/trace/trace_kdb.c | 6 +-----
45 3 files changed, 20 insertions(+), 10 deletions(-)
46
47 --- a/kernel/trace/trace.c
48 +++ b/kernel/trace/trace.c
49 @@ -8249,12 +8249,8 @@ void ftrace_dump(enum ftrace_dump_mode o
50
51 cnt++;
52
53 - /* reset all but tr, trace, and overruns */
54 - memset(&iter.seq, 0,
55 - sizeof(struct trace_iterator) -
56 - offsetof(struct trace_iterator, seq));
57 + trace_iterator_reset(&iter);
58 iter.iter_flags |= TRACE_FILE_LAT_FMT;
59 - iter.pos = -1;
60
61 if (trace_find_next_entry_inc(&iter) != NULL) {
62 int ret;
63 --- a/kernel/trace/trace.h
64 +++ b/kernel/trace/trace.h
65 @@ -1871,4 +1871,22 @@ static inline int tracing_alloc_snapshot
66
67 extern struct trace_iterator *tracepoint_print_iter;
68
69 +/*
70 + * Reset the state of the trace_iterator so that it can read consumed data.
71 + * Normally, the trace_iterator is used for reading the data when it is not
72 + * consumed, and must retain state.
73 + */
74 +static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
75 +{
76 + const size_t offset = offsetof(struct trace_iterator, seq);
77 +
78 + /*
79 + * Keep gcc from complaining about overwriting more than just one
80 + * member in the structure.
81 + */
82 + memset((char *)iter + offset, 0, sizeof(struct trace_iterator) - offset);
83 +
84 + iter->pos = -1;
85 +}
86 +
87 #endif /* _LINUX_KERNEL_TRACE_H */
88 --- a/kernel/trace/trace_kdb.c
89 +++ b/kernel/trace/trace_kdb.c
90 @@ -41,12 +41,8 @@ static void ftrace_dump_buf(int skip_lin
91
92 kdb_printf("Dumping ftrace buffer:\n");
93
94 - /* reset all but tr, trace, and overruns */
95 - memset(&iter.seq, 0,
96 - sizeof(struct trace_iterator) -
97 - offsetof(struct trace_iterator, seq));
98 + trace_iterator_reset(&iter);
99 iter.iter_flags |= TRACE_FILE_LAT_FMT;
100 - iter.pos = -1;
101
102 if (cpu_file == RING_BUFFER_ALL_CPUS) {
103 for_each_tracing_cpu(cpu) {