Fix: liblttng-ctl comm: lttng_event_field is not packed
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.cpp
index f4ce9a8829f70b77ece1e958b1ac42767aa41c8d..0627ba5c8bd5f83ca62d9403cddea283a2ce6f8f 100644 (file)
@@ -2559,31 +2559,70 @@ error:
 /*
  * Command LTTNG_LIST_TRACEPOINT_FIELDS processed by the client thread.
  */
-ssize_t cmd_list_tracepoint_fields(enum lttng_domain_type domain,
-               struct lttng_event_field **fields)
+enum lttng_error_code cmd_list_tracepoint_fields(enum lttng_domain_type domain,
+               struct lttng_payload *reply)
 {
+       enum lttng_error_code ret_code;
        int ret;
-       ssize_t nb_fields = 0;
+       unsigned int i, nb_fields;
+       struct lttng_event_field *fields = NULL;
+       struct lttcomm_list_command_header reply_command_header = {};
+       size_t reply_command_header_offset;
+
+       assert(reply);
+
+       /* Reserve space for command reply header. */
+       reply_command_header_offset = reply->buffer.size;
+       ret = lttng_dynamic_buffer_set_size(&reply->buffer,
+                       reply_command_header_offset +
+                               sizeof(struct lttcomm_list_command_header));
+       if (ret) {
+               ret_code = LTTNG_ERR_NOMEM;
+               goto error;
+       }
 
        switch (domain) {
        case LTTNG_DOMAIN_UST:
-               nb_fields = ust_app_list_event_fields(fields);
-               if (nb_fields < 0) {
-                       ret = LTTNG_ERR_UST_LIST_FAIL;
+               ret = ust_app_list_event_fields(&fields);
+               if (ret < 0) {
+                       ret_code = LTTNG_ERR_UST_LIST_FAIL;
                        goto error;
                }
+
                break;
        case LTTNG_DOMAIN_KERNEL:
        default:        /* fall-through */
-               ret = LTTNG_ERR_UND;
+               ret_code = LTTNG_ERR_UND;
                goto error;
        }
 
-       return nb_fields;
+       nb_fields = ret;
+
+       for (i = 0; i < nb_fields; i++) {
+               ret = lttng_event_field_serialize(&fields[i], reply);
+               if (ret) {
+                       ret_code = LTTNG_ERR_NOMEM;
+                       goto error;
+               }
+       }
+
+       if (nb_fields > UINT32_MAX) {
+               ERR("Tracepoint field count would overflow the tracepoint field listing command's reply");
+               ret_code = LTTNG_ERR_OVERFLOW;
+               goto error;
+       }
+
+       /* Update command reply header. */
+       reply_command_header.count = (uint32_t) nb_fields;
+
+       memcpy(reply->buffer.data + reply_command_header_offset, &reply_command_header,
+                       sizeof(reply_command_header));
+
+       ret_code = LTTNG_OK;
 
 error:
-       /* Return negative value to differentiate return code */
-       return -ret;
+       free(fields);
+       return ret_code;
 }
 
 enum lttng_error_code cmd_list_syscalls(
This page took 0.024217 seconds and 4 git commands to generate.