Fix: unchecked buffer size for communication header
[lttng-tools.git] / src / common / location.c
index d1fd538f2933994e0ba91be7e6ecfa28d8bd4687..c79f8547546f6e65e0aa2dd5012c9c187f1108b7 100644 (file)
@@ -1,18 +1,8 @@
 /*
- * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
  *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License, version 2.1 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: LGPL-2.1-only
  *
- * This library is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <lttng/location-internal.h>
@@ -124,6 +114,160 @@ error:
        return NULL;
 }
 
+LTTNG_HIDDEN
+ssize_t lttng_trace_archive_location_create_from_buffer(
+               const struct lttng_buffer_view *view,
+               struct lttng_trace_archive_location **location)
+{
+       size_t offset = 0;
+       const struct lttng_trace_archive_location_comm *location_comm;
+       struct lttng_buffer_view location_comm_view;
+
+       location_comm_view = lttng_buffer_view_from_view(view, 0,
+                       sizeof(*location_comm));
+       if (!lttng_buffer_view_is_valid(&location_comm_view)) {
+               goto error;
+       }
+
+       offset += location_comm_view.size;
+       location_comm = (const struct lttng_trace_archive_location_comm *) location_comm_view.data;
+
+       switch ((enum lttng_trace_archive_location_type) location_comm->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+       {
+               const struct lttng_buffer_view absolute_path_view =
+                               lttng_buffer_view_from_view(view, offset,
+                               location_comm->types.local.absolute_path_len);
+
+               if (!lttng_buffer_view_is_valid(&absolute_path_view)) {
+                       goto error;
+               }
+
+               if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
+                       goto error;
+               }
+               offset += absolute_path_view.size;
+
+               *location = lttng_trace_archive_location_local_create(
+                               absolute_path_view.data);
+               if (!*location) {
+                       goto error;
+               }
+               break;
+       }
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+       {
+               const struct lttng_buffer_view hostname_view =
+                               lttng_buffer_view_from_view(view, offset,
+                               location_comm->types.relay.hostname_len);
+               const struct lttng_buffer_view relative_path_view =
+                               lttng_buffer_view_from_view(view,
+                               offset + hostname_view.size,
+                               location_comm->types.relay.relative_path_len);
+
+               if (!lttng_buffer_view_is_valid(&hostname_view) ||
+                               !lttng_buffer_view_is_valid(
+                                               &relative_path_view)) {
+                       goto error;
+               }
+
+               if (hostname_view.data[hostname_view.size - 1] != '\0') {
+                       goto error;
+               }
+               if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
+                       goto error;
+               }
+               offset += hostname_view.size + relative_path_view.size;
+
+               *location = lttng_trace_archive_location_relay_create(
+                               hostname_view.data,
+                               (enum lttng_trace_archive_location_relay_protocol_type) location_comm->types.relay.protocol,
+                               location_comm->types.relay.ports.control,
+                               location_comm->types.relay.ports.data,
+                               relative_path_view.data);
+               if (!*location) {
+                       goto error;
+               }
+               break;
+       }
+       default:
+               goto error;
+       }
+
+       return offset;
+error:
+       return -1;
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_trace_archive_location_serialize(
+               const struct lttng_trace_archive_location *location,
+               struct lttng_dynamic_buffer *buffer)
+{
+       int ret;
+       struct lttng_trace_archive_location_comm location_comm;
+
+       location_comm.type = (int8_t) location->type;
+
+       switch (location->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+               location_comm.types.local.absolute_path_len =
+                               strlen(location->types.local.absolute_path) + 1;
+               break;
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+               location_comm.types.relay.hostname_len =
+                               strlen(location->types.relay.host) + 1;
+               location_comm.types.relay.protocol =
+                               (int8_t) location->types.relay.protocol;
+               location_comm.types.relay.ports.control =
+                               location->types.relay.ports.control;
+               location_comm.types.relay.ports.data =
+                               location->types.relay.ports.data;
+               location_comm.types.relay.relative_path_len =
+                               strlen(location->types.relay.relative_path) + 1;
+               break;
+       default:
+               abort();
+       }
+
+       ret = lttng_dynamic_buffer_append(buffer, &location_comm,
+                       sizeof(location_comm));
+       if (ret) {
+               goto error;
+       }
+
+       switch (location->type) {
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
+               ret = lttng_dynamic_buffer_append(buffer,
+                               location->types.local.absolute_path,
+                               location_comm.types.local.absolute_path_len);
+               if (ret) {
+                       goto error;
+               }
+               break;
+       case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
+               ret = lttng_dynamic_buffer_append(buffer,
+                               location->types.relay.host,
+                               location_comm.types.relay.hostname_len);
+               if (ret) {
+                       goto error;
+               }
+               ret = lttng_dynamic_buffer_append(buffer,
+                               location->types.relay.relative_path,
+                               location_comm.types.relay.relative_path_len);
+               if (ret) {
+                       goto error;
+               }
+               break;
+       default:
+               abort();
+       }
+
+       return 0;
+error:
+       return -1;
+}
+
 enum lttng_trace_archive_location_type lttng_trace_archive_location_get_type(
                const struct lttng_trace_archive_location *location)
 {
This page took 0.024589 seconds and 4 git commands to generate.