Fix: use-after-free on error of lttng_event creation and copy
[lttng-tools.git] / src / lib / lttng-ctl / event.c
CommitLineData
eb5c4f4e
JG
1/*
2 * event.c
3 *
4 * Linux Trace Toolkit Control Library
5 *
6 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License, version 2.1 only,
10 * as published by the Free Software Foundation.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#define _LGPL_SOURCE
ef0e06bc 23#include <assert.h>
eb5c4f4e 24#include <stddef.h>
ef0e06bc
JG
25
26#include <common/error.h>
eb5c4f4e 27#include <common/sessiond-comm/sessiond-comm.h>
ef0e06bc
JG
28#include <lttng/event-internal.h>
29#include <lttng/event.h>
30#include <lttng/lttng-error.h>
31#include <lttng/userspace-probe-internal.h>
32
33struct lttng_event *lttng_event_create(void)
34{
35 struct lttng_event *event;
36 struct lttng_event_extended *event_extended;
37
38 event = zmalloc(sizeof(*event));
39 if (!event) {
40 PERROR("Error allocating event structure");
41 goto end;
42 }
43
44 event_extended = zmalloc(sizeof(*event_extended));
45 if (!event_extended) {
46 PERROR("Error allocating event extended structure");
47 goto error;
48 }
49 event->extended.ptr = event_extended;
50end:
51 return event;
52error:
53 free(event);
37750a61 54 event = NULL;
ef0e06bc
JG
55 goto end;
56}
57
58void lttng_event_destroy(struct lttng_event *event)
59{
60 struct lttng_event_extended *event_extended;
61
62 if (!event) {
63 return;
64 }
65
66 event_extended = (struct lttng_event_extended *) event->extended.ptr;
67
68 if (event_extended) {
69 if (event_extended->probe_location) {
70 lttng_userspace_probe_location_destroy(
71 event_extended->probe_location);
72 }
73 free(event_extended);
74 }
75 free(event);
76}
eb5c4f4e
JG
77
78int lttng_event_get_filter_expression(struct lttng_event *event,
79 const char **filter_expression)
80{
81 int ret = 0;
de453daa 82 struct lttng_event_extended *event_extended;
eb5c4f4e
JG
83
84 if (!event || !filter_expression) {
85 ret = -LTTNG_ERR_INVALID;
86 goto end;
87 }
88
de453daa
JG
89 event_extended = (struct lttng_event_extended *) event->extended.ptr;
90 if (!event_extended) {
eb5c4f4e
JG
91 /*
92 * This can happen since the lttng_event structure is
93 * used for other tasks where this pointer is never set.
94 */
95 *filter_expression = NULL;
96 goto end;
97 }
98
de453daa 99 *filter_expression = event_extended->filter_expression;
eb5c4f4e
JG
100end:
101 return ret;
102}
103
104int lttng_event_get_exclusion_name_count(struct lttng_event *event)
105{
de453daa
JG
106 int ret = 0;
107 struct lttng_event_extended *event_extended;
eb5c4f4e
JG
108
109 if (!event) {
110 ret = -LTTNG_ERR_INVALID;
111 goto end;
112 }
113
de453daa
JG
114 event_extended = (struct lttng_event_extended *) event->extended.ptr;
115 if (!event_extended) {
eb5c4f4e
JG
116 /*
117 * This can happen since the lttng_event structure is
118 * used for other tasks where this pointer is never set.
119 */
eb5c4f4e
JG
120 goto end;
121 }
122
de453daa 123 if (event_extended->exclusions.count > INT_MAX) {
eb5c4f4e
JG
124 ret = -LTTNG_ERR_OVERFLOW;
125 goto end;
126 }
de453daa 127 ret = (int) event_extended->exclusions.count;
eb5c4f4e
JG
128end:
129 return ret;
130}
131
132int lttng_event_get_exclusion_name(struct lttng_event *event,
133 size_t index, const char **exclusion_name)
134{
135 int ret = 0;
de453daa 136 struct lttng_event_extended *event_extended;
eb5c4f4e
JG
137
138 if (!event || !exclusion_name) {
139 ret = -LTTNG_ERR_INVALID;
140 goto end;
141 }
142
de453daa
JG
143 if (index > UINT_MAX) {
144 ret = -LTTNG_ERR_OVERFLOW;
eb5c4f4e
JG
145 goto end;
146 }
147
de453daa
JG
148 event_extended = (struct lttng_event_extended *) event->extended.ptr;
149 if (!event_extended) {
150 /*
151 * This can happen since the lttng_event structure is
152 * used for other tasks where this pointer is never set.
153 */
eb5c4f4e
JG
154 ret = -LTTNG_ERR_INVALID;
155 goto end;
156 }
157
de453daa
JG
158 if (index >= event_extended->exclusions.count) {
159 ret = -LTTNG_ERR_INVALID;
160 goto end;
161 }
eb5c4f4e 162
de453daa
JG
163 *exclusion_name = event_extended->exclusions.strings +
164 (index * LTTNG_SYMBOL_NAME_LEN);
eb5c4f4e
JG
165end:
166 return ret;
167}
ef0e06bc 168
87597c2c
JG
169const struct lttng_userspace_probe_location *
170lttng_event_get_userspace_probe_location(const struct lttng_event *event)
ef0e06bc
JG
171{
172 struct lttng_userspace_probe_location *probe_location = NULL;
173 struct lttng_event_extended *event_extended;
174
175 if (!event) {
176 goto end;
177 }
178
179 event_extended = (struct lttng_event_extended *) event->extended.ptr;
180 if (!event_extended) {
181 goto end;
182 }
183 probe_location = event_extended->probe_location;
184end:
185 return probe_location;
186}
187
188int lttng_event_set_userspace_probe_location(struct lttng_event *event,
189 struct lttng_userspace_probe_location *probe_location)
190{
191 int ret = 0;
192 struct lttng_event_extended *event_extended;
193
194 if (!event || !probe_location) {
195 ret = -LTTNG_ERR_INVALID;
196 goto end;
197 }
198
199 event_extended = (struct lttng_event_extended *) event->extended.ptr;
200 assert(event_extended);
201 if (event_extended->probe_location) {
202 lttng_userspace_probe_location_destroy(
203 event_extended->probe_location);
204 }
205 event_extended->probe_location = probe_location;
206end:
207 return ret;
208}
This page took 0.03223 seconds and 5 git commands to generate.