ABI: add key_string_len output field in lttng_kernel_abi_counter_map_descriptor
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 8 Apr 2022 16:22:14 +0000 (12:22 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Jul 2024 21:01:43 +0000 (17:01 -0400)
Tell userspace the size of the key string. Useful to adjust memory
allocation for a retry.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Ifde8f2acc841579b717b78128f8bfddbc0dfee26

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

index 2ec5d6d0fbdd9275b0b21ea20cc37388012c4e95..7b26dafc5b238e87ef1498ea88c399b15e489086 100644 (file)
@@ -210,18 +210,20 @@ enum lttng_kernel_abi_counter_bitness {
 };
 
 struct lttng_kernel_abi_counter_key_string {
-       uint32_t string_len;
-       char str[];     /* Null-terminated string. */
+       uint32_t string_len;            /* string length allocated by user-space (input) (includes \0) */
+       char str[];                     /* Null-terminated string. */
 } __attribute__((packed));
 
 struct lttng_kernel_abi_counter_map_descriptor {
        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;
        uint64_t key_ptr;               /* pointer to struct lttng_kernel_abi_counter_key_string */
+       uint32_t key_string_len;        /* key string length (includes \0) */
 } __attribute__((packed));
 
 struct lttng_kernel_abi_key_token {
index ec5fc8fcb59741484577d067f3150e83da0e7fd8..611836b739ee2feda715ee21b057e5dec5f112b0 100644 (file)
@@ -1172,7 +1172,7 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                struct lttng_counter_map_descriptor *descriptor;
                char key[LTTNG_KERNEL_COUNTER_KEY_LEN] = {};
                size_t key_strlen;
-               uint32_t len, ukey_string_len;
+               uint32_t len;
                int ret;
 
                ret = get_user(len, &udescriptor->len);
@@ -1185,14 +1185,6 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                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 (kdescriptor.descriptor_index >= counter->priv->map.nr_descriptors) {
@@ -1205,13 +1197,24 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                memcpy(&key, descriptor->key, LTTNG_KERNEL_COUNTER_KEY_LEN);
                mutex_unlock(&counter->priv->map.lock);
 
-               key_strlen = strlen(key);
-               if (key_strlen >= ukey_string_len)
-                       return -ENOSPC;
+               key_strlen = strlen(key) + 1;
+               kdescriptor.key_string_len = key_strlen;
                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;
+               ukey_ptr = (struct lttng_kernel_abi_counter_key_string __user *)(unsigned long)kdescriptor.key_ptr;
+               if (ukey_ptr) {
+                       uint32_t ukey_string_len;
+
+                       ret = get_user(ukey_string_len, &ukey_ptr->string_len);
+                       if (ret)
+                               return ret;
+                       if (ukey_string_len > PAGE_SIZE)
+                               return -E2BIG;
+                       if (key_strlen > ukey_string_len)
+                               return -ENOSPC;
+                       if (copy_to_user(ukey_ptr->str, key, key_strlen))
+                               return -EFAULT;
+               }
                return 0;
 
        map_descriptor_error_unlock:
This page took 0.028371 seconds and 4 git commands to generate.