Implement copy_user_event_param_ext with lttng_copy_struct_from_user
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 24 Mar 2022 15:17:52 +0000 (11:17 -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: I55b0c811acc0c09374091dfa2cdc7535d22c9f34

src/lttng-abi.c

index 5c7c58a4326d00d50ceeb29765921a671c88e64b..cfa1307a7bdfd422e9b9e70abc1d9ec146e57bd0 100644 (file)
@@ -646,32 +646,31 @@ int copy_user_event_param_ext(struct lttng_kernel_abi_event_ext *event_param_ext
        uint32_t len;
        int ret;
 
-       memset(event_param_ext, 0, sizeof(*event_param_ext));
        /* Use zeroed defaults if extension parameters are not set. */
        if (!uevent_ext)
                return 0;
        ret = get_user(len, &uevent_ext->len);
        if (ret)
                return ret;
-       if (len > sizeof(struct lttng_kernel_abi_event_ext)) {
-               size_t zeroes_len = len - sizeof(struct lttng_kernel_abi_event_ext);
-               char __user *zeroes_begin = (char __user *)uevent_ext +
-                                               sizeof(struct lttng_kernel_abi_event_ext);
-
-               /*
-                * Userspace exposes unknown features. Make sure those are
-                * zeroed (default).
-                */
-               ret = check_zeroed_user(zeroes_begin, zeroes_len);
-               if (ret < 0)
-                       return ret;
-               if (!ret)
-                       return -E2BIG;
-       }
-       if (copy_from_user(event_param_ext, uevent_ext, len))
-               return -EFAULT;
+       if (len > PAGE_SIZE)
+               return -E2BIG;
+       ret = lttng_copy_struct_from_user(event_param_ext, sizeof(*event_param_ext), uevent_ext, len);
+       if (ret)
+               return ret;
        /* Ensure that len is consistent with the initial get_user(). */
        event_param_ext->len = len;
+
+       /* Validate that we know of all flags and enum values used. */
+       switch (event_param_ext->match_check) {
+       case LTTNG_KERNEL_ABI_MATCH_DEFAULT:
+               lttng_fallthrough;
+       case LTTNG_KERNEL_ABI_MATCH_IMMEDIATE:
+               lttng_fallthrough;
+       case LTTNG_KERNEL_ABI_MATCH_LAZY:
+               break;
+       default:
+               return -EINVAL;
+       }
        return 0;
 }
 
@@ -684,14 +683,6 @@ int user_event_param_ext_get_match_check(const struct lttng_kernel_abi_event_ext
        if (event_param_ext->len < offsetofend(struct lttng_kernel_abi_event_ext, match_check))
                goto end;
        match_check = event_param_ext->match_check;
-       switch (match_check) {
-       case LTTNG_KERNEL_ABI_MATCH_DEFAULT:
-       case LTTNG_KERNEL_ABI_MATCH_IMMEDIATE:
-       case LTTNG_KERNEL_ABI_MATCH_LAZY:
-               break;
-       default:
-               return -EINVAL;
-       }
 end:
        *_match_check = match_check;
        return 0;
@@ -804,7 +795,7 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                (struct lttng_kernel_abi_counter_event __user *) arg;
                struct lttng_kernel_abi_event *event_param;
                struct lttng_kernel_abi_counter_key *key_param;
-               struct lttng_kernel_abi_event_ext event_param_ext;
+               struct lttng_kernel_abi_event_ext event_param_ext = {};
                long ret;
 
                counter_event_param = kzalloc(sizeof(*counter_event_param), GFP_KERNEL);
@@ -2876,7 +2867,7 @@ long lttng_event_notifier_group_ioctl(struct file *file, unsigned int cmd,
        case LTTNG_KERNEL_ABI_EVENT_NOTIFIER_CREATE:
        {
                struct lttng_kernel_abi_event_notifier uevent_notifier_param;
-               struct lttng_kernel_abi_event_ext uevent_param_ext;
+               struct lttng_kernel_abi_event_ext uevent_param_ext = {};
                int ret;
 
                if (copy_from_user(&uevent_notifier_param,
@@ -3026,7 +3017,7 @@ old_event_end:
        case LTTNG_KERNEL_ABI_EVENT:
        {
                struct lttng_kernel_abi_event uevent_param;
-               struct lttng_kernel_abi_event_ext uevent_param_ext;
+               struct lttng_kernel_abi_event_ext uevent_param_ext = {};
                int ret;
 
                if (copy_from_user(&uevent_param,
This page took 0.027706 seconds and 4 git commands to generate.