int btf_struct_access(struct bpf_verifier_log *log,
                      const struct bpf_reg_state *reg,
                      int off, int size, enum bpf_access_type atype,
-                     u32 *next_btf_id, enum bpf_type_flag *flag);
+                     u32 *next_btf_id, enum bpf_type_flag *flag, const char **field_name);
 bool btf_struct_ids_match(struct bpf_verifier_log *log,
                          const struct btf *btf, u32 id, int off,
                          const struct btf *need_btf, u32 need_type_id,
 
 bool btf_nested_type_is_trusted(struct bpf_verifier_log *log,
                                const struct bpf_reg_state *reg,
-                               int off, const char *suffix);
+                               const char *field_name, u32 btf_id, const char *suffix);
 
 bool btf_type_ids_nocast_alias(struct bpf_verifier_log *log,
                               const struct btf *reg_btf, u32 reg_id,
 static inline int btf_struct_access(struct bpf_verifier_log *log,
                                    const struct bpf_reg_state *reg,
                                    int off, int size, enum bpf_access_type atype,
-                                   u32 *next_btf_id, enum bpf_type_flag *flag)
+                                   u32 *next_btf_id, enum bpf_type_flag *flag,
+                                   const char **field_name)
 {
        return -EACCES;
 }
 
 
 static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
                           const struct btf_type *t, int off, int size,
-                          u32 *next_btf_id, enum bpf_type_flag *flag)
+                          u32 *next_btf_id, enum bpf_type_flag *flag,
+                          const char **field_name)
 {
        u32 i, moff, mtrue_end, msize = 0, total_nelems = 0;
        const struct btf_type *mtype, *elem_type = NULL;
                        if (btf_type_is_struct(stype)) {
                                *next_btf_id = id;
                                *flag |= tmp_flag;
+                               if (field_name)
+                                       *field_name = mname;
                                return WALK_PTR;
                        }
                }
 int btf_struct_access(struct bpf_verifier_log *log,
                      const struct bpf_reg_state *reg,
                      int off, int size, enum bpf_access_type atype __maybe_unused,
-                     u32 *next_btf_id, enum bpf_type_flag *flag)
+                     u32 *next_btf_id, enum bpf_type_flag *flag,
+                     const char **field_name)
 {
        const struct btf *btf = reg->btf;
        enum bpf_type_flag tmp_flag = 0;
 
        t = btf_type_by_id(btf, id);
        do {
-               err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag);
+               err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag, field_name);
 
                switch (err) {
                case WALK_PTR:
        type = btf_type_by_id(btf, id);
        if (!type)
                return false;
-       err = btf_struct_walk(log, btf, type, off, 1, &id, &flag);
+       err = btf_struct_walk(log, btf, type, off, 1, &id, &flag, NULL);
        if (err != WALK_STRUCT)
                return false;
 
 
 bool btf_nested_type_is_trusted(struct bpf_verifier_log *log,
                                const struct bpf_reg_state *reg,
-                               int off, const char *suffix)
+                               const char *field_name, u32 btf_id, const char *suffix)
 {
        struct btf *btf = reg->btf;
        const struct btf_type *walk_type, *safe_type;
        const char *tname;
        char safe_tname[64];
        long ret, safe_id;
-       const struct btf_member *member, *m_walk = NULL;
+       const struct btf_member *member;
        u32 i;
-       const char *walk_name;
 
        walk_type = btf_type_by_id(btf, reg->btf_id);
        if (!walk_type)
        if (!safe_type)
                return false;
 
-       for_each_member(i, walk_type, member) {
-               u32 moff;
-
-               /* We're looking for the PTR_TO_BTF_ID member in the struct
-                * type we're walking which matches the specified offset.
-                * Below, we'll iterate over the fields in the safe variant of
-                * the struct and see if any of them has a matching type /
-                * name.
-                */
-               moff = __btf_member_bit_offset(walk_type, member) / 8;
-               if (off == moff) {
-                       m_walk = member;
-                       break;
-               }
-       }
-       if (m_walk == NULL)
-               return false;
-
-       walk_name = __btf_name_by_offset(btf, m_walk->name_off);
        for_each_member(i, safe_type, member) {
                const char *m_name = __btf_name_by_offset(btf, member->name_off);
+               const struct btf_type *mtype = btf_type_by_id(btf, member->type);
+               u32 id;
+
+               if (!btf_type_is_ptr(mtype))
+                       continue;
 
+               btf_type_skip_modifiers(btf, mtype->type, &id);
                /* If we match on both type and name, the field is considered trusted. */
-               if (m_walk->type == member->type && !strcmp(walk_name, m_name))
+               if (btf_id == id && !strcmp(field_name, m_name))
                        return true;
        }
 
 
 
 /* full trusted: these fields are trusted even outside of RCU CS and never NULL */
 BTF_TYPE_SAFE_TRUSTED(struct bpf_iter_meta) {
-       __bpf_md_ptr(struct seq_file *, seq);
+       struct seq_file *seq;
 };
 
 BTF_TYPE_SAFE_TRUSTED(struct bpf_iter__task) {
-       __bpf_md_ptr(struct bpf_iter_meta *, meta);
-       __bpf_md_ptr(struct task_struct *, task);
+       struct bpf_iter_meta *meta;
+       struct task_struct *task;
 };
 
 BTF_TYPE_SAFE_TRUSTED(struct linux_binprm) {
 
 static bool type_is_rcu(struct bpf_verifier_env *env,
                        struct bpf_reg_state *reg,
-                       int off)
+                       const char *field_name, u32 btf_id)
 {
        BTF_TYPE_EMIT(BTF_TYPE_SAFE_RCU(struct task_struct));
        BTF_TYPE_EMIT(BTF_TYPE_SAFE_RCU(struct css_set));
 
-       return btf_nested_type_is_trusted(&env->log, reg, off, "__safe_rcu");
+       return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id, "__safe_rcu");
 }
 
 static bool type_is_trusted(struct bpf_verifier_env *env,
                            struct bpf_reg_state *reg,
-                           int off)
+                           const char *field_name, u32 btf_id)
 {
        BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct bpf_iter_meta));
        BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct bpf_iter__task));
        BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct dentry));
        BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct socket));
 
-       return btf_nested_type_is_trusted(&env->log, reg, off, "__safe_trusted");
+       return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id, "__safe_trusted");
 }
 
 static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
        struct bpf_reg_state *reg = regs + regno;
        const struct btf_type *t = btf_type_by_id(reg->btf, reg->btf_id);
        const char *tname = btf_name_by_offset(reg->btf, t->name_off);
+       const char *field_name = NULL;
        enum bpf_type_flag flag = 0;
        u32 btf_id = 0;
        int ret;
                        return -EFAULT;
                }
 
-               ret = btf_struct_access(&env->log, reg, off, size, atype, &btf_id, &flag);
+               ret = btf_struct_access(&env->log, reg, off, size, atype, &btf_id, &flag, &field_name);
        }
 
        if (ret < 0)
                 * A regular RCU-protected pointer with __rcu tag can also be deemed
                 * trusted if we are in an RCU CS. Such pointer can be NULL.
                 */
-               if (type_is_trusted(env, reg, off)) {
+               if (type_is_trusted(env, reg, field_name, btf_id)) {
                        flag |= PTR_TRUSTED;
                } else if (in_rcu_cs(env) && !type_may_be_null(reg->type)) {
-                       if (type_is_rcu(env, reg, off)) {
+                       if (type_is_rcu(env, reg, field_name, btf_id)) {
                                /* ignore __rcu tag and mark it MEM_RCU */
                                flag |= MEM_RCU;
                        } else if (flag & MEM_RCU) {
        /* Simulate access to a PTR_TO_BTF_ID */
        memset(&map_reg, 0, sizeof(map_reg));
        mark_btf_ld_reg(env, &map_reg, 0, PTR_TO_BTF_ID, btf_vmlinux, *map->ops->map_btf_id, 0);
-       ret = btf_struct_access(&env->log, &map_reg, off, size, atype, &btf_id, &flag);
+       ret = btf_struct_access(&env->log, &map_reg, off, size, atype, &btf_id, &flag, NULL);
        if (ret < 0)
                return ret;