From 428d8ee5ebdee80fbfb94eccf5571b546a6ae880 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 14 Apr 2022 15:20:18 -0400 Subject: [PATCH] Fix communication protocol: ensure extensibility of counter commands Signed-off-by: Mathieu Desnoyers Change-Id: Ia9f6d4f550d999a3dade435612565941ebb86d25 --- include/lttng/ust-abi.h | 34 ++++----- src/common/events.h | 6 +- src/common/ustcomm.c | 18 ++--- src/common/ustcomm.h | 26 +------ src/lib/lttng-ust-ctl/ustctl.c | 60 ++++++++++----- src/lib/lttng-ust/lttng-ust-abi.c | 55 ++++++++----- src/lib/lttng-ust/lttng-ust-comm.c | 119 ++++++++++++++++++----------- 7 files changed, 181 insertions(+), 137 deletions(-) diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h index a995e3ac..9823b3f4 100644 --- a/include/lttng/ust-abi.h +++ b/include/lttng/ust-abi.h @@ -23,6 +23,8 @@ #define LTTNG_UST_ABI_MAJOR_VERSION_OLDEST_COMPATIBLE 8 #define LTTNG_UST_ABI_MINOR_VERSION 0 +#define LTTNG_UST_ABI_CMD_MAX_LEN 4096U + enum lttng_ust_abi_instrumentation { LTTNG_UST_ABI_TRACEPOINT = 0, LTTNG_UST_ABI_PROBE = 1, @@ -144,7 +146,6 @@ struct lttng_ust_abi_counter_key_dimension { /* Followed by a variable-length array of key tokens */ } __attribute__((packed)); -#define LTTNG_UST_ABI_COUNTER_EVENT_MAX_LEN 4096U struct lttng_ust_abi_counter_event { uint32_t len; /* length of this structure */ @@ -180,20 +181,14 @@ struct lttng_ust_abi_counter_conf { uint32_t elem_len; /* array stride (size of lttng_ust_abi_counter_dimension) */ } __attribute__((packed)); -#define LTTNG_UST_ABI_COUNTER_DATA_MAX_LEN 4096U -struct lttng_ust_abi_counter { - uint64_t len; - char data[]; /* variable sized data */ -} __attribute__((packed)); - struct lttng_ust_abi_counter_global { - uint32_t len; /* Length of this structure */ - uint64_t shm_len; /* shm len */ + uint32_t len; /* Length of this structure */ + uint64_t shm_len; /* shm len */ } __attribute__((packed)); struct lttng_ust_abi_counter_cpu { - uint32_t len; /* Length of this structure */ - uint64_t shm_len; /* shm len */ + uint32_t len; /* Length of this structure */ + uint64_t shm_len; /* shm len */ uint32_t cpu_nr; } __attribute__((packed)); @@ -378,9 +373,10 @@ struct lttng_ust_abi_event_exclusion { char names[LTTNG_UST_ABI_SYM_NAME_LEN][0]; } __attribute__((packed)); -#define LTTNG_UST_ABI_CMD(minor) (minor) -#define LTTNG_UST_ABI_CMDR(minor, type) (minor) -#define LTTNG_UST_ABI_CMDW(minor, type) (minor) +#define LTTNG_UST_ABI_CMD(minor) (minor) +#define LTTNG_UST_ABI_CMDR(minor, type) (minor) +#define LTTNG_UST_ABI_CMDW(minor, type) (minor) +#define LTTNG_UST_ABI_CMDV(minor, var_len_cmd_type) (minor) /* Handled by object descriptor */ #define LTTNG_UST_ABI_RELEASE LTTNG_UST_ABI_CMD(0x1) @@ -430,22 +426,22 @@ struct lttng_ust_abi_event_exclusion { /* Event notifier group commands */ #define LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE \ - LTTNG_UST_ABI_CMDW(0xB0, struct lttng_ust_abi_event_notifier) + LTTNG_UST_ABI_CMDV(0xB0, struct lttng_ust_abi_event_notifier) /* Event notifier commands */ #define LTTNG_UST_ABI_CAPTURE LTTNG_UST_ABI_CMD(0xB6) /* Session and event notifier group commands */ #define LTTNG_UST_ABI_COUNTER \ - LTTNG_UST_ABI_CMDW(0xC0, struct lttng_ust_abi_counter) + LTTNG_UST_ABI_CMDV(0xC0, struct lttng_ust_abi_counter_conf) /* Counter commands */ #define LTTNG_UST_ABI_COUNTER_GLOBAL \ - LTTNG_UST_ABI_CMDW(0xD0, struct lttng_ust_abi_counter_global) + LTTNG_UST_ABI_CMDV(0xD0, struct lttng_ust_abi_counter_global) #define LTTNG_UST_ABI_COUNTER_CPU \ - LTTNG_UST_ABI_CMDW(0xD1, struct lttng_ust_abi_counter_cpu) + LTTNG_UST_ABI_CMDV(0xD1, struct lttng_ust_abi_counter_cpu) #define LTTNG_UST_ABI_COUNTER_EVENT \ - LTTNG_UST_ABI_CMDW(0xD2, struct lttng_ust_abi_counter_event) + LTTNG_UST_ABI_CMDV(0xD2, struct lttng_ust_abi_counter_event) #define LTTNG_UST_ABI_ROOT_HANDLE 0 diff --git a/src/common/events.h b/src/common/events.h index 94e8038b..5c6d1d9a 100644 --- a/src/common/events.h +++ b/src/common/events.h @@ -47,9 +47,13 @@ union lttng_ust_abi_args { int event_notifier_notif_fd; } event_notifier_handle; struct { - void *counter_data; + uint32_t len; + } event_notifier; + struct { + uint32_t len; } counter; struct { + uint32_t len; int shm_fd; } counter_shm; struct { diff --git a/src/common/ustcomm.c b/src/common/ustcomm.c index 33515656..2435e380 100644 --- a/src/common/ustcomm.c +++ b/src/common/ustcomm.c @@ -708,31 +708,31 @@ error: return ret; } -ssize_t ustcomm_recv_counter_from_sessiond(int sock, - void **_counter_data, uint64_t var_len) +ssize_t ustcomm_recv_var_len_cmd_from_sessiond(int sock, + void **_data, uint32_t var_len) { - void *counter_data; + void *data; ssize_t len; - if (var_len > LTTNG_UST_ABI_COUNTER_DATA_MAX_LEN) { + if (var_len > LTTNG_UST_ABI_CMD_MAX_LEN) { len = -EINVAL; goto error_check; } /* Receive variable length data */ - counter_data = zmalloc(var_len); - if (!counter_data) { + data = zmalloc(var_len); + if (!data) { len = -ENOMEM; goto error_alloc; } - len = ustcomm_recv_unix_sock(sock, counter_data, var_len); + len = ustcomm_recv_unix_sock(sock, data, var_len); if (len != var_len) { goto error_recv; } - *_counter_data = counter_data; + *_data = data; return len; error_recv: - free(counter_data); + free(data); error_alloc: error_check: return len; diff --git a/src/common/ustcomm.h b/src/common/ustcomm.h index 4bdc8a50..bbd33868 100644 --- a/src/common/ustcomm.h +++ b/src/common/ustcomm.h @@ -90,27 +90,9 @@ struct ustcomm_ust_msg { uint32_t reloc_offset; uint64_t seqnum; } __attribute__((packed)) capture; - struct lttng_ust_abi_counter counter; - struct lttng_ust_abi_counter_global counter_global; - struct lttng_ust_abi_counter_cpu counter_cpu; - /* - * For lttng_ust_abi_EVENT_NOTIFIER_CREATE, a struct - * lttng_ust_abi_event_notifier implicitly follows struct - * ustcomm_ust_msg. - */ struct { - /* Length of struct lttng_ust_abi_event_notifier */ - uint32_t len; - } event_notifier; - /* - * For LTTNG_UST_ABI_COUNTER_EVENT, a struct - * lttng_ust_counter_event implicitly follows struct - * ustcomm_ust_msg. - */ - struct { - /* Length of struct lttng_ust_abi_counter_event */ - uint32_t len; - } counter_event; + uint32_t cmd_len; + } __attribute__((packed)) var_len_cmd; char padding[USTCOMM_MSG_PADDING2]; } u; } __attribute__((packed)); @@ -266,8 +248,8 @@ ssize_t ustcomm_recv_event_notifier_notif_fd_from_sessiond(int sock, int *event_notifier_notif_fd) __attribute__((visibility("hidden"))); -ssize_t ustcomm_recv_counter_from_sessiond(int sock, - void **counter_data, uint64_t len) +ssize_t ustcomm_recv_var_len_cmd_from_sessiond(int sock, + void **data, uint32_t len) __attribute__((visibility("hidden"))); int ustcomm_recv_counter_shm_from_sessiond(int sock, diff --git a/src/lib/lttng-ust-ctl/ustctl.c b/src/lib/lttng-ust-ctl/ustctl.c index 53d63c6d..285c295b 100644 --- a/src/lib/lttng-ust-ctl/ustctl.c +++ b/src/lib/lttng-ust-ctl/ustctl.c @@ -683,7 +683,7 @@ int lttng_ust_ctl_create_event_notifier(int sock, struct lttng_ust_abi_event_not struct lttng_ust_abi_object_data *event_notifier_group, struct lttng_ust_abi_object_data **_event_notifier_data) { - struct ustcomm_ust_msg lum; + struct ustcomm_ust_msg lum = {}; struct ustcomm_ust_reply lur; struct lttng_ust_abi_object_data *event_notifier_data; ssize_t len; @@ -698,10 +698,9 @@ int lttng_ust_ctl_create_event_notifier(int sock, struct lttng_ust_abi_event_not event_notifier_data->type = LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER; - memset(&lum, 0, sizeof(lum)); lum.handle = event_notifier_group->handle; lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE; - lum.u.event_notifier.len = sizeof(*event_notifier); + lum.u.var_len_cmd.cmd_len = sizeof(*event_notifier); ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { @@ -3155,7 +3154,7 @@ void lttng_ust_ctl_destroy_counter(struct lttng_ust_ctl_daemon_counter *counter) int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle, struct lttng_ust_abi_object_data *counter_data) { - struct ustcomm_ust_msg lum; + struct ustcomm_ust_msg lum = {}; struct ustcomm_ust_reply lur; int ret; size_t size; @@ -3165,15 +3164,14 @@ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle, return -EINVAL; size = counter_data->size; - memset(&lum, 0, sizeof(lum)); lum.handle = parent_handle; lum.cmd = LTTNG_UST_ABI_COUNTER; - lum.u.counter.len = size; + lum.u.var_len_cmd.cmd_len = size; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; - /* Send counter data */ + /* Send var len cmd */ len = ustcomm_send_unix_sock(sock, counter_data->u.counter.data, size); if (len != size) { if (len < 0) @@ -3201,7 +3199,8 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock, struct lttng_ust_abi_object_data *counter_data, struct lttng_ust_abi_object_data *counter_global_data) { - struct ustcomm_ust_msg lum; + struct lttng_ust_abi_counter_global counter_global = {}; + struct ustcomm_ust_msg lum = {}; struct ustcomm_ust_reply lur; int ret, shm_fd[1]; size_t size; @@ -3211,15 +3210,25 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock, return -EINVAL; size = counter_global_data->size; - memset(&lum, 0, sizeof(lum)); lum.handle = counter_data->handle; /* parent handle */ lum.cmd = LTTNG_UST_ABI_COUNTER_GLOBAL; - lum.u.counter_global.len = sizeof(struct lttng_ust_abi_counter_global); - lum.u.counter_global.shm_len = size; + lum.u.var_len_cmd.cmd_len = sizeof(struct lttng_ust_abi_counter_global); ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; + counter_global.len = sizeof(struct lttng_ust_abi_counter_global); + counter_global.shm_len = size; + + /* Send var len cmd */ + len = ustcomm_send_unix_sock(sock, &counter_global, sizeof(struct lttng_ust_abi_counter_global)); + if (len != sizeof(struct lttng_ust_abi_counter_global)) { + if (len < 0) + return len; + else + return -EIO; + } + shm_fd[0] = counter_global_data->u.counter_global.shm_fd; len = ustcomm_send_fds_unix_sock(sock, shm_fd, 1); if (len <= 0) { @@ -3248,7 +3257,8 @@ int lttng_ust_ctl_send_counter_cpu_data_to_ust(int sock, struct lttng_ust_abi_object_data *counter_data, struct lttng_ust_abi_object_data *counter_cpu_data) { - struct ustcomm_ust_msg lum; + struct lttng_ust_abi_counter_cpu counter_cpu = {}; + struct ustcomm_ust_msg lum = {}; struct ustcomm_ust_reply lur; int ret, shm_fd[1]; size_t size; @@ -3258,16 +3268,26 @@ int lttng_ust_ctl_send_counter_cpu_data_to_ust(int sock, return -EINVAL; size = counter_cpu_data->size; - memset(&lum, 0, sizeof(lum)); lum.handle = counter_data->handle; /* parent handle */ lum.cmd = LTTNG_UST_ABI_COUNTER_CPU; - lum.u.counter_cpu.len = sizeof(struct lttng_ust_abi_counter_cpu); - lum.u.counter_cpu.shm_len = size; - lum.u.counter_cpu.cpu_nr = counter_cpu_data->u.counter_cpu.cpu_nr; + lum.u.var_len_cmd.cmd_len = sizeof(struct lttng_ust_abi_counter_cpu); ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) return ret; + counter_cpu.len = sizeof(struct lttng_ust_abi_counter_cpu); + counter_cpu.shm_len = size; + counter_cpu.cpu_nr = counter_cpu_data->u.counter_cpu.cpu_nr; + + /* Send var len cmd */ + len = ustcomm_send_unix_sock(sock, &counter_cpu, sizeof(struct lttng_ust_abi_counter_cpu)); + if (len != sizeof(struct lttng_ust_abi_counter_cpu)) { + if (len < 0) + return len; + else + return -EIO; + } + shm_fd[0] = counter_cpu_data->u.counter_global.shm_fd; len = ustcomm_send_fds_unix_sock(sock, shm_fd, 1); if (len <= 0) { @@ -3322,7 +3342,7 @@ int lttng_ust_ctl_counter_create_event(int sock, struct lttng_ust_abi_object_data *counter_data, struct lttng_ust_abi_object_data **_counter_event_data) { - struct ustcomm_ust_msg lum; + struct ustcomm_ust_msg lum = {}; struct ustcomm_ust_reply lur; struct lttng_ust_abi_object_data *counter_event_data; ssize_t len; @@ -3335,16 +3355,16 @@ int lttng_ust_ctl_counter_create_event(int sock, if (!counter_event_data) return -ENOMEM; counter_event_data->type = LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_EVENT; - memset(&lum, 0, sizeof(lum)); lum.handle = counter_data->handle; lum.cmd = LTTNG_UST_ABI_COUNTER_EVENT; - lum.u.counter_event.len = counter_event_len; + lum.u.var_len_cmd.cmd_len = counter_event_len; ret = ustcomm_send_app_cmd(sock, &lum, &lur); if (ret) { free(counter_event_data); return ret; } - /* Send struct lttng_ust_counter_event */ + + /* Send var len cmd */ len = ustcomm_send_unix_sock(sock, counter_event, counter_event_len); if (len != counter_event_len) { free(counter_event_data); diff --git a/src/lib/lttng-ust/lttng-ust-abi.c b/src/lib/lttng-ust/lttng-ust-abi.c index f9bddd01..d327cd91 100644 --- a/src/lib/lttng-ust/lttng-ust-abi.c +++ b/src/lib/lttng-ust/lttng-ust-abi.c @@ -633,7 +633,7 @@ int copy_abi_struct(void *dst_struct, size_t dst_struct_len, static long lttng_session_create_counter( int session_objd, - struct lttng_ust_abi_counter *ust_counter, + const struct lttng_ust_abi_counter_conf *abi_counter_conf, union lttng_ust_abi_args *uargs, void *owner) { @@ -643,18 +643,16 @@ long lttng_session_create_counter( struct lttng_ust_channel_counter *counter = NULL; struct lttng_counter_dimension dimensions[1] = {}; size_t number_dimensions = 1; - const struct lttng_ust_abi_counter_conf *abi_counter_conf; struct lttng_ust_abi_counter_conf counter_conf; uint32_t min_expected_len = lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len); const struct lttng_ust_abi_counter_dimension *abi_dimension; struct lttng_ust_abi_counter_dimension dimension; - if (ust_counter->len < min_expected_len) { + if (uargs->counter.len < min_expected_len) { ERR("LTTng: Map: Counter configuration of wrong size."); return -EINVAL; } - abi_counter_conf = uargs->counter.counter_data; - if (abi_counter_conf->len > ust_counter->len || abi_counter_conf->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len)) { + if (abi_counter_conf->len > uargs->counter.len || abi_counter_conf->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len)) { return -EINVAL; } ret = copy_abi_struct(&counter_conf, sizeof(counter_conf), abi_counter_conf, abi_counter_conf->len); @@ -670,7 +668,7 @@ long lttng_session_create_counter( ERR("Unexpected dimension array element length %u.", counter_conf.elem_len); return -EINVAL; } - if (counter_conf.len + counter_conf.elem_len > ust_counter->len) { + if (counter_conf.len + counter_conf.elem_len > uargs->counter.len) { return -EINVAL; } abi_dimension = (const struct lttng_ust_abi_counter_dimension *)(((char *)abi_counter_conf) + counter_conf.len); @@ -778,8 +776,8 @@ long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg, return lttng_session_statedump(session); case LTTNG_UST_ABI_COUNTER: return lttng_session_create_counter(objd, - (struct lttng_ust_abi_counter *) arg, - uargs, owner); + (struct lttng_ust_abi_counter_conf *)arg, + uargs, owner); default: return -EINVAL; } @@ -954,7 +952,7 @@ static const struct lttng_ust_abi_objd_ops lttng_event_notifier_group_error_coun static int lttng_ust_event_notifier_group_create_error_counter(int event_notifier_group_objd, - struct lttng_ust_abi_counter *ust_counter, + struct lttng_ust_abi_counter_conf *abi_counter_conf, union lttng_ust_abi_args *uargs, void *owner) { @@ -965,7 +963,6 @@ int lttng_ust_event_notifier_group_create_error_counter(int event_notifier_group int counter_objd, ret; size_t counter_len; struct lttng_counter_dimension dimensions[1] = {}; - const struct lttng_ust_abi_counter_conf *abi_counter_conf; struct lttng_ust_abi_counter_conf counter_conf; uint32_t min_expected_len = lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len); const struct lttng_ust_abi_counter_dimension *abi_dimension; @@ -974,12 +971,11 @@ int lttng_ust_event_notifier_group_create_error_counter(int event_notifier_group if (event_notifier_group->error_counter) return -EBUSY; - if (ust_counter->len < min_expected_len) { + if (uargs->counter.len < min_expected_len) { ERR("LTTng: Counter configuration of wrong size."); return -EINVAL; } - abi_counter_conf = uargs->counter.counter_data; - if (abi_counter_conf->len > ust_counter->len || abi_counter_conf->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len)) { + if (abi_counter_conf->len > uargs->counter.len || abi_counter_conf->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_conf, elem_len)) { return -EINVAL; } ret = copy_abi_struct(&counter_conf, sizeof(counter_conf), abi_counter_conf, abi_counter_conf->len); @@ -995,7 +991,7 @@ int lttng_ust_event_notifier_group_create_error_counter(int event_notifier_group ERR("Unexpected dimension array element length %u.", counter_conf.elem_len); return -EINVAL; } - if (counter_conf.len + counter_conf.elem_len > ust_counter->len) { + if (counter_conf.len + counter_conf.elem_len > uargs->counter.len) { return -EINVAL; } abi_dimension = (const struct lttng_ust_abi_counter_dimension *)(((char *)abi_counter_conf) + counter_conf.len); @@ -1078,29 +1074,40 @@ static long lttng_event_notifier_group_cmd(int objd, unsigned int cmd, unsigned long arg, union lttng_ust_abi_args *uargs, void *owner) { + int ret; + switch (cmd) { case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE: { - struct lttng_ust_abi_event_notifier *event_notifier_param = + struct lttng_ust_abi_event_notifier *abi_event_notifier = (struct lttng_ust_abi_event_notifier *) arg; - if (strutils_is_star_glob_pattern(event_notifier_param->event.name)) { + struct lttng_ust_abi_event_notifier event_notifier = {}; + + if (uargs->event_notifier.len < lttng_ust_offsetofend(struct lttng_ust_abi_event_notifier, error_counter_index)) + return -EINVAL; + ret = copy_abi_struct(&event_notifier, sizeof(event_notifier), + abi_event_notifier, uargs->event_notifier.len); + if (ret) + return ret; + event_notifier.event.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0'; + if (strutils_is_star_glob_pattern(event_notifier.event.name)) { /* * If the event name is a star globbing pattern, * we create the special star globbing enabler. */ return lttng_ust_event_notifier_enabler_create(objd, - owner, event_notifier_param, + owner, &event_notifier, LTTNG_ENABLER_FORMAT_STAR_GLOB); } else { return lttng_ust_event_notifier_enabler_create(objd, - owner, event_notifier_param, + owner, &event_notifier, LTTNG_ENABLER_FORMAT_EVENT); } } case LTTNG_UST_ABI_COUNTER: { return lttng_ust_event_notifier_group_create_error_counter( - objd, (struct lttng_ust_abi_counter *) arg, uargs, owner); + objd, (struct lttng_ust_abi_counter_conf *) arg, uargs, owner); } default: return -EINVAL; @@ -1653,7 +1660,10 @@ long lttng_counter_cmd(int objd, unsigned int cmd, unsigned long arg, long ret; int shm_fd; - if (abi_counter_global->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_global, shm_len)) { + if (uargs->counter_shm.len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_global, shm_len)) + return -EINVAL; + if (abi_counter_global->len > uargs->counter_shm.len || + abi_counter_global->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_global, shm_len)) { return -EINVAL; } ret = copy_abi_struct(&counter_global, sizeof(counter_global), @@ -1676,7 +1686,10 @@ long lttng_counter_cmd(int objd, unsigned int cmd, unsigned long arg, long ret; int shm_fd; - if (abi_counter_cpu->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_cpu, cpu_nr)) { + if (uargs->counter_shm.len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_cpu, cpu_nr)) + return -EINVAL; + if (abi_counter_cpu->len > uargs->counter_shm.len || + abi_counter_cpu->len < lttng_ust_offsetofend(struct lttng_ust_abi_counter_cpu, cpu_nr)) { return -EINVAL; } ret = copy_abi_struct(&counter_cpu, sizeof(counter_cpu), diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index fe2437b8..69ff7e5e 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -1058,7 +1058,7 @@ int handle_message(struct sock_info *sock_info, union lttng_ust_abi_args args; char ctxstr[LTTNG_UST_ABI_SYM_NAME_LEN]; /* App context string. */ ssize_t len; - struct lttng_ust_abi_counter_event *counter_event = NULL; + void *var_len_cmd_data = NULL; memset(&lur, 0, sizeof(lur)); @@ -1393,16 +1393,14 @@ int handle_message(struct sock_info *sock_info, break; case LTTNG_UST_ABI_COUNTER: { - void *counter_data; - - len = ustcomm_recv_counter_from_sessiond(sock, - &counter_data, lum->u.counter.len); + len = ustcomm_recv_var_len_cmd_from_sessiond(sock, + &var_len_cmd_data, lum->u.var_len_cmd.cmd_len); switch (len) { case 0: /* orderly shutdown */ ret = 0; goto error; default: - if (len == lum->u.counter.len) { + if (len == lum->u.var_len_cmd.cmd_len) { DBG("counter data received"); break; } else if (len < 0) { @@ -1420,28 +1418,51 @@ int handle_message(struct sock_info *sock_info, goto error; } } - args.counter.counter_data = counter_data; + args.counter.len = lum->u.var_len_cmd.cmd_len; if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) &lum->u, + (unsigned long) var_len_cmd_data, &args, sock_info); else ret = -ENOSYS; - free(args.counter.counter_data); break; } case LTTNG_UST_ABI_COUNTER_GLOBAL: { + len = ustcomm_recv_var_len_cmd_from_sessiond(sock, + &var_len_cmd_data, lum->u.var_len_cmd.cmd_len); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + goto error; + default: + if (len == lum->u.var_len_cmd.cmd_len) { + DBG("counter data received"); + break; + } else if (len < 0) { + DBG("Receive failed from lttng-sessiond with errno %d", (int) -len); + if (len == -ECONNRESET) { + ERR("%s remote end closed connection", sock_info->name); + ret = len; + goto error; + } + ret = len; + goto error; + } else { + DBG("incorrect counter data message size: %zd", len); + ret = -EINVAL; + goto error; + } + } /* Receive shm_fd */ - ret = ustcomm_recv_counter_shm_from_sessiond(sock, - &args.counter_shm.shm_fd); + ret = ustcomm_recv_counter_shm_from_sessiond(sock, &args.counter_shm.shm_fd); if (ret) { goto error; } - + args.counter_shm.len = lum->u.var_len_cmd.cmd_len; if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) &lum->u, + (unsigned long) var_len_cmd_data, &args, sock_info); else ret = -ENOSYS; @@ -1459,16 +1480,40 @@ int handle_message(struct sock_info *sock_info, } case LTTNG_UST_ABI_COUNTER_CPU: { + len = ustcomm_recv_var_len_cmd_from_sessiond(sock, + &var_len_cmd_data, lum->u.var_len_cmd.cmd_len); + switch (len) { + case 0: /* orderly shutdown */ + ret = 0; + goto error; + default: + if (len == lum->u.var_len_cmd.cmd_len) { + DBG("counter data received"); + break; + } else if (len < 0) { + DBG("Receive failed from lttng-sessiond with errno %d", (int) -len); + if (len == -ECONNRESET) { + ERR("%s remote end closed connection", sock_info->name); + ret = len; + goto error; + } + ret = len; + goto error; + } else { + DBG("incorrect counter data message size: %zd", len); + ret = -EINVAL; + goto error; + } + } /* Receive shm_fd */ - ret = ustcomm_recv_counter_shm_from_sessiond(sock, - &args.counter_shm.shm_fd); + ret = ustcomm_recv_counter_shm_from_sessiond(sock, &args.counter_shm.shm_fd); if (ret) { goto error; } - + args.counter_shm.len = lum->u.var_len_cmd.cmd_len; if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) &lum->u, + (unsigned long) var_len_cmd_data, &args, sock_info); else ret = -ENOSYS; @@ -1486,25 +1531,14 @@ int handle_message(struct sock_info *sock_info, } case LTTNG_UST_ABI_COUNTER_EVENT: { - /* Receive struct lttng_ust_abi_counter_event */ - if (lum->u.counter_event.len > LTTNG_UST_ABI_COUNTER_EVENT_MAX_LEN) { - DBG("counter event data message too large: %u", lum->u.counter_event.len); - ret = -EINVAL; - goto error; - } - args.counter_event.len = lum->u.counter_event.len; - counter_event = zmalloc(lum->u.counter_event.len); - if (!counter_event) { - ret = -ENOMEM; - goto error; - } - len = ustcomm_recv_unix_sock(sock, counter_event, lum->u.counter_event.len); + len = ustcomm_recv_var_len_cmd_from_sessiond(sock, + &var_len_cmd_data, lum->u.var_len_cmd.cmd_len); switch (len) { case 0: /* orderly shutdown */ ret = 0; goto error; default: - if (len == lum->u.counter_event.len) { + if (len == lum->u.var_len_cmd.cmd_len) { DBG("counter event data received"); break; } else if (len < 0) { @@ -1517,14 +1551,15 @@ int handle_message(struct sock_info *sock_info, ret = len; goto error; } else { - DBG("incorrect event notifier data message size: %zd", len); + DBG("incorrect counter data message size: %zd", len); ret = -EINVAL; goto error; } } + args.counter_event.len = lum->u.var_len_cmd.cmd_len; if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) counter_event, + (unsigned long) var_len_cmd_data, &args, sock_info); else ret = -ENOSYS; @@ -1532,21 +1567,14 @@ int handle_message(struct sock_info *sock_info, } case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE: { - /* Receive struct lttng_ust_event_notifier */ - struct lttng_ust_abi_event_notifier event_notifier; - - if (sizeof(event_notifier) != lum->u.event_notifier.len) { - DBG("incorrect event notifier data message size: %u", lum->u.event_notifier.len); - ret = -EINVAL; - goto error; - } - len = ustcomm_recv_unix_sock(sock, &event_notifier, sizeof(event_notifier)); + len = ustcomm_recv_var_len_cmd_from_sessiond(sock, + &var_len_cmd_data, lum->u.var_len_cmd.cmd_len); switch (len) { case 0: /* orderly shutdown */ ret = 0; goto error; default: - if (len == sizeof(event_notifier)) { + if (len == lum->u.var_len_cmd.cmd_len) { DBG("event notifier data received"); break; } else if (len < 0) { @@ -1564,9 +1592,10 @@ int handle_message(struct sock_info *sock_info, goto error; } } + args.event_notifier.len = lum->u.var_len_cmd.cmd_len; if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, - (unsigned long) &event_notifier, + (unsigned long) var_len_cmd_data, &args, sock_info); else ret = -ENOSYS; @@ -1641,7 +1670,7 @@ int handle_message(struct sock_info *sock_info, error: ust_unlock(); - free(counter_event); + free(var_len_cmd_data); return ret; } -- 2.34.1