Hi Guo, Thank you for the patch! Yet something to improve: [auto build test ERROR on v6.0-rc3] [also build test ERROR on linus/master next-20220829] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Guo-Xuenan/xfs-fix-uaf-when-leaf-dir-bestcount-not-match-with-dir-data-blocks/20220829-144530 base: b90cb1053190353cc30f0fef0ef1f378ccc063c5 config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20220829/202208291703.BcRRyCDy-lkp@xxxxxxxxx/config) compiler: sh4-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/26c85e96017e84257ac452f142a123bfd7dad776 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Guo-Xuenan/xfs-fix-uaf-when-leaf-dir-bestcount-not-match-with-dir-data-blocks/20220829-144530 git checkout 26c85e96017e84257ac452f142a123bfd7dad776 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sh SHELL=/bin/bash fs/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@xxxxxxxxx> All errors (new ones prefixed by >>): fs/xfs/libxfs/xfs_dir2_leaf.c: In function 'xfs_dir2_leaf_addname': >> fs/xfs/libxfs/xfs_dir2_leaf.c:668:60: error: 'struct xfs_inode' has no member named 'i_d'; did you mean 'i_df'? 668 | xfs_dir2_byte_to_db(args->geo, dp->i_d.di_size)) { | ^~~ | i_df vim +668 fs/xfs/libxfs/xfs_dir2_leaf.c 604 605 /* 606 * Add an entry to a leaf form directory. 607 */ 608 int /* error */ 609 xfs_dir2_leaf_addname( 610 struct xfs_da_args *args) /* operation arguments */ 611 { 612 struct xfs_dir3_icleaf_hdr leafhdr; 613 struct xfs_trans *tp = args->trans; 614 __be16 *bestsp; /* freespace table in leaf */ 615 __be16 *tagp; /* end of data entry */ 616 struct xfs_buf *dbp; /* data block buffer */ 617 struct xfs_buf *lbp; /* leaf's buffer */ 618 struct xfs_dir2_leaf *leaf; /* leaf structure */ 619 struct xfs_inode *dp = args->dp; /* incore directory inode */ 620 struct xfs_dir2_data_hdr *hdr; /* data block header */ 621 struct xfs_dir2_data_entry *dep; /* data block entry */ 622 struct xfs_dir2_leaf_entry *lep; /* leaf entry table pointer */ 623 struct xfs_dir2_leaf_entry *ents; 624 struct xfs_dir2_data_unused *dup; /* data unused entry */ 625 struct xfs_dir2_leaf_tail *ltp; /* leaf tail pointer */ 626 struct xfs_dir2_data_free *bf; /* bestfree table */ 627 int compact; /* need to compact leaves */ 628 int error; /* error return value */ 629 int grown; /* allocated new data block */ 630 int highstale = 0; /* index of next stale leaf */ 631 int i; /* temporary, index */ 632 int index; /* leaf table position */ 633 int length; /* length of new entry */ 634 int lfloglow; /* low leaf logging index */ 635 int lfloghigh; /* high leaf logging index */ 636 int lowstale = 0; /* index of prev stale leaf */ 637 int needbytes; /* leaf block bytes needed */ 638 int needlog; /* need to log data header */ 639 int needscan; /* need to rescan data free */ 640 xfs_dir2_db_t use_block; /* data block number */ 641 642 trace_xfs_dir2_leaf_addname(args); 643 644 error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, &lbp); 645 if (error) 646 return error; 647 648 /* 649 * Look up the entry by hash value and name. 650 * We know it's not there, our caller has already done a lookup. 651 * So the index is of the entry to insert in front of. 652 * But if there are dup hash values the index is of the first of those. 653 */ 654 index = xfs_dir2_leaf_search_hash(args, lbp); 655 leaf = lbp->b_addr; 656 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); 657 xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 658 ents = leafhdr.ents; 659 bestsp = xfs_dir2_leaf_bests_p(ltp); 660 length = xfs_dir2_data_entsize(dp->i_mount, args->namelen); 661 662 /* 663 * There should be as many bestfree slots as there are dir data 664 * blocks that can fit under i_size. Othrewise, which may cause 665 * serious problems eg. UAF or slab-out-of bound etc. 666 */ 667 if (be32_to_cpu(ltp->bestcount) != > 668 xfs_dir2_byte_to_db(args->geo, dp->i_d.di_size)) { 669 xfs_buf_ioerror_alert(lbp, __return_address); 670 if (tp->t_flags & XFS_TRANS_DIRTY) 671 xfs_force_shutdown(tp->t_mountp, 672 SHUTDOWN_CORRUPT_INCORE); 673 return -EFSCORRUPTED; 674 } 675 676 /* 677 * See if there are any entries with the same hash value 678 * and space in their block for the new entry. 679 * This is good because it puts multiple same-hash value entries 680 * in a data block, improving the lookup of those entries. 681 */ 682 for (use_block = -1, lep = &ents[index]; 683 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; 684 index++, lep++) { 685 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 686 continue; 687 i = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); 688 ASSERT(i < be32_to_cpu(ltp->bestcount)); 689 ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF)); 690 if (be16_to_cpu(bestsp[i]) >= length) { 691 use_block = i; 692 break; 693 } 694 } 695 /* 696 * Didn't find a block yet, linear search all the data blocks. 697 */ 698 if (use_block == -1) { 699 for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) { 700 /* 701 * Remember a block we see that's missing. 702 */ 703 if (bestsp[i] == cpu_to_be16(NULLDATAOFF) && 704 use_block == -1) 705 use_block = i; 706 else if (be16_to_cpu(bestsp[i]) >= length) { 707 use_block = i; 708 break; 709 } 710 } 711 } 712 /* 713 * How many bytes do we need in the leaf block? 714 */ 715 needbytes = 0; 716 if (!leafhdr.stale) 717 needbytes += sizeof(xfs_dir2_leaf_entry_t); 718 if (use_block == -1) 719 needbytes += sizeof(xfs_dir2_data_off_t); 720 721 /* 722 * Now kill use_block if it refers to a missing block, so we 723 * can use it as an indication of allocation needed. 724 */ 725 if (use_block != -1 && bestsp[use_block] == cpu_to_be16(NULLDATAOFF)) 726 use_block = -1; 727 /* 728 * If we don't have enough free bytes but we can make enough 729 * by compacting out stale entries, we'll do that. 730 */ 731 if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes && 732 leafhdr.stale > 1) 733 compact = 1; 734 735 /* 736 * Otherwise if we don't have enough free bytes we need to 737 * convert to node form. 738 */ 739 else if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes) { 740 /* 741 * Just checking or no space reservation, give up. 742 */ 743 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || 744 args->total == 0) { 745 xfs_trans_brelse(tp, lbp); 746 return -ENOSPC; 747 } 748 /* 749 * Convert to node form. 750 */ 751 error = xfs_dir2_leaf_to_node(args, lbp); 752 if (error) 753 return error; 754 /* 755 * Then add the new entry. 756 */ 757 return xfs_dir2_node_addname(args); 758 } 759 /* 760 * Otherwise it will fit without compaction. 761 */ 762 else 763 compact = 0; 764 /* 765 * If just checking, then it will fit unless we needed to allocate 766 * a new data block. 767 */ 768 if (args->op_flags & XFS_DA_OP_JUSTCHECK) { 769 xfs_trans_brelse(tp, lbp); 770 return use_block == -1 ? -ENOSPC : 0; 771 } 772 /* 773 * If no allocations are allowed, return now before we've 774 * changed anything. 775 */ 776 if (args->total == 0 && use_block == -1) { 777 xfs_trans_brelse(tp, lbp); 778 return -ENOSPC; 779 } 780 /* 781 * Need to compact the leaf entries, removing stale ones. 782 * Leave one stale entry behind - the one closest to our 783 * insertion index - and we'll shift that one to our insertion 784 * point later. 785 */ 786 if (compact) { 787 xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale, 788 &highstale, &lfloglow, &lfloghigh); 789 } 790 /* 791 * There are stale entries, so we'll need log-low and log-high 792 * impossibly bad values later. 793 */ 794 else if (leafhdr.stale) { 795 lfloglow = leafhdr.count; 796 lfloghigh = -1; 797 } 798 /* 799 * If there was no data block space found, we need to allocate 800 * a new one. 801 */ 802 if (use_block == -1) { 803 /* 804 * Add the new data block. 805 */ 806 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, 807 &use_block))) { 808 xfs_trans_brelse(tp, lbp); 809 return error; 810 } 811 /* 812 * Initialize the block. 813 */ 814 if ((error = xfs_dir3_data_init(args, use_block, &dbp))) { 815 xfs_trans_brelse(tp, lbp); 816 return error; 817 } 818 /* 819 * If we're adding a new data block on the end we need to 820 * extend the bests table. Copy it up one entry. 821 */ 822 if (use_block >= be32_to_cpu(ltp->bestcount)) { 823 bestsp--; 824 memmove(&bestsp[0], &bestsp[1], 825 be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); 826 be32_add_cpu(<p->bestcount, 1); 827 xfs_dir3_leaf_log_tail(args, lbp); 828 xfs_dir3_leaf_log_bests(args, lbp, 0, 829 be32_to_cpu(ltp->bestcount) - 1); 830 } 831 /* 832 * If we're filling in a previously empty block just log it. 833 */ 834 else 835 xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block); 836 hdr = dbp->b_addr; 837 bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 838 bestsp[use_block] = bf[0].length; 839 grown = 1; 840 } else { 841 /* 842 * Already had space in some data block. 843 * Just read that one in. 844 */ 845 error = xfs_dir3_data_read(tp, dp, 846 xfs_dir2_db_to_da(args->geo, use_block), 847 0, &dbp); 848 if (error) { 849 xfs_trans_brelse(tp, lbp); 850 return error; 851 } 852 hdr = dbp->b_addr; 853 bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 854 grown = 0; 855 } 856 /* 857 * Point to the biggest freespace in our data block. 858 */ 859 dup = (xfs_dir2_data_unused_t *) 860 ((char *)hdr + be16_to_cpu(bf[0].offset)); 861 needscan = needlog = 0; 862 /* 863 * Mark the initial part of our freespace in use for the new entry. 864 */ 865 error = xfs_dir2_data_use_free(args, dbp, dup, 866 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), 867 length, &needlog, &needscan); 868 if (error) { 869 xfs_trans_brelse(tp, lbp); 870 return error; 871 } 872 /* 873 * Initialize our new entry (at last). 874 */ 875 dep = (xfs_dir2_data_entry_t *)dup; 876 dep->inumber = cpu_to_be64(args->inumber); 877 dep->namelen = args->namelen; 878 memcpy(dep->name, args->name, dep->namelen); 879 xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); 880 tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); 881 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 882 /* 883 * Need to scan fix up the bestfree table. 884 */ 885 if (needscan) 886 xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 887 /* 888 * Need to log the data block's header. 889 */ 890 if (needlog) 891 xfs_dir2_data_log_header(args, dbp); 892 xfs_dir2_data_log_entry(args, dbp, dep); 893 /* 894 * If the bests table needs to be changed, do it. 895 * Log the change unless we've already done that. 896 */ 897 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) { 898 bestsp[use_block] = bf[0].length; 899 if (!grown) 900 xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block); 901 } 902 903 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale, 904 highstale, &lfloglow, &lfloghigh); 905 906 /* 907 * Fill in the new leaf entry. 908 */ 909 lep->hashval = cpu_to_be32(args->hashval); 910 lep->address = cpu_to_be32( 911 xfs_dir2_db_off_to_dataptr(args->geo, use_block, 912 be16_to_cpu(*tagp))); 913 /* 914 * Log the leaf fields and give up the buffers. 915 */ 916 xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); 917 xfs_dir3_leaf_log_header(args, lbp); 918 xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, lfloglow, lfloghigh); 919 xfs_dir3_leaf_check(dp, lbp); 920 xfs_dir3_data_check(dp, dbp); 921 return 0; 922 } 923 -- 0-DAY CI Kernel Test Service https://01.org/lkp