return 0;
 }
 
-static int btf_parse_hdr(struct btf_verifier_env *env, void __user *btf_data,
-                        u32 btf_data_size)
+static int btf_parse_hdr(struct btf_verifier_env *env)
 {
+       u32 hdr_len, hdr_copy, btf_data_size;
        const struct btf_header *hdr;
-       u32 hdr_len, hdr_copy;
-       /*
-        * Minimal part of the "struct btf_header" that
-        * contains the hdr_len.
-        */
-       struct btf_min_header {
-               u16     magic;
-               u8      version;
-               u8      flags;
-               u32     hdr_len;
-       } __user *min_hdr;
        struct btf *btf;
        int err;
 
        btf = env->btf;
-       min_hdr = btf_data;
+       btf_data_size = btf->data_size;
 
-       if (btf_data_size < sizeof(*min_hdr)) {
+       if (btf_data_size <
+           offsetof(struct btf_header, hdr_len) + sizeof(hdr->hdr_len)) {
                btf_verifier_log(env, "hdr_len not found");
                return -EINVAL;
        }
 
-       if (get_user(hdr_len, &min_hdr->hdr_len))
-               return -EFAULT;
-
+       hdr = btf->data;
+       hdr_len = hdr->hdr_len;
        if (btf_data_size < hdr_len) {
                btf_verifier_log(env, "btf_header not found");
                return -EINVAL;
        }
 
-       err = bpf_check_uarg_tail_zero(btf_data, sizeof(btf->hdr), hdr_len);
-       if (err) {
-               if (err == -E2BIG)
-                       btf_verifier_log(env, "Unsupported btf_header");
-               return err;
+       /* Ensure the unsupported header fields are zero */
+       if (hdr_len > sizeof(btf->hdr)) {
+               u8 *expected_zero = btf->data + sizeof(btf->hdr);
+               u8 *end = btf->data + hdr_len;
+
+               for (; expected_zero < end; expected_zero++) {
+                       if (*expected_zero) {
+                               btf_verifier_log(env, "Unsupported btf_header");
+                               return -E2BIG;
+                       }
+               }
        }
 
        hdr_copy = min_t(u32, hdr_len, sizeof(btf->hdr));
-       if (copy_from_user(&btf->hdr, btf_data, hdr_copy))
-               return -EFAULT;
+       memcpy(&btf->hdr, btf->data, hdr_copy);
 
        hdr = &btf->hdr;
 
-       if (hdr->hdr_len != hdr_len)
-               return -EINVAL;
-
        btf_verifier_log_hdr(env, btf_data_size);
 
        if (hdr->magic != BTF_MAGIC) {
        }
        env->btf = btf;
 
-       err = btf_parse_hdr(env, btf_data, btf_data_size);
-       if (err)
-               goto errout;
-
        data = kvmalloc(btf_data_size, GFP_KERNEL | __GFP_NOWARN);
        if (!data) {
                err = -ENOMEM;
 
        btf->data = data;
        btf->data_size = btf_data_size;
-       btf->nohdr_data = btf->data + btf->hdr.hdr_len;
 
        if (copy_from_user(data, btf_data, btf_data_size)) {
                err = -EFAULT;
                goto errout;
        }
 
+       err = btf_parse_hdr(env);
+       if (err)
+               goto errout;
+
+       btf->nohdr_data = btf->data + btf->hdr.hdr_len;
+
        err = btf_parse_str_sec(env);
        if (err)
                goto errout;