size parameter, and the value of the constant matters for program safety, __k
 suffix should be used.
 
+2.2.2 __uninit Annotation
+--------------------
+
+This annotation is used to indicate that the argument will be treated as
+uninitialized.
+
+An example is given below::
+
+        __bpf_kfunc int bpf_dynptr_from_skb(..., struct bpf_dynptr_kern *ptr__uninit)
+        {
+        ...
+        }
+
+Here, the dynptr will be treated as an uninitialized dynptr. Without this
+annotation, the verifier will reject the program if the dynptr passed in is
+not initialized.
+
 .. _BPF_kfunc_nodef:
 
 2.3 Using an existing kernel function
 
        return __kfunc_param_match_suffix(btf, arg, "__alloc");
 }
 
+static bool is_kfunc_arg_uninit(const struct btf *btf, const struct btf_param *arg)
+{
+       return __kfunc_param_match_suffix(btf, arg, "__uninit");
+}
+
 static bool is_kfunc_arg_scalar_with_name(const struct btf *btf,
                                          const struct btf_param *arg,
                                          const char *name)
                                return ret;
                        break;
                case KF_ARG_PTR_TO_DYNPTR:
+               {
+                       enum bpf_arg_type dynptr_arg_type = ARG_PTR_TO_DYNPTR;
+
                        if (reg->type != PTR_TO_STACK &&
                            reg->type != CONST_PTR_TO_DYNPTR) {
                                verbose(env, "arg#%d expected pointer to stack or dynptr_ptr\n", i);
                                return -EINVAL;
                        }
 
-                       ret = process_dynptr_func(env, regno, insn_idx,
-                                                 ARG_PTR_TO_DYNPTR | MEM_RDONLY);
+                       if (reg->type == CONST_PTR_TO_DYNPTR)
+                               dynptr_arg_type |= MEM_RDONLY;
+
+                       if (is_kfunc_arg_uninit(btf, &args[i]))
+                               dynptr_arg_type |= MEM_UNINIT;
+
+                       ret = process_dynptr_func(env, regno, insn_idx, dynptr_arg_type);
                        if (ret < 0)
                                return ret;
                        break;
+               }
                case KF_ARG_PTR_TO_LIST_HEAD:
                        if (reg->type != PTR_TO_MAP_VALUE &&
                            reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {