};
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 {
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);
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) {
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: