diff options
author | Sahara <keun-o.park@windriver.com> | 2013-04-14 22:13:15 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-04-19 19:59:49 -0400 |
commit | 4c69e6ea415a35eb7f0fc8ee9390c8f7436492a2 (patch) | |
tree | 586b87d0779390d498ce45df375b97decacfb059 /kernel/tracepoint.c | |
parent | d2802d0739dcc61af5e5ea00773ce7ddead4e9c2 (diff) |
tracepoints: Prevent null probe from being added
Somehow tracepoint_entry_add_probe() function allows a null probe function.
And, this may lead to unexpected results since the number of probe
functions in an entry can be counted by checking whether a probe is null
or not in the for-loop.
This patch prevents a null probe from being added.
In tracepoint_entry_remove_probe() function, checking probe parameter
within the for-loop is moved out for code efficiency, leaving the null probe
feature which removes all probe functions in the entry.
Link: http://lkml.kernel.org/r/1365991995-19445-1-git-send-email-kpark3469@gmail.com
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Sahara <keun-o.park@windriver.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/tracepoint.c')
-rw-r--r-- | kernel/tracepoint.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index d96ba22dabfa..99e7e314e451 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
@@ -112,7 +112,8 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, | |||
112 | int nr_probes = 0; | 112 | int nr_probes = 0; |
113 | struct tracepoint_func *old, *new; | 113 | struct tracepoint_func *old, *new; |
114 | 114 | ||
115 | WARN_ON(!probe); | 115 | if (WARN_ON(!probe)) |
116 | return ERR_PTR(-EINVAL); | ||
116 | 117 | ||
117 | debug_print_probes(entry); | 118 | debug_print_probes(entry); |
118 | old = entry->funcs; | 119 | old = entry->funcs; |
@@ -152,13 +153,18 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, | |||
152 | 153 | ||
153 | debug_print_probes(entry); | 154 | debug_print_probes(entry); |
154 | /* (N -> M), (N > 1, M >= 0) probes */ | 155 | /* (N -> M), (N > 1, M >= 0) probes */ |
155 | for (nr_probes = 0; old[nr_probes].func; nr_probes++) { | 156 | if (probe) { |
156 | if (!probe || | 157 | for (nr_probes = 0; old[nr_probes].func; nr_probes++) { |
157 | (old[nr_probes].func == probe && | 158 | if (old[nr_probes].func == probe && |
158 | old[nr_probes].data == data)) | 159 | old[nr_probes].data == data) |
159 | nr_del++; | 160 | nr_del++; |
161 | } | ||
160 | } | 162 | } |
161 | 163 | ||
164 | /* | ||
165 | * If probe is NULL, then nr_probes = nr_del = 0, and then the | ||
166 | * entire entry will be removed. | ||
167 | */ | ||
162 | if (nr_probes - nr_del == 0) { | 168 | if (nr_probes - nr_del == 0) { |
163 | /* N -> 0, (N > 1) */ | 169 | /* N -> 0, (N > 1) */ |
164 | entry->funcs = NULL; | 170 | entry->funcs = NULL; |
@@ -173,8 +179,7 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, | |||
173 | if (new == NULL) | 179 | if (new == NULL) |
174 | return ERR_PTR(-ENOMEM); | 180 | return ERR_PTR(-ENOMEM); |
175 | for (i = 0; old[i].func; i++) | 181 | for (i = 0; old[i].func; i++) |
176 | if (probe && | 182 | if (old[i].func != probe || old[i].data != data) |
177 | (old[i].func != probe || old[i].data != data)) | ||
178 | new[j++] = old[i]; | 183 | new[j++] = old[i]; |
179 | new[nr_probes - nr_del].func = NULL; | 184 | new[nr_probes - nr_del].func = NULL; |
180 | entry->refcount = nr_probes - nr_del; | 185 | entry->refcount = nr_probes - nr_del; |