X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Flttng-event-notifier-notification.c;h=957883a801e6651e48b307ba3320e688f740b25b;hb=b9315ad80f02c7299cf499d8edf5f7b9dbbf5876;hp=b8f01395c57bf4e7fd3954f555aa26a286acbf7a;hpb=76db48089b6717136c4712db4e663011fcb4714b;p=lttng-modules.git diff --git a/src/lttng-event-notifier-notification.c b/src/lttng-event-notifier-notification.c index b8f01395..957883a8 100644 --- a/src/lttng-event-notifier-notification.c +++ b/src/lttng-event-notifier-notification.c @@ -25,6 +25,8 @@ */ #define CAPTURE_BUFFER_SIZE 512 +#define MSG_WRITE_NIL_LEN 1 + struct lttng_event_notifier_notification { int notification_fd; uint64_t event_notifier_token; @@ -442,20 +444,34 @@ void notification_send(struct lttng_event_notifier_notification *notif, irq_work_queue(&event_notifier_group->wakeup_pending); } +/* + * Validate that the buffer has enough room to hold empty capture fields. + */ +static +bool validate_buffer_len(struct lttng_event_notifier_notification *notif, size_t captures_left) +{ + if (notif->writer.end_write_pos - notif->writer.write_pos < MSG_WRITE_NIL_LEN * captures_left) + return false; + return true; +} + void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier *event_notifier, const char *stack_data, struct lttng_kernel_probe_ctx *probe_ctx, struct lttng_kernel_notification_ctx *notif_ctx) { struct lttng_event_notifier_notification notif = { 0 }; + size_t captures_left; if (unlikely(!READ_ONCE(event_notifier->parent.enabled))) return; - if (notification_init(¬if, event_notifier)) { - record_error(event_notifier); - goto end; - } + if (notification_init(¬if, event_notifier)) + goto error; + + captures_left = event_notifier->priv->num_captures; + if (!validate_buffer_len(¬if, captures_left)) + goto error; if (unlikely(notif_ctx->eval_capture)) { struct lttng_kernel_bytecode_runtime *capture_bc_runtime; @@ -470,30 +486,40 @@ void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier * &event_notifier->priv->capture_bytecode_runtime_head, node) { struct lttng_interpreter_output output; uint8_t *save_pos; - int ret; + int ret = -1; lttng_msgpack_save_writer_pos(¬if.writer, &save_pos); + captures_left--; if (capture_bc_runtime->interpreter_func(capture_bc_runtime, stack_data, probe_ctx, &output) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK) ret = notification_append_capture(¬if, &output); - else - ret = notification_append_empty_capture(¬if); - if (ret) { + if (ret || !validate_buffer_len(¬if, captures_left)) { /* - * On append capture error, skip the field - * capture by restoring the msgpack writer - * position. + * On append capture error or if the generated + * buffer data would not leave enough room to + * write empty capture fields for the remaining + * fields, skip the field capture by restoring + * the msgpack writer position and writing an + * empty capture field. */ lttng_msgpack_restore_writer_pos(¬if.writer, save_pos); + ret = notification_append_empty_capture(¬if); + WARN_ON_ONCE(ret); } } } + if (notif.has_captures && lttng_msgpack_end_array(¬if.writer)) + goto error; + /* * Send the notification (including the capture buffer) to the * sessiond. */ notification_send(¬if, event_notifier); -end: + return; + +error: + record_error(event_notifier); return; }