va_end(args);
 }
 
+static bool is_valid_dref_root(u64 rootid)
+{
+       /*
+        * The following tree root objectids are allowed to have a data backref:
+        * - subvolume trees
+        * - data reloc tree
+        * - tree root
+        *   For v1 space cache
+        */
+       return is_fstree(rootid) || rootid == BTRFS_DATA_RELOC_TREE_OBJECTID ||
+              rootid == BTRFS_ROOT_TREE_OBJECTID;
+}
+
 static int check_extent_item(struct extent_buffer *leaf,
                             struct btrfs_key *key, int slot,
                             struct btrfs_key *prev_key)
                struct btrfs_extent_data_ref *dref;
                struct btrfs_shared_data_ref *sref;
                u64 seq;
+               u64 dref_root;
+               u64 dref_objectid;
                u64 dref_offset;
                u64 inline_offset;
                u8 inline_type;
                 */
                case BTRFS_EXTENT_DATA_REF_KEY:
                        dref = (struct btrfs_extent_data_ref *)(&iref->offset);
+                       dref_root = btrfs_extent_data_ref_root(leaf, dref);
+                       dref_objectid = btrfs_extent_data_ref_objectid(leaf, dref);
                        dref_offset = btrfs_extent_data_ref_offset(leaf, dref);
                        seq = hash_extent_data_ref(
                                        btrfs_extent_data_ref_root(leaf, dref),
                                        btrfs_extent_data_ref_objectid(leaf, dref),
                                        btrfs_extent_data_ref_offset(leaf, dref));
+                       if (unlikely(!is_valid_dref_root(dref_root))) {
+                               extent_err(leaf, slot,
+                                          "invalid data ref root value %llu",
+                                          dref_root);
+                               return -EUCLEAN;
+                       }
+                       if (unlikely(dref_objectid < BTRFS_FIRST_FREE_OBJECTID ||
+                                    dref_objectid > BTRFS_LAST_FREE_OBJECTID)) {
+                               extent_err(leaf, slot,
+                                          "invalid data ref objectid value %llu",
+                                          dref_root);
+                               return -EUCLEAN;
+                       }
                        if (unlikely(!IS_ALIGNED(dref_offset,
                                                 fs_info->sectorsize))) {
                                extent_err(leaf, slot,
                return -EUCLEAN;
        }
        for (; ptr < end; ptr += sizeof(*dref)) {
+               u64 root;
+               u64 objectid;
                u64 offset;
 
                /*
                 * overflow from the leaf due to hash collisions.
                 */
                dref = (struct btrfs_extent_data_ref *)ptr;
+               root = btrfs_extent_data_ref_root(leaf, dref);
+               objectid = btrfs_extent_data_ref_objectid(leaf, dref);
                offset = btrfs_extent_data_ref_offset(leaf, dref);
+               if (unlikely(!is_valid_dref_root(root))) {
+                       extent_err(leaf, slot,
+                                  "invalid extent data backref root value %llu",
+                                  root);
+                       return -EUCLEAN;
+               }
+               if (unlikely(objectid < BTRFS_FIRST_FREE_OBJECTID ||
+                            objectid > BTRFS_LAST_FREE_OBJECTID)) {
+                       extent_err(leaf, slot,
+                                  "invalid extent data backref objectid value %llu",
+                                  root);
+                       return -EUCLEAN;
+               }
                if (unlikely(!IS_ALIGNED(offset, leaf->fs_info->sectorsize))) {
                        extent_err(leaf, slot,
        "invalid extent data backref offset, have %llu expect aligned to %u",