tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master head: c8109c2ba35e9bfd8a55087ffb1f42cc0dcf71e6 commit: 39a464de961f256197934d36aa5dda546cba8ed0 [13255/13500] udf: Fix crash after seekdir config: arc-allyesconfig (attached as .config) compiler: arceb-elf-gcc (GCC) 11.2.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://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=39a464de961f256197934d36aa5dda546cba8ed0 git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git git fetch --no-tags linux-next master git checkout 39a464de961f256197934d36aa5dda546cba8ed0 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): fs/udf/dir.c: In function 'udf_readdir': >> fs/udf/dir.c:78:25: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] 78 | if (ctx->pos != (loff_t)file->private_data) { | ^ >> fs/udf/dir.c:211:30: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] 211 | file->private_data = (void *)ctx->pos; | ^ cc1: all warnings being treated as errors vim +78 fs/udf/dir.c 37 38 static int udf_readdir(struct file *file, struct dir_context *ctx) 39 { 40 struct inode *dir = file_inode(file); 41 struct udf_inode_info *iinfo = UDF_I(dir); 42 struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; 43 struct fileIdentDesc *fi = NULL; 44 struct fileIdentDesc cfi; 45 udf_pblk_t block, iblock; 46 loff_t nf_pos, emit_pos; 47 int flen; 48 unsigned char *fname = NULL, *copy_name = NULL; 49 unsigned char *nameptr; 50 uint16_t liu; 51 uint8_t lfi; 52 loff_t size = udf_ext0_offset(dir) + dir->i_size; 53 struct buffer_head *tmp, *bha[16]; 54 struct kernel_lb_addr eloc; 55 uint32_t elen; 56 sector_t offset; 57 int i, num, ret = 0; 58 struct extent_position epos = { NULL, 0, {0, 0} }; 59 struct super_block *sb = dir->i_sb; 60 61 if (ctx->pos == 0) { 62 if (!dir_emit_dot(file, ctx)) 63 return 0; 64 ctx->pos = 1; 65 } 66 nf_pos = (ctx->pos - 1) << 2; 67 if (nf_pos >= size) 68 goto out; 69 70 /* 71 * Did our position change since last readdir (likely lseek was 72 * called)? We need to verify the position correctly points at the 73 * beginning of some dir entry so that the directory parsing code does 74 * not get confused. Since UDF does not have any reliable way of 75 * identifying beginning of dir entry (names are under user control), 76 * we need to scan the directory from the beginning. 77 */ > 78 if (ctx->pos != (loff_t)file->private_data) { 79 emit_pos = nf_pos; 80 nf_pos = 0; 81 } 82 83 fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); 84 if (!fname) { 85 ret = -ENOMEM; 86 goto out; 87 } 88 89 if (nf_pos == 0) 90 nf_pos = udf_ext0_offset(dir); 91 92 fibh.soffset = fibh.eoffset = nf_pos & (sb->s_blocksize - 1); 93 if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 94 if (inode_bmap(dir, nf_pos >> sb->s_blocksize_bits, 95 &epos, &eloc, &elen, &offset) 96 != (EXT_RECORDED_ALLOCATED >> 30)) { 97 ret = -ENOENT; 98 goto out; 99 } 100 block = udf_get_lb_pblock(sb, &eloc, offset); 101 if ((++offset << sb->s_blocksize_bits) < elen) { 102 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 103 epos.offset -= sizeof(struct short_ad); 104 else if (iinfo->i_alloc_type == 105 ICBTAG_FLAG_AD_LONG) 106 epos.offset -= sizeof(struct long_ad); 107 } else { 108 offset = 0; 109 } 110 111 if (!(fibh.sbh = fibh.ebh = udf_tread(sb, block))) { 112 ret = -EIO; 113 goto out; 114 } 115 116 if (!(offset & ((16 >> (sb->s_blocksize_bits - 9)) - 1))) { 117 i = 16 >> (sb->s_blocksize_bits - 9); 118 if (i + offset > (elen >> sb->s_blocksize_bits)) 119 i = (elen >> sb->s_blocksize_bits) - offset; 120 for (num = 0; i > 0; i--) { 121 block = udf_get_lb_pblock(sb, &eloc, offset + i); 122 tmp = udf_tgetblk(sb, block); 123 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) 124 bha[num++] = tmp; 125 else 126 brelse(tmp); 127 } 128 if (num) { 129 ll_rw_block(REQ_OP_READ, REQ_RAHEAD, num, bha); 130 for (i = 0; i < num; i++) 131 brelse(bha[i]); 132 } 133 } 134 } 135 136 while (nf_pos < size) { 137 struct kernel_lb_addr tloc; 138 loff_t cur_pos = nf_pos; 139 140 /* Update file position only if we got past the current one */ 141 if (nf_pos >= emit_pos) 142 ctx->pos = (nf_pos >> 2) + 1; 143 144 fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, 145 &elen, &offset); 146 if (!fi) 147 goto out; 148 /* Still not at offset where user asked us to read from? */ 149 if (cur_pos < emit_pos) 150 continue; 151 152 liu = le16_to_cpu(cfi.lengthOfImpUse); 153 lfi = cfi.lengthFileIdent; 154 155 if (fibh.sbh == fibh.ebh) { 156 nameptr = udf_get_fi_ident(fi); 157 } else { 158 int poffset; /* Unpaded ending offset */ 159 160 poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi; 161 162 if (poffset >= lfi) { 163 nameptr = (char *)(fibh.ebh->b_data + poffset - lfi); 164 } else { 165 if (!copy_name) { 166 copy_name = kmalloc(UDF_NAME_LEN, 167 GFP_NOFS); 168 if (!copy_name) { 169 ret = -ENOMEM; 170 goto out; 171 } 172 } 173 nameptr = copy_name; 174 memcpy(nameptr, udf_get_fi_ident(fi), 175 lfi - poffset); 176 memcpy(nameptr + lfi - poffset, 177 fibh.ebh->b_data, poffset); 178 } 179 } 180 181 if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { 182 if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE)) 183 continue; 184 } 185 186 if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { 187 if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) 188 continue; 189 } 190 191 if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { 192 if (!dir_emit_dotdot(file, ctx)) 193 goto out; 194 continue; 195 } 196 197 flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); 198 if (flen < 0) 199 continue; 200 201 tloc = lelb_to_cpu(cfi.icb.extLocation); 202 iblock = udf_get_lb_pblock(sb, &tloc, 0); 203 if (!dir_emit(ctx, fname, flen, iblock, DT_UNKNOWN)) 204 goto out; 205 } /* end while */ 206 207 ctx->pos = (nf_pos >> 2) + 1; 208 209 out: 210 /* Store position where we've ended */ > 211 file->private_data = (void *)ctx->pos; 212 if (fibh.sbh != fibh.ebh) 213 brelse(fibh.ebh); 214 brelse(fibh.sbh); 215 brelse(epos.bh); 216 kfree(fname); 217 kfree(copy_name); 218 219 return ret; 220 } 221 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org