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(u32, 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 int8_t etype = -1; 170 int err = 0; 171 172 iter->loffset++; 173 if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits)) 174 return 0; 175 176 iter->loffset = 0; 177 err = udf_next_aext(iter->dir, &iter->epos, &iter->eloc, 178 &iter->elen, &etype, 1); 179 if (err < 0) 180 return err; 181 else if (err == 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) { 182 if (iter->pos == iter->dir->i_size) { 183 iter->elen = 0; 184 return 0; 185 } 186 udf_err(iter->dir->i_sb, 187 "extent after position %llu not allocated in directory (ino %lu)\n", 188 (unsigned long long)iter->pos, iter->dir->i_ino); 189 return -EFSCORRUPTED; 190 } 191 return 0; 192 } 193 194 static int udf_fiiter_load_bhs(struct udf_fileident_iter *iter) 195 { 196 int blksize = 1 << iter->dir->i_blkbits; 197 int off = iter->pos & (blksize - 1); 198 int err; 199 struct fileIdentDesc *fi; 200 201 /* Is there any further extent we can map from? */ 202 if (!iter->bh[0] && iter->elen) { 203 iter->bh[0] = udf_fiiter_bread_blk(iter); 204 if (!iter->bh[0]) { 205 err = -ENOMEM; 206 goto out_brelse; 207 } 208 if (!buffer_uptodate(iter->bh[0])) { 209 err = -EIO; 210 goto out_brelse; 211 } 212 } 213 /* There's no next block so we are done */ 214 if (iter->pos >= iter->dir->i_size) 215 return 0; 216 /* Need to fetch next block as well? */ 217 if (off + sizeof(struct fileIdentDesc) > blksize) 218 goto fetch_next; 219 fi = (struct fileIdentDesc *)(iter->bh[0]->b_data + off); 220 /* Need to fetch next block to get name? */ 221 if (off + udf_dir_entry_len(fi) > blksize) { 222 fetch_next: 223 err = udf_fiiter_advance_blk(iter); 224 if (err) 225 goto out_brelse; 226 iter->bh[1] = udf_fiiter_bread_blk(iter); 227 if (!iter->bh[1]) { 228 err = -ENOMEM; 229 goto out_brelse; 230 } 231 if (!buffer_uptodate(iter->bh[1])) { 232 err = -EIO; 233 goto out_brelse; 234 } 235 } 236 return 0; 237 out_brelse: 238 brelse(iter->bh[0]); 239 brelse(iter->bh[1]); 240 iter->bh[0] = iter->bh[1] = NULL; 241 return err; 242 } 243 244 int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir, 245 loff_t pos) 246 { 247 struct udf_inode_info *iinfo = UDF_I(dir); 248 int err = 0; 249 int8_t etype; 250 251 iter->dir = dir; 252 iter->bh[0] = iter->bh[1] = NULL; 253 iter->pos = pos; 254 iter->elen = 0; 255 iter->epos.bh = NULL; 256 iter->name = NULL; 257 /* 258 * When directory is verified, we don't expect directory iteration to 259 * fail and it can be difficult to undo without corrupting filesystem. 260 * So just do not allow memory allocation failures here. 261 */ 262 iter->namebuf = kmalloc(UDF_NAME_LEN_CS0, GFP_KERNEL | __GFP_NOFAIL); 263 264 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 265 err = udf_copy_fi(iter); 266 goto out; 267 } 268 269 err = inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, 270 &iter->eloc, &iter->elen, &iter->loffset, &etype); 271 if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) { 272 if (pos == dir->i_size) 273 return 0; 274 udf_err(dir->i_sb, 275 "position %llu not allocated in directory (ino %lu)\n", 276 (unsigned long long)pos, dir->i_ino); 277 err = -EFSCORRUPTED; 278 goto out; 279 } 280 err = udf_fiiter_load_bhs(iter); 281 if (err < 0) 282 goto out; 283 err = udf_copy_fi(iter); 284 out: 285 if (err < 0) 286 udf_fiiter_release(iter); 287 return err; 288 } 289 290 int udf_fiiter_advance(struct udf_fileident_iter *iter) 291 { 292 unsigned int oldoff, len; 293 int blksize = 1 << iter->dir->i_blkbits; 294 int err; 295 296 oldoff = iter->pos & (blksize - 1); 297 len = udf_dir_entry_len(&iter->fi); 298 iter->pos += len; 299 if (UDF_I(iter->dir)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 300 if (oldoff + len >= blksize) { 301 brelse(iter->bh[0]); 302 iter->bh[0] = NULL; 303 /* Next block already loaded? */ 304 if (iter->bh[1]) { 305 iter->bh[0] = iter->bh[1]; 306 iter->bh[1] = NULL; 307 } else { 308 err = udf_fiiter_advance_blk(iter); 309 if (err < 0) 310 return err; 311 } 312 } 313 err = udf_fiiter_load_bhs(iter); 314 if (err < 0) 315 return err; 316 } 317 return udf_copy_fi(iter); 318 } 319 320 void udf_fiiter_release(struct udf_fileident_iter *iter) 321 { 322 iter->dir = NULL; 323 brelse(iter->bh[0]); 324 brelse(iter->bh[1]); 325 iter->bh[0] = iter->bh[1] = NULL; 326 kfree(iter->namebuf); 327 iter->namebuf = NULL; 328 } 329 330 static void udf_copy_to_bufs(void *buf1, int len1, void *buf2, int len2, 331 int off, void *src, int len) 332 { 333 int copy; 334 335 if (off >= len1) { 336 off -= len1; 337 } else { 338 copy = min(off + len, len1) - off; 339 memcpy(buf1 + off, src, copy); 340 src += copy; 341 len -= copy; 342 off = 0; 343 } 344 if (len > 0) { 345 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 346 return; 347 memcpy(buf2 + off, src, len); 348 } 349 } 350 351 static uint16_t udf_crc_fi_bufs(void *buf1, int len1, void *buf2, int len2, 352 int off, int len) 353 { 354 int copy; 355 uint16_t crc = 0; 356 357 if (off >= len1) { 358 off -= len1; 359 } else { 360 copy = min(off + len, len1) - off; 361 crc = crc_itu_t(crc, buf1 + off, copy); 362 len -= copy; 363 off = 0; 364 } 365 if (len > 0) { 366 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 367 return 0; 368 crc = crc_itu_t(crc, buf2 + off, len); 369 } 370 return crc; 371 } 372 373 static void udf_copy_fi_to_bufs(char *buf1, int len1, char *buf2, int len2, 374 int off, struct fileIdentDesc *fi, 375 uint8_t *impuse, uint8_t *name) 376 { 377 uint16_t crc; 378 int fioff = off; 379 int crcoff = off + sizeof(struct tag); 380 unsigned int crclen = udf_dir_entry_len(fi) - sizeof(struct tag); 381 char zeros[UDF_NAME_PAD] = {}; 382 int endoff = off + udf_dir_entry_len(fi); 383 384 udf_copy_to_bufs(buf1, len1, buf2, len2, off, fi, 385 sizeof(struct fileIdentDesc)); 386 off += sizeof(struct fileIdentDesc); 387 if (impuse) 388 udf_copy_to_bufs(buf1, len1, buf2, len2, off, impuse, 389 le16_to_cpu(fi->lengthOfImpUse)); 390 off += le16_to_cpu(fi->lengthOfImpUse); 391 if (name) { 392 udf_copy_to_bufs(buf1, len1, buf2, len2, off, name, 393 fi->lengthFileIdent); 394 off += fi->lengthFileIdent; 395 udf_copy_to_bufs(buf1, len1, buf2, len2, off, zeros, 396 endoff - off); 397 } 398 399 crc = udf_crc_fi_bufs(buf1, len1, buf2, len2, crcoff, crclen); 400 fi->descTag.descCRC = cpu_to_le16(crc); 401 fi->descTag.descCRCLength = cpu_to_le16(crclen); 402 fi->descTag.tagChecksum = udf_tag_checksum(&fi->descTag); 403 404 udf_copy_to_bufs(buf1, len1, buf2, len2, fioff, fi, sizeof(struct tag)); 405 } 406 407 void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse) 408 { 409 struct udf_inode_info *iinfo = UDF_I(iter->dir); 410 void *buf1, *buf2 = NULL; 411 int len1, len2 = 0, off; 412 int blksize = 1 << iter->dir->i_blkbits; 413 414 off = iter->pos & (blksize - 1); 415 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 416 buf1 = iinfo->i_data + iinfo->i_lenEAttr; 417 len1 = iter->dir->i_size; 418 } else { 419 buf1 = iter->bh[0]->b_data; 420 len1 = blksize; 421 if (iter->bh[1]) { 422 buf2 = iter->bh[1]->b_data; 423 len2 = blksize; 424 } 425 } 426 427 udf_copy_fi_to_bufs(buf1, len1, buf2, len2, off, &iter->fi, impuse, 428 iter->name == iter->namebuf ? iter->name : NULL); 429 430 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 431 mark_inode_dirty(iter->dir); 432 } else { 433 mark_buffer_dirty_inode(iter->bh[0], iter->dir); 434 if (iter->bh[1]) 435 mark_buffer_dirty_inode(iter->bh[1], iter->dir); 436 } 437 inode_inc_iversion(iter->dir); 438 } 439 440 void udf_fiiter_update_elen(struct udf_fileident_iter *iter, uint32_t new_elen) 441 { 442 struct udf_inode_info *iinfo = UDF_I(iter->dir); 443 int diff = new_elen - iter->elen; 444 445 /* Skip update when we already went past the last extent */ 446 if (!iter->elen) 447 return; 448 iter->elen = new_elen; 449 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 450 iter->epos.offset -= sizeof(struct short_ad); 451 else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) 452 iter->epos.offset -= sizeof(struct long_ad); 453 udf_write_aext(iter->dir, &iter->epos, &iter->eloc, iter->elen, 1); 454 iinfo->i_lenExtents += diff; 455 mark_inode_dirty(iter->dir); 456 } 457 458 /* Append new block to directory. @iter is expected to point at EOF */ 459 int udf_fiiter_append_blk(struct udf_fileident_iter *iter) 460 { 461 struct udf_inode_info *iinfo = UDF_I(iter->dir); 462 int blksize = 1 << iter->dir->i_blkbits; 463 struct buffer_head *bh; 464 sector_t block; 465 uint32_t old_elen = iter->elen; 466 int err; 467 int8_t etype; 468 469 if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)) 470 return -EINVAL; 471 472 /* Round up last extent in the file */ 473 udf_fiiter_update_elen(iter, ALIGN(iter->elen, blksize)); 474 475 /* Allocate new block and refresh mapping information */ 476 block = iinfo->i_lenExtents >> iter->dir->i_blkbits; 477 bh = udf_bread(iter->dir, block, 1, &err); 478 if (!bh) { 479 udf_fiiter_update_elen(iter, old_elen); 480 return err; 481 } 482 err = inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, 483 &iter->loffset, &etype); 484 if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) { 485 udf_err(iter->dir->i_sb, 486 "block %llu not allocated in directory (ino %lu)\n", 487 (unsigned long long)block, iter->dir->i_ino); 488 return -EFSCORRUPTED; 489 } 490 if (!(iter->pos & (blksize - 1))) { 491 brelse(iter->bh[0]); 492 iter->bh[0] = bh; 493 } else { 494 iter->bh[1] = bh; 495 } 496 return 0; 497 } 498 499 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, 500 int inc) 501 { 502 struct short_ad *sa; 503 504 if ((!ptr) || (!offset)) { 505 pr_err("%s: invalidparms\n", __func__); 506 return NULL; 507 } 508 509 if ((*offset + sizeof(struct short_ad)) > maxoffset) 510 return NULL; 511 else { 512 sa = (struct short_ad *)ptr; 513 if (sa->extLength == 0) 514 return NULL; 515 } 516 517 if (inc) 518 *offset += sizeof(struct short_ad); 519 return sa; 520 } 521 522 struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) 523 { 524 struct long_ad *la; 525 526 if ((!ptr) || (!offset)) { 527 pr_err("%s: invalidparms\n", __func__); 528 return NULL; 529 } 530 531 if ((*offset + sizeof(struct long_ad)) > maxoffset) 532 return NULL; 533 else { 534 la = (struct long_ad *)ptr; 535 if (la->extLength == 0) 536 return NULL; 537 } 538 539 if (inc) 540 *offset += sizeof(struct long_ad); 541 return la; 542 } 543