Fix: lttng_trace_archive_location_serialize is called on freed memory
[lttng-tools.git] / src / common / location.c
1 /*
2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <lttng/location-internal.h>
9 #include <common/macros.h>
10 #include <stdlib.h>
11 #include <common/error.h>
12
13 static
14 struct lttng_trace_archive_location *lttng_trace_archive_location_create(
15 enum lttng_trace_archive_location_type type)
16 {
17 struct lttng_trace_archive_location *location;
18
19 location = zmalloc(sizeof(*location));
20 if (!location) {
21 goto end;
22 }
23
24 urcu_ref_init(&location->ref);
25 location->type = type;
26 end:
27 return location;
28 }
29
30 static
31 void trace_archive_location_destroy_ref(struct urcu_ref *ref)
32 {
33 struct lttng_trace_archive_location *location =
34 container_of(ref, struct lttng_trace_archive_location, ref);
35
36 switch (location->type) {
37 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
38 free(location->types.local.absolute_path);
39 break;
40 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
41 free(location->types.relay.host);
42 free(location->types.relay.relative_path);
43 break;
44 default:
45 abort();
46 }
47
48 free(location);
49 }
50
51 LTTNG_HIDDEN
52 void lttng_trace_archive_location_get(struct lttng_trace_archive_location *location)
53 {
54 urcu_ref_get(&location->ref);
55 }
56
57 LTTNG_HIDDEN
58 void lttng_trace_archive_location_put(struct lttng_trace_archive_location *location)
59 {
60 if (!location) {
61 return;
62 }
63
64 urcu_ref_put(&location->ref, trace_archive_location_destroy_ref);
65 }
66
67 LTTNG_HIDDEN
68 struct lttng_trace_archive_location *lttng_trace_archive_location_local_create(
69 const char *absolute_path)
70 {
71 struct lttng_trace_archive_location *location = NULL;
72
73 if (!absolute_path) {
74 goto end;
75 }
76
77 location = lttng_trace_archive_location_create(
78 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL);
79 if (!location) {
80 goto end;
81 }
82
83 location->types.local.absolute_path = strdup(absolute_path);
84 if (!location->types.local.absolute_path) {
85 goto error;
86 }
87
88 end:
89 return location;
90 error:
91 lttng_trace_archive_location_put(location);
92 return NULL;
93 }
94
95 LTTNG_HIDDEN
96 struct lttng_trace_archive_location *lttng_trace_archive_location_relay_create(
97 const char *host,
98 enum lttng_trace_archive_location_relay_protocol_type protocol,
99 uint16_t control_port, uint16_t data_port,
100 const char *relative_path)
101 {
102 struct lttng_trace_archive_location *location = NULL;
103
104 if (!host || !relative_path) {
105 goto end;
106 }
107
108 location = lttng_trace_archive_location_create(
109 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY);
110 if (!location) {
111 goto end;
112 }
113
114 location->types.relay.host = strdup(host);
115 if (!location->types.relay.host) {
116 goto error;
117 }
118 location->types.relay.relative_path = strdup(relative_path);
119 if (!location->types.relay.relative_path) {
120 goto error;
121 }
122
123 location->types.relay.protocol = protocol;
124 location->types.relay.ports.control = control_port;
125 location->types.relay.ports.data = data_port;
126 end:
127 return location;
128 error:
129 lttng_trace_archive_location_put(location);
130 return NULL;
131 }
132
133 LTTNG_HIDDEN
134 ssize_t lttng_trace_archive_location_create_from_buffer(
135 const struct lttng_buffer_view *view,
136 struct lttng_trace_archive_location **location)
137 {
138 size_t offset = 0;
139 const struct lttng_trace_archive_location_comm *location_comm;
140 struct lttng_buffer_view location_comm_view;
141
142 location_comm_view = lttng_buffer_view_from_view(view, 0,
143 sizeof(*location_comm));
144 if (!lttng_buffer_view_is_valid(&location_comm_view)) {
145 goto error;
146 }
147
148 offset += location_comm_view.size;
149 location_comm = (const struct lttng_trace_archive_location_comm *) location_comm_view.data;
150
151 switch ((enum lttng_trace_archive_location_type) location_comm->type) {
152 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
153 {
154 const struct lttng_buffer_view absolute_path_view =
155 lttng_buffer_view_from_view(view, offset,
156 location_comm->types.local.absolute_path_len);
157
158 if (!lttng_buffer_view_is_valid(&absolute_path_view)) {
159 goto error;
160 }
161
162 if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
163 goto error;
164 }
165 offset += absolute_path_view.size;
166
167 *location = lttng_trace_archive_location_local_create(
168 absolute_path_view.data);
169 if (!*location) {
170 goto error;
171 }
172 break;
173 }
174 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
175 {
176 const struct lttng_buffer_view hostname_view =
177 lttng_buffer_view_from_view(view, offset,
178 location_comm->types.relay.hostname_len);
179 const struct lttng_buffer_view relative_path_view =
180 lttng_buffer_view_from_view(view,
181 offset + hostname_view.size,
182 location_comm->types.relay.relative_path_len);
183
184 if (!lttng_buffer_view_is_valid(&hostname_view) ||
185 !lttng_buffer_view_is_valid(
186 &relative_path_view)) {
187 goto error;
188 }
189
190 if (hostname_view.data[hostname_view.size - 1] != '\0') {
191 goto error;
192 }
193 if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
194 goto error;
195 }
196 offset += hostname_view.size + relative_path_view.size;
197
198 *location = lttng_trace_archive_location_relay_create(
199 hostname_view.data,
200 (enum lttng_trace_archive_location_relay_protocol_type) location_comm->types.relay.protocol,
201 location_comm->types.relay.ports.control,
202 location_comm->types.relay.ports.data,
203 relative_path_view.data);
204 if (!*location) {
205 goto error;
206 }
207 break;
208 }
209 default:
210 goto error;
211 }
212
213 return offset;
214 error:
215 return -1;
216 }
217
218 LTTNG_HIDDEN
219 ssize_t lttng_trace_archive_location_serialize(
220 const struct lttng_trace_archive_location *location,
221 struct lttng_dynamic_buffer *buffer)
222 {
223 int ret;
224 struct lttng_trace_archive_location_comm location_comm;
225
226 location_comm.type = (int8_t) location->type;
227
228 switch (location->type) {
229 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
230 location_comm.types.local.absolute_path_len =
231 strlen(location->types.local.absolute_path) + 1;
232 break;
233 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
234 location_comm.types.relay.hostname_len =
235 strlen(location->types.relay.host) + 1;
236 location_comm.types.relay.protocol =
237 (int8_t) location->types.relay.protocol;
238 location_comm.types.relay.ports.control =
239 location->types.relay.ports.control;
240 location_comm.types.relay.ports.data =
241 location->types.relay.ports.data;
242 location_comm.types.relay.relative_path_len =
243 strlen(location->types.relay.relative_path) + 1;
244 break;
245 default:
246 abort();
247 }
248
249 ret = lttng_dynamic_buffer_append(buffer, &location_comm,
250 sizeof(location_comm));
251 if (ret) {
252 goto error;
253 }
254
255 switch (location->type) {
256 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
257 ret = lttng_dynamic_buffer_append(buffer,
258 location->types.local.absolute_path,
259 location_comm.types.local.absolute_path_len);
260 if (ret) {
261 goto error;
262 }
263 break;
264 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
265 ret = lttng_dynamic_buffer_append(buffer,
266 location->types.relay.host,
267 location_comm.types.relay.hostname_len);
268 if (ret) {
269 goto error;
270 }
271 ret = lttng_dynamic_buffer_append(buffer,
272 location->types.relay.relative_path,
273 location_comm.types.relay.relative_path_len);
274 if (ret) {
275 goto error;
276 }
277 break;
278 default:
279 abort();
280 }
281
282 return 0;
283 error:
284 return -1;
285 }
286
287 enum lttng_trace_archive_location_type lttng_trace_archive_location_get_type(
288 const struct lttng_trace_archive_location *location)
289 {
290 enum lttng_trace_archive_location_type type;
291
292 if (!location) {
293 type = LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN;
294 goto end;
295 }
296
297 type = location->type;
298 end:
299 return type;
300 }
301
302 enum lttng_trace_archive_location_status
303 lttng_trace_archive_location_local_get_absolute_path(
304 const struct lttng_trace_archive_location *location,
305 const char **absolute_path)
306 {
307 enum lttng_trace_archive_location_status status =
308 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
309
310 if (!location || !absolute_path ||
311 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL) {
312 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
313 goto end;
314 }
315
316 *absolute_path = location->types.local.absolute_path;
317 end:
318 return status;
319 }
320
321 enum lttng_trace_archive_location_status
322 lttng_trace_archive_location_relay_get_host(
323 const struct lttng_trace_archive_location *location,
324 const char **relay_host)
325 {
326 enum lttng_trace_archive_location_status status =
327 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
328
329 if (!location || !relay_host ||
330 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
331 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
332 goto end;
333 }
334
335 *relay_host = location->types.relay.host;
336 end:
337 return status;
338 }
339
340 enum lttng_trace_archive_location_status
341 lttng_trace_archive_location_relay_get_relative_path(
342 const struct lttng_trace_archive_location *location,
343 const char **relative_path)
344 {
345 enum lttng_trace_archive_location_status status =
346 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
347
348 if (!location || !relative_path ||
349 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
350 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
351 goto end;
352 }
353
354 *relative_path = location->types.relay.relative_path;
355 end:
356 return status;
357 }
358
359 enum lttng_trace_archive_location_status
360 lttng_trace_archive_location_relay_get_control_port(
361 const struct lttng_trace_archive_location *location,
362 uint16_t *control_port)
363 {
364 enum lttng_trace_archive_location_status status =
365 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
366
367 if (!location || !control_port ||
368 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
369 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
370 goto end;
371 }
372
373 *control_port = location->types.relay.ports.control;
374 end:
375 return status;
376 }
377
378 enum lttng_trace_archive_location_status
379 lttng_trace_archive_location_relay_get_data_port(
380 const struct lttng_trace_archive_location *location,
381 uint16_t *data_port)
382 {
383 enum lttng_trace_archive_location_status status =
384 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
385
386 if (!location || !data_port ||
387 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
388 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
389 goto end;
390 }
391
392 *data_port = location->types.relay.ports.data;
393 end:
394 return status;
395 }
396
397 enum lttng_trace_archive_location_status
398 lttng_trace_archive_location_relay_get_protocol_type(
399 const struct lttng_trace_archive_location *location,
400 enum lttng_trace_archive_location_relay_protocol_type *protocol)
401 {
402 enum lttng_trace_archive_location_status status =
403 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
404
405 if (!location || !protocol ||
406 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
407 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
408 goto end;
409 }
410
411 *protocol = location->types.relay.protocol;
412 end:
413 return status;
414 }
This page took 0.036858 seconds and 4 git commands to generate.