X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-registry.c;h=65ba82c1b99b16bb51991161bc32f42dafcadcae;hp=298ddbb6a9326c8355a98045d254de439e81785f;hb=55d097957f5bb8138959ad2202a40d85d49f029e;hpb=d5d629b58bff4ded0814e352d7dbdda6d1b6c9c2 diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c index 298ddbb6a..65ba82c1b 100644 --- a/src/bin/lttng-sessiond/ust-registry.c +++ b/src/bin/lttng-sessiond/ust-registry.c @@ -23,6 +23,7 @@ #include #include "ust-registry.h" +#include "ust-app.h" #include "utils.h" /* @@ -71,16 +72,78 @@ static unsigned long ht_hash_event(void *_key, unsigned long seed) return hash_key_u64(&xored_key, seed); } +/* + * Return negative value on error, 0 if OK. + * + * TODO: we could add stricter verification of more types to catch + * errors in liblttng-ust implementation earlier than consumption by the + * trace reader. + */ +static +int validate_event_field(struct ustctl_field *field, + const char *event_name, + struct ust_app *app) +{ + switch(field->type.atype) { + case ustctl_atype_integer: + case ustctl_atype_enum: + case ustctl_atype_array: + case ustctl_atype_sequence: + case ustctl_atype_string: + break; + + case ustctl_atype_float: + switch (field->type.u.basic._float.mant_dig) { + case 0: + WARN("UST application '%s' (pid: %d) has unknown float mantissa '%u' " + "in field '%s', rejecting event '%s'", + app->name, app->pid, + field->type.u.basic._float.mant_dig, + field->name, + event_name); + return -EINVAL; + default: + break; + } + break; + + default: + return -ENOENT; + } + return 0; +} + +static +int validate_event_fields(size_t nr_fields, struct ustctl_field *fields, + const char *event_name, struct ust_app *app) +{ + unsigned int i; + + for (i = 0; i < nr_fields; i++) { + if (validate_event_field(&fields[i], event_name, app) < 0) + return -EINVAL; + } + return 0; +} + /* * Allocate event and initialize it. This does NOT set a valid event id from a * registry. */ static struct ust_registry_event *alloc_event(int session_objd, int channel_objd, char *name, char *sig, size_t nr_fields, - struct ustctl_field *fields, int loglevel, char *model_emf_uri) + struct ustctl_field *fields, int loglevel, char *model_emf_uri, + struct ust_app *app) { struct ust_registry_event *event = NULL; + /* + * Ensure that the field content is valid. + */ + if (validate_event_fields(nr_fields, fields, name, app) < 0) { + return NULL; + } + event = zmalloc(sizeof(*event)); if (!event) { PERROR("zmalloc ust registry event"); @@ -185,7 +248,8 @@ end: int ust_registry_create_event(struct ust_registry_session *session, uint64_t chan_key, int session_objd, int channel_objd, char *name, char *sig, size_t nr_fields, struct ustctl_field *fields, int loglevel, - char *model_emf_uri, int buffer_type, uint32_t *event_id_p) + char *model_emf_uri, int buffer_type, uint32_t *event_id_p, + struct ust_app *app) { int ret; uint32_t event_id; @@ -222,7 +286,7 @@ int ust_registry_create_event(struct ust_registry_session *session, } event = alloc_event(session_objd, channel_objd, name, sig, nr_fields, - fields, loglevel, model_emf_uri); + fields, loglevel, model_emf_uri, app); if (!event) { ret = -ENOMEM; goto error_free; @@ -556,8 +620,6 @@ void ust_registry_session_destroy(struct ust_registry_session *reg) } rcu_read_unlock(); - if (reg->channels) { - ht_cleanup_push(reg->channels); - } + ht_cleanup_push(reg->channels); free(reg->metadata); }