Implement extensible LTTNG_KERNEL_ABI_COUNTER_MAP_DESCRIPTOR
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 24 Mar 2022 18:38:20 +0000 (14:38 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Jul 2024 21:01:43 +0000 (17:01 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Ibd16679a5e3354553a9b606a6f3a5f9f2692836d

include/lttng/abi.h
include/lttng/events-internal.h
src/lttng-abi.c
src/lttng-events.c

index a512c54cd457d7b6ba0a4a515fbb74bef479ee8b..ac5469edc7af106e96a959a2dc756a2509d956e2 100644 (file)
@@ -212,18 +212,19 @@ enum lttng_kernel_abi_counter_bitness {
 //TODO: remove this define.
 #define LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX 4
 
-//TODO: new in 2.14, update.
-#define LTTNG_KERNEL_ABI_COUNTER_KEY_LEN 256
-#define LTTNG_KERNEL_ABI_COUNTER_MAP_DESCRIPTOR_PADDING 32
+struct lttng_kernel_abi_counter_key_string {
+       uint32_t string_len;
+       char str[];     /* Null-terminated string. */
+} __attribute__((packed));
+
 struct lttng_kernel_abi_counter_map_descriptor {
-       uint64_t descriptor_index;      /* input. [ 0 .. nr_descriptors - 1 ] */
+       uint32_t len;                   /* length of this structure */
 
+       uint64_t descriptor_index;      /* input. [ 0 .. nr_descriptors - 1 ] */
        uint32_t dimension;             /* outputs */
        uint64_t array_index;
        uint64_t user_token;
-       char key[LTTNG_KERNEL_ABI_COUNTER_KEY_LEN];
-
-       char padding[LTTNG_KERNEL_ABI_COUNTER_MAP_DESCRIPTOR_PADDING];
+       uint64_t key_ptr;               /* pointer to struct lttng_kernel_abi_counter_key_string */
 } __attribute__((packed));
 
 //TODO: new in 2.14, update.
@@ -506,7 +507,7 @@ struct lttng_kernel_abi_tracker_args {
 #define LTTNG_KERNEL_ABI_ENABLE                        _IO(0xF6, 0x82)
 #define LTTNG_KERNEL_ABI_DISABLE                       _IO(0xF6, 0x83)
 
-/* Trigger group and session ioctl */
+/* Event notifier group and session ioctl */
 
 /* (0xF6, 0x84) is reserved for old ABI. */
 
index b4d2277ba41e0a467d731fe3e67fa0db67ac59a1..21ab79262271e24c9a429c9f0ee54962acaaf5f2 100644 (file)
@@ -261,10 +261,11 @@ struct lttng_kernel_channel_counter_ops_private {
                        size_t *max_nr_elem);   /* array of size nr_dimensions */
 };
 
+#define LTTNG_KERNEL_COUNTER_KEY_LEN           256
 struct lttng_counter_map_descriptor {
        uint64_t user_token;
        size_t array_index;
-       char key[LTTNG_KERNEL_ABI_COUNTER_KEY_LEN];
+       char key[LTTNG_KERNEL_COUNTER_KEY_LEN];
 };
 
 struct lttng_counter_map {
index ffe0f10940e9bfa8d616cba9e184cb454592894f..6471aa669e5f2072c744a6073c1f469718e082f8 100644 (file)
@@ -965,34 +965,53 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        }
        case LTTNG_KERNEL_ABI_COUNTER_MAP_DESCRIPTOR:
        {
-               struct lttng_kernel_abi_counter_map_descriptor __user *user_descriptor =
+               struct lttng_kernel_abi_counter_map_descriptor __user *udescriptor =
                        (struct lttng_kernel_abi_counter_map_descriptor __user *) arg;
-               struct lttng_kernel_abi_counter_map_descriptor local_descriptor;
-               struct lttng_counter_map_descriptor *kernel_descriptor;
+               struct lttng_kernel_abi_counter_key_string __user *ukey_ptr;
+               struct lttng_kernel_abi_counter_map_descriptor kdescriptor = {};
+               struct lttng_counter_map_descriptor *descriptor;
+               char key[LTTNG_KERNEL_COUNTER_KEY_LEN] = {};
+               size_t key_strlen;
+               uint32_t len, ukey_string_len;
                int ret;
 
-               if (copy_from_user(&local_descriptor, user_descriptor,
-                                       sizeof(local_descriptor)))
-                       return -EFAULT;
-               if (validate_zeroed_padding(local_descriptor.padding,
-                               sizeof(local_descriptor.padding)))
+               ret = get_user(len, &udescriptor->len);
+               if (ret)
+                       return ret;
+               if (len > PAGE_SIZE)
+                       return -E2BIG;
+               if (!len || len < offsetofend(struct lttng_kernel_abi_counter_map_descriptor, key_ptr))
+                       return -EINVAL;
+               ret = lttng_copy_struct_from_user(&kdescriptor, sizeof(kdescriptor), udescriptor, len);
+               if (ret)
+                       return ret;
+               ukey_ptr = (struct lttng_kernel_abi_counter_key_string __user *)(unsigned long)kdescriptor.key_ptr;
+               ret = get_user(ukey_string_len, &ukey_ptr->string_len);
+               if (ret)
+                       return ret;
+               if (ukey_string_len > PAGE_SIZE)
+                       return -E2BIG;
+               if (!ukey_string_len)
                        return -EINVAL;
 
                mutex_lock(&counter->priv->map.lock);
-               if (local_descriptor.descriptor_index >= counter->priv->map.nr_descriptors) {
+               if (kdescriptor.descriptor_index >= counter->priv->map.nr_descriptors) {
                        ret = -EOVERFLOW;
                        goto map_descriptor_error_unlock;
                }
-               kernel_descriptor = &counter->priv->map.descriptors[local_descriptor.descriptor_index];
-               local_descriptor.user_token = kernel_descriptor->user_token;
-               local_descriptor.array_index = kernel_descriptor->array_index;
-               memcpy(local_descriptor.key, kernel_descriptor->key, LTTNG_KERNEL_ABI_COUNTER_KEY_LEN);
+               descriptor = &counter->priv->map.descriptors[kdescriptor.descriptor_index];
+               kdescriptor.user_token = descriptor->user_token;
+               kdescriptor.array_index = descriptor->array_index;
+               memcpy(&key, descriptor->key, LTTNG_KERNEL_COUNTER_KEY_LEN);
                mutex_unlock(&counter->priv->map.lock);
 
-               if (copy_to_user(user_descriptor, &local_descriptor,
-                                       sizeof(local_descriptor)))
+               key_strlen = strlen(key);
+               if (key_strlen >= ukey_string_len)
+                       return -ENOSPC;
+               if (copy_to_user(udescriptor, &kdescriptor, min(sizeof(kdescriptor), (size_t)len)))
+                       return -EFAULT;
+               if (copy_to_user(ukey_ptr->str, key, key_strlen + 1))
                        return -EFAULT;
-
                return 0;
 
        map_descriptor_error_unlock:
index 007fe80ebac10bc8c157fb814a3b4781cfc65469..72dcbe400286e034f5bab11fe39e124f9fd8df58 100644 (file)
@@ -1316,7 +1316,7 @@ int lttng_counter_append_descriptor(struct lttng_kernel_channel_counter *counter
        struct lttng_counter_map_descriptor *last;
        int ret = 0;
 
-       if (strlen(key) >= LTTNG_KERNEL_ABI_COUNTER_KEY_LEN) {
+       if (strlen(key) >= LTTNG_KERNEL_COUNTER_KEY_LEN) {
                WARN_ON_ONCE(1);
                return -EOVERFLOW;
        }
This page took 0.029582 seconds and 4 git commands to generate.