X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Fevent-rule%2Fkprobe.c;h=37592962b2181c6c4f7794c6dd83e8e8821b5ed8;hb=f27911615bc5907d61d8ea236da974090bd85d24;hp=a5c93e653f08784dbb4af8997dc1d14c66ba80c9;hpb=077192fd1880652a61400b493a0b6cf5bb199435;p=lttng-tools.git diff --git a/src/common/event-rule/kprobe.c b/src/common/event-rule/kprobe.c index a5c93e653..37592962b 100644 --- a/src/common/event-rule/kprobe.c +++ b/src/common/event-rule/kprobe.c @@ -6,11 +6,14 @@ */ #include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -20,34 +23,34 @@ #include #define IS_KPROBE_EVENT_RULE(rule) \ - (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KPROBE) + (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE) #if (LTTNG_SYMBOL_NAME_LEN == 256) #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255" #endif -static void lttng_event_rule_kprobe_destroy(struct lttng_event_rule *rule) +static void lttng_event_rule_kernel_probe_destroy(struct lttng_event_rule *rule) { - struct lttng_event_rule_kprobe *kprobe; + struct lttng_event_rule_kernel_probe *kprobe; - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); lttng_kernel_probe_location_destroy(kprobe->location); free(kprobe->name); free(kprobe); } -static bool lttng_event_rule_kprobe_validate( +static bool lttng_event_rule_kernel_probe_validate( const struct lttng_event_rule *rule) { bool valid = false; - struct lttng_event_rule_kprobe *kprobe; + struct lttng_event_rule_kernel_probe *kprobe; if (!rule) { goto end; } - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); /* Required field. */ if (!kprobe->name) { @@ -66,15 +69,15 @@ end: return valid; } -static int lttng_event_rule_kprobe_serialize( +static int lttng_event_rule_kernel_probe_serialize( const struct lttng_event_rule *rule, struct lttng_payload *payload) { int ret; size_t name_len, header_offset, size_before_location; - struct lttng_event_rule_kprobe *kprobe; - struct lttng_event_rule_kprobe_comm kprobe_comm; - struct lttng_event_rule_kprobe_comm *header; + struct lttng_event_rule_kernel_probe *kprobe; + struct lttng_event_rule_kernel_probe_comm kprobe_comm; + struct lttng_event_rule_kernel_probe_comm *header; if (!rule || !IS_KPROBE_EVENT_RULE(rule)) { ret = -1; @@ -84,7 +87,7 @@ static int lttng_event_rule_kprobe_serialize( header_offset = payload->buffer.size; DBG("Serializing kprobe event rule."); - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); name_len = strlen(kprobe->name) + 1; kprobe_comm.name_len = name_len; @@ -108,7 +111,7 @@ static int lttng_event_rule_kprobe_serialize( } /* Update the header regarding the probe size. */ - header = (struct lttng_event_rule_kprobe_comm*) ( + header = (struct lttng_event_rule_kernel_probe_comm*) ( (char *) payload->buffer.data + header_offset); header->location_len = payload->buffer.size - size_before_location; @@ -118,14 +121,14 @@ end: return ret; } -static bool lttng_event_rule_kprobe_is_equal(const struct lttng_event_rule *_a, +static bool lttng_event_rule_kernel_probe_is_equal(const struct lttng_event_rule *_a, const struct lttng_event_rule *_b) { bool is_equal = false; - struct lttng_event_rule_kprobe *a, *b; + struct lttng_event_rule_kernel_probe *a, *b; - a = container_of(_a, struct lttng_event_rule_kprobe, parent); - b = container_of(_b, struct lttng_event_rule_kprobe, parent); + a = container_of(_a, struct lttng_event_rule_kernel_probe, parent); + b = container_of(_b, struct lttng_event_rule_kernel_probe, parent); /* Quick checks */ if (!!a->name != !!b->name) { @@ -145,73 +148,93 @@ end: return is_equal; } -static enum lttng_error_code lttng_event_rule_kprobe_generate_filter_bytecode( - struct lttng_event_rule *rule, uid_t uid, gid_t gid) +static enum lttng_error_code lttng_event_rule_kernel_probe_generate_filter_bytecode( + struct lttng_event_rule *rule, + const struct lttng_credentials *creds) { /* Nothing to do. */ return LTTNG_OK; } -static const char *lttng_event_rule_kprobe_get_filter( +static const char *lttng_event_rule_kernel_probe_get_filter( const struct lttng_event_rule *rule) { /* Not supported. */ return NULL; } -static const struct lttng_filter_bytecode * -lttng_event_rule_kprobe_get_filter_bytecode(const struct lttng_event_rule *rule) +static const struct lttng_bytecode * +lttng_event_rule_kernel_probe_get_filter_bytecode(const struct lttng_event_rule *rule) { /* Not supported. */ return NULL; } -static struct lttng_event_exclusion * -lttng_event_rule_kprobe_generate_exclusions(const struct lttng_event_rule *rule) +static enum lttng_event_rule_generate_exclusions_status +lttng_event_rule_kernel_probe_generate_exclusions(const struct lttng_event_rule *rule, + struct lttng_event_exclusion **exclusions) { /* Not supported. */ - return NULL; + *exclusions = NULL; + return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE; } -struct lttng_event_rule *lttng_event_rule_kprobe_create() +static unsigned long +lttng_event_rule_kernel_probe_hash( + const struct lttng_event_rule *rule) +{ + unsigned long hash; + struct lttng_event_rule_kernel_probe *krule = + container_of(rule, typeof(*krule), parent); + + hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE, + lttng_ht_seed); + hash ^= hash_key_str(krule->name, lttng_ht_seed); + hash ^= lttng_kernel_probe_location_hash(krule->location); + + return hash; +} + +struct lttng_event_rule *lttng_event_rule_kernel_probe_create(void) { struct lttng_event_rule *rule = NULL; - struct lttng_event_rule_kprobe *krule; + struct lttng_event_rule_kernel_probe *krule; - krule = zmalloc(sizeof(struct lttng_event_rule_kprobe)); + krule = zmalloc(sizeof(struct lttng_event_rule_kernel_probe)); if (!krule) { goto end; } rule = &krule->parent; - lttng_event_rule_init(&krule->parent, LTTNG_EVENT_RULE_TYPE_KPROBE); - krule->parent.validate = lttng_event_rule_kprobe_validate; - krule->parent.serialize = lttng_event_rule_kprobe_serialize; - krule->parent.equal = lttng_event_rule_kprobe_is_equal; - krule->parent.destroy = lttng_event_rule_kprobe_destroy; + lttng_event_rule_init(&krule->parent, LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE); + krule->parent.validate = lttng_event_rule_kernel_probe_validate; + krule->parent.serialize = lttng_event_rule_kernel_probe_serialize; + krule->parent.equal = lttng_event_rule_kernel_probe_is_equal; + krule->parent.destroy = lttng_event_rule_kernel_probe_destroy; krule->parent.generate_filter_bytecode = - lttng_event_rule_kprobe_generate_filter_bytecode; - krule->parent.get_filter = lttng_event_rule_kprobe_get_filter; + lttng_event_rule_kernel_probe_generate_filter_bytecode; + krule->parent.get_filter = lttng_event_rule_kernel_probe_get_filter; krule->parent.get_filter_bytecode = - lttng_event_rule_kprobe_get_filter_bytecode; + lttng_event_rule_kernel_probe_get_filter_bytecode; krule->parent.generate_exclusions = - lttng_event_rule_kprobe_generate_exclusions; + lttng_event_rule_kernel_probe_generate_exclusions; + krule->parent.hash = lttng_event_rule_kernel_probe_hash; end: return rule; } LTTNG_HIDDEN -ssize_t lttng_event_rule_kprobe_create_from_payload( +ssize_t lttng_event_rule_kernel_probe_create_from_payload( struct lttng_payload_view *view, struct lttng_event_rule **_event_rule) { ssize_t ret, offset = 0; enum lttng_event_rule_status status; - const struct lttng_event_rule_kprobe_comm *kprobe_comm; + const struct lttng_event_rule_kernel_probe_comm *kprobe_comm; const char *name; struct lttng_buffer_view current_buffer_view; struct lttng_event_rule *rule = NULL; - struct lttng_event_rule_kprobe *kprobe = NULL; + struct lttng_event_rule_kernel_probe *kprobe = NULL; struct lttng_kernel_probe_location *location; if (!_event_rule) { @@ -219,28 +242,24 @@ ssize_t lttng_event_rule_kprobe_create_from_payload( goto end; } - if (view->buffer.size < sizeof(*kprobe_comm)) { + current_buffer_view = lttng_buffer_view_from_view( + &view->buffer, offset, sizeof(*kprobe_comm)); + if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { ERR("Failed to initialize from malformed event rule kprobe: buffer too short to contain header."); ret = -1; goto end; } - current_buffer_view = lttng_buffer_view_from_view( - &view->buffer, offset, sizeof(*kprobe_comm)); kprobe_comm = (typeof(kprobe_comm)) current_buffer_view.data; - if (!kprobe_comm) { - ret = -1; - goto end; - } - rule = lttng_event_rule_kprobe_create(); + rule = lttng_event_rule_kernel_probe_create(); if (!rule) { ERR("Failed to create event rule kprobe."); ret = -1; goto end; } - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); /* Skip to payload */ offset += current_buffer_view.size; @@ -251,12 +270,12 @@ ssize_t lttng_event_rule_kprobe_create_from_payload( lttng_payload_view_from_view(view, offset, kprobe_comm->name_len); - name = current_payload_view.buffer.data; - if (!name) { + if (!lttng_payload_view_is_valid(¤t_payload_view)) { ret = -1; goto end; } + name = current_payload_view.buffer.data; if (!lttng_buffer_view_contains_string( ¤t_payload_view.buffer, name, kprobe_comm->name_len)) { @@ -274,6 +293,11 @@ ssize_t lttng_event_rule_kprobe_create_from_payload( lttng_payload_view_from_view(view, offset, kprobe_comm->location_len); + if (!lttng_payload_view_is_valid(¤t_payload_view)) { + ret = -1; + goto end; + } + ret = lttng_kernel_probe_location_create_from_payload( ¤t_payload_view, &location); if (ret < 0) { @@ -292,7 +316,7 @@ ssize_t lttng_event_rule_kprobe_create_from_payload( /* Skip after the location */ offset += kprobe_comm->location_len; - status = lttng_event_rule_kprobe_set_name(rule, name); + status = lttng_event_rule_kernel_probe_set_name(rule, name); if (status != LTTNG_EVENT_RULE_STATUS_OK) { ERR("Failed to set event rule kprobe name."); ret = -1; @@ -307,12 +331,12 @@ end: return ret; } -enum lttng_event_rule_status lttng_event_rule_kprobe_set_location( +enum lttng_event_rule_status lttng_event_rule_kernel_probe_set_location( struct lttng_event_rule *rule, const struct lttng_kernel_probe_location *location) { struct lttng_kernel_probe_location *location_copy = NULL; - struct lttng_event_rule_kprobe *kprobe; + struct lttng_event_rule_kernel_probe *kprobe; enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !location) { @@ -320,7 +344,7 @@ enum lttng_event_rule_status lttng_event_rule_kprobe_set_location( goto end; } - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); location_copy = lttng_kernel_probe_location_copy(location); if (!location_copy) { status = LTTNG_EVENT_RULE_STATUS_ERROR; @@ -338,19 +362,19 @@ end: return status; } -enum lttng_event_rule_status lttng_event_rule_kprobe_get_location( +enum lttng_event_rule_status lttng_event_rule_kernel_probe_get_location( const struct lttng_event_rule *rule, const struct lttng_kernel_probe_location **location) { enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; - struct lttng_event_rule_kprobe *kprobe; + struct lttng_event_rule_kernel_probe *kprobe; if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !location) { status = LTTNG_EVENT_RULE_STATUS_INVALID; goto end; } - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); *location = kprobe->location; if (!*location) { @@ -362,11 +386,11 @@ end: return status; } -enum lttng_event_rule_status lttng_event_rule_kprobe_set_name( +enum lttng_event_rule_status lttng_event_rule_kernel_probe_set_name( struct lttng_event_rule *rule, const char *name) { char *name_copy = NULL; - struct lttng_event_rule_kprobe *kprobe; + struct lttng_event_rule_kernel_probe *kprobe; enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !name || @@ -375,7 +399,7 @@ enum lttng_event_rule_status lttng_event_rule_kprobe_set_name( goto end; } - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); name_copy = strdup(name); if (!name_copy) { status = LTTNG_EVENT_RULE_STATUS_ERROR; @@ -390,10 +414,10 @@ end: return status; } -enum lttng_event_rule_status lttng_event_rule_kprobe_get_name( +enum lttng_event_rule_status lttng_event_rule_kernel_probe_get_name( const struct lttng_event_rule *rule, const char **name) { - struct lttng_event_rule_kprobe *kprobe; + struct lttng_event_rule_kernel_probe *kprobe; enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; if (!rule || !IS_KPROBE_EVENT_RULE(rule) || !name) { @@ -401,7 +425,7 @@ enum lttng_event_rule_status lttng_event_rule_kprobe_get_name( goto end; } - kprobe = container_of(rule, struct lttng_event_rule_kprobe, parent); + kprobe = container_of(rule, struct lttng_event_rule_kernel_probe, parent); if (!kprobe->name) { status = LTTNG_EVENT_RULE_STATUS_UNSET; goto end;