From: Mathieu Desnoyers Date: Fri, 8 Apr 2022 16:22:14 +0000 (-0400) Subject: ABI: add key_string_len output field in lttng_kernel_abi_counter_map_descriptor X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=83ab4b09b075a7076fc0c28fbfc21c632919a8e4;p=lttng-modules.git ABI: add key_string_len output field in lttng_kernel_abi_counter_map_descriptor Tell userspace the size of the key string. Useful to adjust memory allocation for a retry. Signed-off-by: Mathieu Desnoyers Change-Id: Ifde8f2acc841579b717b78128f8bfddbc0dfee26 --- diff --git a/include/lttng/abi.h b/include/lttng/abi.h index 2ec5d6d0..7b26dafc 100644 --- a/include/lttng/abi.h +++ b/include/lttng/abi.h @@ -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 { diff --git a/src/lttng-abi.c b/src/lttng-abi.c index ec5fc8fc..611836b7 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -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: