1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * directory.c 4 * 5 * PURPOSE 6 * Directory related functions 7 * 8 */ 9 10 #include "udfdecl.h" 11 #include "udf_i.h" 12 13 #include <linux/fs.h> 14 #include <linux/string.h> 15 #include <linux/bio.h> 16 #include <linux/crc-itu-t.h> 17 #include <linux/iversion.h> 18 19 static int udf_verify_fi(struct udf_fileident_iter *iter) 20 { 21 unsigned int len; 22 23 if (iter->fi.descTag.tagIdent != cpu_to_le16(TAG_IDENT_FID)) { 24 udf_err(iter->dir->i_sb, 25 "directory (ino %lu) has entry at pos %llu with incorrect tag %x\n", 26 iter->dir->i_ino, (unsigned long long)iter->pos, 27 le16_to_cpu(iter->fi.descTag.tagIdent)); 28 return -EFSCORRUPTED; 29 } 30 len = udf_dir_entry_len(&iter->fi); 31 if (le16_to_cpu(iter->fi.lengthOfImpUse) & 3) { 32 udf_err(iter->dir->i_sb, 33 "directory (ino %lu) has entry at pos %llu with unaligned length of impUse field\n", 34 iter->dir->i_ino, (unsigned long long)iter->pos); 35 return -EFSCORRUPTED; 36 } 37 /* 38 * This is in fact allowed by the spec due to long impUse field but 39 * we don't support it. If there is real media with this large impUse 40 * field, support can be added. 41 */ 42 if (len > 1 << iter->dir->i_blkbits) { 43 udf_err(iter->dir->i_sb, 44 "directory (ino %lu) has too big (%u) entry at pos %llu\n", 45 iter->dir->i_ino, len, (unsigned long long)iter->pos); 46 return -EFSCORRUPTED; 47 } 48 if (iter->pos + len > iter->dir->i_size) { 49 udf_err(iter->dir->i_sb, 50 "directory (ino %lu) has entry past directory size at pos %llu\n", 51 iter->dir->i_ino, (unsigned long long)iter->pos); 52 return -EFSCORRUPTED; 53 } 54 if (udf_dir_entry_len(&iter->fi) != 55 sizeof(struct tag) + le16_to_cpu(iter->fi.descTag.descCRCLength)) { 56 udf_err(iter->dir->i_sb, 57 "directory (ino %lu) has entry where CRC length (%u) does not match entry length (%u)\n", 58 iter->dir->i_ino, 59 (unsigned)le16_to_cpu(iter->fi.descTag.descCRCLength), 60 (unsigned)(udf_dir_entry_len(&iter->fi) - 61 sizeof(struct tag))); 62 return -EFSCORRUPTED; 63 } 64 return 0; 65 } 66 67 static int udf_copy_fi(struct udf_fileident_iter *iter) 68 { 69 struct udf_inode_info *iinfo = UDF_I(iter->dir); 70 u32 blksize = 1 << iter->dir->i_blkbits; 71 u32 off, len, nameoff; 72 int err; 73 74 /* Skip copying when we are at EOF */ 75 if (iter->pos >= iter->dir->i_size) { 76 iter->name = NULL; 77 return 0; 78 } 79 if (iter->dir->i_size < iter->pos + sizeof(struct fileIdentDesc)) { 80 udf_err(iter->dir->i_sb, 81 "directory (ino %lu) has entry straddling EOF\n", 82 iter->dir->i_ino); 83 return -EFSCORRUPTED; 84 } 85 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 86 memcpy(&iter->fi, iinfo->i_data + iinfo->i_lenEAttr + iter->pos, 87 sizeof(struct fileIdentDesc)); 88 err = udf_verify_fi(iter); 89 if (err < 0) 90 return err; 91 iter->name = iinfo->i_data + iinfo->i_lenEAttr + iter->pos + 92 sizeof(struct fileIdentDesc) + 93 le16_to_cpu(iter->fi.lengthOfImpUse); 94 return 0; 95 } 96 97 off = iter->pos & (blksize - 1); 98 len = min_t(int, sizeof(struct fileIdentDesc), blksize - off); 99 memcpy(&iter->fi, iter->bh[0]->b_data + off, len); 100 if (len < sizeof(struct fileIdentDesc)) 101 memcpy((char *)(&iter->fi) + len, iter->bh[1]->b_data, 102 sizeof(struct fileIdentDesc) - len); 103 err = udf_verify_fi(iter); 104 if (err < 0) 105 return err; 106 107 /* Handle directory entry name */ 108 nameoff = off + sizeof(struct fileIdentDesc) + 109 le16_to_cpu(iter->fi.lengthOfImpUse); 110 if (off + udf_dir_entry_len(&iter->fi) <= blksize) { 111 iter->name = iter->bh[0]->b_data + nameoff; 112 } else if (nameoff >= blksize) { 113 iter->name = iter->bh[1]->b_data + (nameoff - blksize); 114 } else { 115 iter->name = iter->namebuf; 116 len = blksize - nameoff; 117 memcpy(iter->name, iter->bh[0]->b_data + nameoff, len); 118 memcpy(iter->name + len, iter->bh[1]->b_data, 119 iter->fi.lengthFileIdent - len); 120 } 121 return 0; 122 } 123 124 /* Readahead 8k once we are at 8k boundary */ 125 static void udf_readahead_dir(struct udf_fileident_iter *iter) 126 { 127 unsigned int ralen = 16 >> (iter->dir->i_blkbits - 9); 128 struct buffer_head *tmp, *bha[16]; 129 int i, num; 130 udf_pblk_t blk; 131 132 if (iter->loffset & (ralen - 1)) 133 return; 134 135 if (iter->loffset + ralen > (iter->elen >> iter->dir->i_blkbits)) 136 ralen = (iter->elen >> iter->dir->i_blkbits) - iter->loffset; 137 num = 0; 138 for (i = 0; i < ralen; i++) { 139 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, 140 iter->loffset + i); 141 tmp = sb_getblk(iter->dir->i_sb, blk); 142 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) 143 bha[num++] = tmp; 144 else 145 brelse(tmp); 146 } 147 if (num) { 148 bh_readahead_batch(num, bha, REQ_RAHEAD); 149 for (i = 0; i < num; i++) 150 brelse(bha[i]); 151 } 152 } 153 154 static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter) 155 { 156 udf_pblk_t blk; 157 158 udf_readahead_dir(iter); 159 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, iter->loffset); 160 return sb_bread(iter->dir->i_sb, blk); 161 } 162 163 /* 164 * Updates loffset to point to next directory block; eloc, elen & epos are 165 * updated if we need to traverse to the next extent as well. 166 */ 167 static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter) 168 { 169 iter->loffset++; 170 if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits)) 171 return 0; 172 173 iter->loffset = 0; 174 if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1) 175 != (EXT_RECORDED_ALLOCATED >> 30)) { 176 if (iter->pos == iter->dir->i_size) { 177 iter->elen = 0; 178 return 0; 179 } 180 udf_err(iter->dir->i_sb, 181 "extent after position %llu not allocated in directory (ino %lu)\n", 182 (unsigned long long)iter->pos, iter->dir->i_ino); 183 return -EFSCORRUPTED; 184 } 185 return 0; 186 } 187 188 static int udf_fiiter_load_bhs(struct udf_fileident_iter *iter) 189 { 190 int blksize = 1 << iter->dir->i_blkbits; 191 int off = iter->pos & (blksize - 1); 192 int err; 193 struct fileIdentDesc *fi; 194 195 /* Is there any further extent we can map from? */ 196 if (!iter->bh[0] && iter->elen) { 197 iter->bh[0] = udf_fiiter_bread_blk(iter); 198 if (!iter->bh[0]) { 199 err = -ENOMEM; 200 goto out_brelse; 201 } 202 if (!buffer_uptodate(iter->bh[0])) { 203 err = -EIO; 204 goto out_brelse; 205 } 206 } 207 /* There's no next block so we are done */ 208 if (iter->pos >= iter->dir->i_size) 209 return 0; 210 /* Need to fetch next block as well? */ 211 if (off + sizeof(struct fileIdentDesc) > blksize) 212 goto fetch_next; 213 fi = (struct fileIdentDesc *)(iter->bh[0]->b_data + off); 214 /* Need to fetch next block to get name? */ 215 if (off + udf_dir_entry_len(fi) > blksize) { 216 fetch_next: 217 err = udf_fiiter_advance_blk(iter); 218 if (err) 219 goto out_brelse; 220 iter->bh[1] = udf_fiiter_bread_blk(iter); 221 if (!iter->bh[1]) { 222 err = -ENOMEM; 223 goto out_brelse; 224 } 225 if (!buffer_uptodate(iter->bh[1])) { 226 err = -EIO; 227 goto out_brelse; 228 } 229 } 230 return 0; 231 out_brelse: 232 brelse(iter->bh[0]); 233 brelse(iter->bh[1]); 234 iter->bh[0] = iter->bh[1] = NULL; 235 return err; 236 } 237 238 int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir, 239 loff_t pos) 240 { 241 struct udf_inode_info *iinfo = UDF_I(dir); 242 int err = 0; 243 244 iter->dir = dir; 245 iter->bh[0] = iter->bh[1] = NULL; 246 iter->pos = pos; 247 iter->elen = 0; 248 iter->epos.bh = NULL; 249 iter->name = NULL; 250 /* 251 * When directory is verified, we don't expect directory iteration to 252 * fail and it can be difficult to undo without corrupting filesystem. 253 * So just do not allow memory allocation failures here. 254 */ 255 iter->namebuf = kmalloc(UDF_NAME_LEN_CS0, GFP_KERNEL | __GFP_NOFAIL); 256 257 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 258 err = udf_copy_fi(iter); 259 goto out; 260 } 261 262 if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, 263 &iter->eloc, &iter->elen, &iter->loffset) != 264 (EXT_RECORDED_ALLOCATED >> 30)) { 265 if (pos == dir->i_size) 266 return 0; 267 udf_err(dir->i_sb, 268 "position %llu not allocated in directory (ino %lu)\n", 269 (unsigned long long)pos, dir->i_ino); 270 err = -EFSCORRUPTED; 271 goto out; 272 } 273 err = udf_fiiter_load_bhs(iter); 274 if (err < 0) 275 goto out; 276 err = udf_copy_fi(iter); 277 out: 278 if (err < 0) 279 udf_fiiter_release(iter); 280 return err; 281 } 282 283 int udf_fiiter_advance(struct udf_fileident_iter *iter) 284 { 285 unsigned int oldoff, len; 286 int blksize = 1 << iter->dir->i_blkbits; 287 int err; 288 289 oldoff = iter->pos & (blksize - 1); 290 len = udf_dir_entry_len(&iter->fi); 291 iter->pos += len; 292 if (UDF_I(iter->dir)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 293 if (oldoff + len >= blksize) { 294 brelse(iter->bh[0]); 295 iter->bh[0] = NULL; 296 /* Next block already loaded? */ 297 if (iter->bh[1]) { 298 iter->bh[0] = iter->bh[1]; 299 iter->bh[1] = NULL; 300 } else { 301 err = udf_fiiter_advance_blk(iter); 302 if (err < 0) 303 return err; 304 } 305 } 306 err = udf_fiiter_load_bhs(iter); 307 if (err < 0) 308 return err; 309 } 310 return udf_copy_fi(iter); 311 } 312 313 void udf_fiiter_release(struct udf_fileident_iter *iter) 314 { 315 iter->dir = NULL; 316 brelse(iter->bh[0]); 317 brelse(iter->bh[1]); 318 iter->bh[0] = iter->bh[1] = NULL; 319 kfree(iter->namebuf); 320 iter->namebuf = NULL; 321 } 322 323 static void udf_copy_to_bufs(void *buf1, int len1, void *buf2, int len2, 324 int off, void *src, int len) 325 { 326 int copy; 327 328 if (off >= len1) { 329 off -= len1; 330 } else { 331 copy = min(off + len, len1) - off; 332 memcpy(buf1 + off, src, copy); 333 src += copy; 334 len -= copy; 335 off = 0; 336 } 337 if (len > 0) { 338 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 339 return; 340 memcpy(buf2 + off, src, len); 341 } 342 } 343 344 static uint16_t udf_crc_fi_bufs(void *buf1, int len1, void *buf2, int len2, 345 int off, int len) 346 { 347 int copy; 348 uint16_t crc = 0; 349 350 if (off >= len1) { 351 off -= len1; 352 } else { 353 copy = min(off + len, len1) - off; 354 crc = crc_itu_t(crc, buf1 + off, copy); 355 len -= copy; 356 off = 0; 357 } 358 if (len > 0) { 359 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 360 return 0; 361 crc = crc_itu_t(crc, buf2 + off, len); 362 } 363 return crc; 364 } 365 366 static void udf_copy_fi_to_bufs(char *buf1, int len1, char *buf2, int len2, 367 int off, struct fileIdentDesc *fi, 368 uint8_t *impuse, uint8_t *name) 369 { 370 uint16_t crc; 371 int fioff = off; 372 int crcoff = off + sizeof(struct tag); 373 unsigned int crclen = udf_dir_entry_len(fi) - sizeof(struct tag); 374 char zeros[UDF_NAME_PAD] = {}; 375 int endoff = off + udf_dir_entry_len(fi); 376 377 udf_copy_to_bufs(buf1, len1, buf2, len2, off, fi, 378 sizeof(struct fileIdentDesc)); 379 off += sizeof(struct fileIdentDesc); 380 if (impuse) 381 udf_copy_to_bufs(buf1, len1, buf2, len2, off, impuse, 382 le16_to_cpu(fi->lengthOfImpUse)); 383 off += le16_to_cpu(fi->lengthOfImpUse); 384 if (name) { 385 udf_copy_to_bufs(buf1, len1, buf2, len2, off, name, 386 fi->lengthFileIdent); 387 off += fi->lengthFileIdent; 388 udf_copy_to_bufs(buf1, len1, buf2, len2, off, zeros, 389 endoff - off); 390 } 391 392 crc = udf_crc_fi_bufs(buf1, len1, buf2, len2, crcoff, crclen); 393 fi->descTag.descCRC = cpu_to_le16(crc); 394 fi->descTag.descCRCLength = cpu_to_le16(crclen); 395 fi->descTag.tagChecksum = udf_tag_checksum(&fi->descTag); 396 397 udf_copy_to_bufs(buf1, len1, buf2, len2, fioff, fi, sizeof(struct tag)); 398 } 399 400 void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse) 401 { 402 struct udf_inode_info *iinfo = UDF_I(iter->dir); 403 void *buf1, *buf2 = NULL; 404 int len1, len2 = 0, off; 405 int blksize = 1 << iter->dir->i_blkbits; 406 407 off = iter->pos & (blksize - 1); 408 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 409 buf1 = iinfo->i_data + iinfo->i_lenEAttr; 410 len1 = iter->dir->i_size; 411 } else { 412 buf1 = iter->bh[0]->b_data; 413 len1 = blksize; 414 if (iter->bh[1]) { 415 buf2 = iter->bh[1]->b_data; 416 len2 = blksize; 417 } 418 } 419 420 udf_copy_fi_to_bufs(buf1, len1, buf2, len2, off, &iter->fi, impuse, 421 iter->name == iter->namebuf ? iter->name : NULL); 422 423 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 424 mark_inode_dirty(iter->dir); 425 } else { 426 mark_buffer_dirty_inode(iter->bh[0], iter->dir); 427 if (iter->bh[1]) 428 mark_buffer_dirty_inode(iter->bh[1], iter->dir); 429 } 430 inode_inc_iversion(iter->dir); 431 } 432 433 void udf_fiiter_update_elen(struct udf_fileident_iter *iter, uint32_t new_elen) 434 { 435 struct udf_inode_info *iinfo = UDF_I(iter->dir); 436 int diff = new_elen - iter->elen; 437 438 /* Skip update when we already went past the last extent */ 439 if (!iter->elen) 440 return; 441 iter->elen = new_elen; 442 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 443 iter->epos.offset -= sizeof(struct short_ad); 444 else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) 445 iter->epos.offset -= sizeof(struct long_ad); 446 udf_write_aext(iter->dir, &iter->epos, &iter->eloc, iter->elen, 1); 447 iinfo->i_lenExtents += diff; 448 mark_inode_dirty(iter->dir); 449 } 450 451 /* Append new block to directory. @iter is expected to point at EOF */ 452 int udf_fiiter_append_blk(struct udf_fileident_iter *iter) 453 { 454 struct udf_inode_info *iinfo = UDF_I(iter->dir); 455 int blksize = 1 << iter->dir->i_blkbits; 456 struct buffer_head *bh; 457 sector_t block; 458 uint32_t old_elen = iter->elen; 459 int err; 460 461 if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)) 462 return -EINVAL; 463 464 /* Round up last extent in the file */ 465 udf_fiiter_update_elen(iter, ALIGN(iter->elen, blksize)); 466 467 /* Allocate new block and refresh mapping information */ 468 block = iinfo->i_lenExtents >> iter->dir->i_blkbits; 469 bh = udf_bread(iter->dir, block, 1, &err); 470 if (!bh) { 471 udf_fiiter_update_elen(iter, old_elen); 472 return err; 473 } 474 if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, 475 &iter->loffset) != (EXT_RECORDED_ALLOCATED >> 30)) { 476 udf_err(iter->dir->i_sb, 477 "block %llu not allocated in directory (ino %lu)\n", 478 (unsigned long long)block, iter->dir->i_ino); 479 return -EFSCORRUPTED; 480 } 481 if (!(iter->pos & (blksize - 1))) { 482 brelse(iter->bh[0]); 483 iter->bh[0] = bh; 484 } else { 485 iter->bh[1] = bh; 486 } 487 return 0; 488 } 489 490 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, 491 int inc) 492 { 493 struct short_ad *sa; 494 495 if ((!ptr) || (!offset)) { 496 pr_err("%s: invalidparms\n", __func__); 497 return NULL; 498 } 499 500 if ((*offset + sizeof(struct short_ad)) > maxoffset) 501 return NULL; 502 else { 503 sa = (struct short_ad *)ptr; 504 if (sa->extLength == 0) 505 return NULL; 506 } 507 508 if (inc) 509 *offset += sizeof(struct short_ad); 510 return sa; 511 } 512 513 struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) 514 { 515 struct long_ad *la; 516 517 if ((!ptr) || (!offset)) { 518 pr_err("%s: invalidparms\n", __func__); 519 return NULL; 520 } 521 522 if ((*offset + sizeof(struct long_ad)) > maxoffset) 523 return NULL; 524 else { 525 la = (struct long_ad *)ptr; 526 if (la->extLength == 0) 527 return NULL; 528 } 529 530 if (inc) 531 *offset += sizeof(struct long_ad); 532 return la; 533 } 534