1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * Copyright (c) 2013 Red Hat, Inc. 5 * All Rights Reserved. 6 */ 7 #include "xfs.h" 8 #include "xfs_fs.h" 9 #include "xfs_shared.h" 10 #include "xfs_format.h" 11 #include "xfs_log_format.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_mount.h" 14 #include "xfs_da_format.h" 15 #include "xfs_inode.h" 16 #include "xfs_trans.h" 17 #include "xfs_bmap.h" 18 #include "xfs_attr.h" 19 #include "xfs_attr_sf.h" 20 #include "xfs_attr_leaf.h" 21 #include "xfs_error.h" 22 #include "xfs_trace.h" 23 #include "xfs_dir2.h" 24 25 STATIC int 26 xfs_attr_shortform_compare(const void *a, const void *b) 27 { 28 xfs_attr_sf_sort_t *sa, *sb; 29 30 sa = (xfs_attr_sf_sort_t *)a; 31 sb = (xfs_attr_sf_sort_t *)b; 32 if (sa->hash < sb->hash) { 33 return -1; 34 } else if (sa->hash > sb->hash) { 35 return 1; 36 } else { 37 return sa->entno - sb->entno; 38 } 39 } 40 41 #define XFS_ISRESET_CURSOR(cursor) \ 42 (!((cursor)->initted) && !((cursor)->hashval) && \ 43 !((cursor)->blkno) && !((cursor)->offset)) 44 /* 45 * Copy out entries of shortform attribute lists for attr_list(). 46 * Shortform attribute lists are not stored in hashval sorted order. 47 * If the output buffer is not large enough to hold them all, then we 48 * we have to calculate each entries' hashvalue and sort them before 49 * we can begin returning them to the user. 50 */ 51 static int 52 xfs_attr_shortform_list(xfs_attr_list_context_t *context) 53 { 54 attrlist_cursor_kern_t *cursor; 55 xfs_attr_sf_sort_t *sbuf, *sbp; 56 xfs_attr_shortform_t *sf; 57 xfs_attr_sf_entry_t *sfe; 58 xfs_inode_t *dp; 59 int sbsize, nsbuf, count, i; 60 61 ASSERT(context != NULL); 62 dp = context->dp; 63 ASSERT(dp != NULL); 64 ASSERT(dp->i_afp != NULL); 65 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; 66 ASSERT(sf != NULL); 67 if (!sf->hdr.count) 68 return 0; 69 cursor = context->cursor; 70 ASSERT(cursor != NULL); 71 72 trace_xfs_attr_list_sf(context); 73 74 /* 75 * If the buffer is large enough and the cursor is at the start, 76 * do not bother with sorting since we will return everything in 77 * one buffer and another call using the cursor won't need to be 78 * made. 79 * Note the generous fudge factor of 16 overhead bytes per entry. 80 * If bufsize is zero then put_listent must be a search function 81 * and can just scan through what we have. 82 */ 83 if (context->bufsize == 0 || 84 (XFS_ISRESET_CURSOR(cursor) && 85 (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { 86 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 87 context->put_listent(context, 88 sfe->flags, 89 sfe->nameval, 90 (int)sfe->namelen, 91 (int)sfe->valuelen); 92 /* 93 * Either search callback finished early or 94 * didn't fit it all in the buffer after all. 95 */ 96 if (context->seen_enough) 97 break; 98 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 99 } 100 trace_xfs_attr_list_sf_all(context); 101 return 0; 102 } 103 104 /* do no more for a search callback */ 105 if (context->bufsize == 0) 106 return 0; 107 108 /* 109 * It didn't all fit, so we have to sort everything on hashval. 110 */ 111 sbsize = sf->hdr.count * sizeof(*sbuf); 112 sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP | KM_NOFS); 113 114 /* 115 * Scan the attribute list for the rest of the entries, storing 116 * the relevant info from only those that match into a buffer. 117 */ 118 nsbuf = 0; 119 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 120 if (unlikely( 121 ((char *)sfe < (char *)sf) || 122 ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)))) { 123 XFS_CORRUPTION_ERROR("xfs_attr_shortform_list", 124 XFS_ERRLEVEL_LOW, 125 context->dp->i_mount, sfe, 126 sizeof(*sfe)); 127 kmem_free(sbuf); 128 return -EFSCORRUPTED; 129 } 130 131 sbp->entno = i; 132 sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); 133 sbp->name = sfe->nameval; 134 sbp->namelen = sfe->namelen; 135 /* These are bytes, and both on-disk, don't endian-flip */ 136 sbp->valuelen = sfe->valuelen; 137 sbp->flags = sfe->flags; 138 sfe = XFS_ATTR_SF_NEXTENTRY(sfe); 139 sbp++; 140 nsbuf++; 141 } 142 143 /* 144 * Sort the entries on hash then entno. 145 */ 146 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare); 147 148 /* 149 * Re-find our place IN THE SORTED LIST. 150 */ 151 count = 0; 152 cursor->initted = 1; 153 cursor->blkno = 0; 154 for (sbp = sbuf, i = 0; i < nsbuf; i++, sbp++) { 155 if (sbp->hash == cursor->hashval) { 156 if (cursor->offset == count) { 157 break; 158 } 159 count++; 160 } else if (sbp->hash > cursor->hashval) { 161 break; 162 } 163 } 164 if (i == nsbuf) { 165 kmem_free(sbuf); 166 return 0; 167 } 168 169 /* 170 * Loop putting entries into the user buffer. 171 */ 172 for ( ; i < nsbuf; i++, sbp++) { 173 if (cursor->hashval != sbp->hash) { 174 cursor->hashval = sbp->hash; 175 cursor->offset = 0; 176 } 177 context->put_listent(context, 178 sbp->flags, 179 sbp->name, 180 sbp->namelen, 181 sbp->valuelen); 182 if (context->seen_enough) 183 break; 184 cursor->offset++; 185 } 186 187 kmem_free(sbuf); 188 return 0; 189 } 190 191 /* 192 * We didn't find the block & hash mentioned in the cursor state, so 193 * walk down the attr btree looking for the hash. 194 */ 195 STATIC int 196 xfs_attr_node_list_lookup( 197 struct xfs_attr_list_context *context, 198 struct attrlist_cursor_kern *cursor, 199 struct xfs_buf **pbp) 200 { 201 struct xfs_da3_icnode_hdr nodehdr; 202 struct xfs_da_intnode *node; 203 struct xfs_da_node_entry *btree; 204 struct xfs_inode *dp = context->dp; 205 struct xfs_mount *mp = dp->i_mount; 206 struct xfs_trans *tp = context->tp; 207 struct xfs_buf *bp; 208 int i; 209 int error = 0; 210 unsigned int expected_level = 0; 211 uint16_t magic; 212 213 ASSERT(*pbp == NULL); 214 cursor->blkno = 0; 215 for (;;) { 216 error = xfs_da3_node_read(tp, dp, cursor->blkno, -1, &bp, 217 XFS_ATTR_FORK); 218 if (error) 219 return error; 220 node = bp->b_addr; 221 magic = be16_to_cpu(node->hdr.info.magic); 222 if (magic == XFS_ATTR_LEAF_MAGIC || 223 magic == XFS_ATTR3_LEAF_MAGIC) 224 break; 225 if (magic != XFS_DA_NODE_MAGIC && 226 magic != XFS_DA3_NODE_MAGIC) { 227 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, 228 node, sizeof(*node)); 229 goto out_corruptbuf; 230 } 231 232 dp->d_ops->node_hdr_from_disk(&nodehdr, node); 233 234 /* Tree taller than we can handle; bail out! */ 235 if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) 236 goto out_corruptbuf; 237 238 /* Check the level from the root node. */ 239 if (cursor->blkno == 0) 240 expected_level = nodehdr.level - 1; 241 else if (expected_level != nodehdr.level) 242 goto out_corruptbuf; 243 else 244 expected_level--; 245 246 btree = dp->d_ops->node_tree_p(node); 247 for (i = 0; i < nodehdr.count; btree++, i++) { 248 if (cursor->hashval <= be32_to_cpu(btree->hashval)) { 249 cursor->blkno = be32_to_cpu(btree->before); 250 trace_xfs_attr_list_node_descend(context, 251 btree); 252 break; 253 } 254 } 255 xfs_trans_brelse(tp, bp); 256 257 if (i == nodehdr.count) 258 return 0; 259 260 /* We can't point back to the root. */ 261 if (cursor->blkno == 0) 262 return -EFSCORRUPTED; 263 } 264 265 if (expected_level != 0) 266 goto out_corruptbuf; 267 268 *pbp = bp; 269 return 0; 270 271 out_corruptbuf: 272 xfs_trans_brelse(tp, bp); 273 return -EFSCORRUPTED; 274 } 275 276 STATIC int 277 xfs_attr_node_list( 278 struct xfs_attr_list_context *context) 279 { 280 struct xfs_attr3_icleaf_hdr leafhdr; 281 struct attrlist_cursor_kern *cursor; 282 struct xfs_attr_leafblock *leaf; 283 struct xfs_da_intnode *node; 284 struct xfs_buf *bp; 285 struct xfs_inode *dp = context->dp; 286 struct xfs_mount *mp = dp->i_mount; 287 int error; 288 289 trace_xfs_attr_node_list(context); 290 291 cursor = context->cursor; 292 cursor->initted = 1; 293 294 /* 295 * Do all sorts of validation on the passed-in cursor structure. 296 * If anything is amiss, ignore the cursor and look up the hashval 297 * starting from the btree root. 298 */ 299 bp = NULL; 300 if (cursor->blkno > 0) { 301 error = xfs_da3_node_read(context->tp, dp, cursor->blkno, -1, 302 &bp, XFS_ATTR_FORK); 303 if ((error != 0) && (error != -EFSCORRUPTED)) 304 return error; 305 if (bp) { 306 struct xfs_attr_leaf_entry *entries; 307 308 node = bp->b_addr; 309 switch (be16_to_cpu(node->hdr.info.magic)) { 310 case XFS_DA_NODE_MAGIC: 311 case XFS_DA3_NODE_MAGIC: 312 trace_xfs_attr_list_wrong_blk(context); 313 xfs_trans_brelse(context->tp, bp); 314 bp = NULL; 315 break; 316 case XFS_ATTR_LEAF_MAGIC: 317 case XFS_ATTR3_LEAF_MAGIC: 318 leaf = bp->b_addr; 319 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, 320 &leafhdr, leaf); 321 entries = xfs_attr3_leaf_entryp(leaf); 322 if (cursor->hashval > be32_to_cpu( 323 entries[leafhdr.count - 1].hashval)) { 324 trace_xfs_attr_list_wrong_blk(context); 325 xfs_trans_brelse(context->tp, bp); 326 bp = NULL; 327 } else if (cursor->hashval <= be32_to_cpu( 328 entries[0].hashval)) { 329 trace_xfs_attr_list_wrong_blk(context); 330 xfs_trans_brelse(context->tp, bp); 331 bp = NULL; 332 } 333 break; 334 default: 335 trace_xfs_attr_list_wrong_blk(context); 336 xfs_trans_brelse(context->tp, bp); 337 bp = NULL; 338 } 339 } 340 } 341 342 /* 343 * We did not find what we expected given the cursor's contents, 344 * so we start from the top and work down based on the hash value. 345 * Note that start of node block is same as start of leaf block. 346 */ 347 if (bp == NULL) { 348 error = xfs_attr_node_list_lookup(context, cursor, &bp); 349 if (error || !bp) 350 return error; 351 } 352 ASSERT(bp != NULL); 353 354 /* 355 * Roll upward through the blocks, processing each leaf block in 356 * order. As long as there is space in the result buffer, keep 357 * adding the information. 358 */ 359 for (;;) { 360 leaf = bp->b_addr; 361 xfs_attr3_leaf_list_int(bp, context); 362 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); 363 if (context->seen_enough || leafhdr.forw == 0) 364 break; 365 cursor->blkno = leafhdr.forw; 366 xfs_trans_brelse(context->tp, bp); 367 error = xfs_attr3_leaf_read(context->tp, dp, cursor->blkno, -1, &bp); 368 if (error) 369 return error; 370 } 371 xfs_trans_brelse(context->tp, bp); 372 return 0; 373 } 374 375 /* 376 * Copy out attribute list entries for attr_list(), for leaf attribute lists. 377 */ 378 void 379 xfs_attr3_leaf_list_int( 380 struct xfs_buf *bp, 381 struct xfs_attr_list_context *context) 382 { 383 struct attrlist_cursor_kern *cursor; 384 struct xfs_attr_leafblock *leaf; 385 struct xfs_attr3_icleaf_hdr ichdr; 386 struct xfs_attr_leaf_entry *entries; 387 struct xfs_attr_leaf_entry *entry; 388 int i; 389 struct xfs_mount *mp = context->dp->i_mount; 390 391 trace_xfs_attr_list_leaf(context); 392 393 leaf = bp->b_addr; 394 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); 395 entries = xfs_attr3_leaf_entryp(leaf); 396 397 cursor = context->cursor; 398 cursor->initted = 1; 399 400 /* 401 * Re-find our place in the leaf block if this is a new syscall. 402 */ 403 if (context->resynch) { 404 entry = &entries[0]; 405 for (i = 0; i < ichdr.count; entry++, i++) { 406 if (be32_to_cpu(entry->hashval) == cursor->hashval) { 407 if (cursor->offset == context->dupcnt) { 408 context->dupcnt = 0; 409 break; 410 } 411 context->dupcnt++; 412 } else if (be32_to_cpu(entry->hashval) > 413 cursor->hashval) { 414 context->dupcnt = 0; 415 break; 416 } 417 } 418 if (i == ichdr.count) { 419 trace_xfs_attr_list_notfound(context); 420 return; 421 } 422 } else { 423 entry = &entries[0]; 424 i = 0; 425 } 426 context->resynch = 0; 427 428 /* 429 * We have found our place, start copying out the new attributes. 430 */ 431 for (; i < ichdr.count; entry++, i++) { 432 char *name; 433 int namelen, valuelen; 434 435 if (be32_to_cpu(entry->hashval) != cursor->hashval) { 436 cursor->hashval = be32_to_cpu(entry->hashval); 437 cursor->offset = 0; 438 } 439 440 if ((entry->flags & XFS_ATTR_INCOMPLETE) && 441 !(context->flags & ATTR_INCOMPLETE)) 442 continue; /* skip incomplete entries */ 443 444 if (entry->flags & XFS_ATTR_LOCAL) { 445 xfs_attr_leaf_name_local_t *name_loc; 446 447 name_loc = xfs_attr3_leaf_name_local(leaf, i); 448 name = name_loc->nameval; 449 namelen = name_loc->namelen; 450 valuelen = be16_to_cpu(name_loc->valuelen); 451 } else { 452 xfs_attr_leaf_name_remote_t *name_rmt; 453 454 name_rmt = xfs_attr3_leaf_name_remote(leaf, i); 455 name = name_rmt->name; 456 namelen = name_rmt->namelen; 457 valuelen = be32_to_cpu(name_rmt->valuelen); 458 } 459 460 context->put_listent(context, entry->flags, 461 name, namelen, valuelen); 462 if (context->seen_enough) 463 break; 464 cursor->offset++; 465 } 466 trace_xfs_attr_list_leaf_end(context); 467 return; 468 } 469 470 /* 471 * Copy out attribute entries for attr_list(), for leaf attribute lists. 472 */ 473 STATIC int 474 xfs_attr_leaf_list(xfs_attr_list_context_t *context) 475 { 476 int error; 477 struct xfs_buf *bp; 478 479 trace_xfs_attr_leaf_list(context); 480 481 context->cursor->blkno = 0; 482 error = xfs_attr3_leaf_read(context->tp, context->dp, 0, -1, &bp); 483 if (error) 484 return error; 485 486 xfs_attr3_leaf_list_int(bp, context); 487 xfs_trans_brelse(context->tp, bp); 488 return 0; 489 } 490 491 int 492 xfs_attr_list_int_ilocked( 493 struct xfs_attr_list_context *context) 494 { 495 struct xfs_inode *dp = context->dp; 496 497 ASSERT(xfs_isilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 498 499 /* 500 * Decide on what work routines to call based on the inode size. 501 */ 502 if (!xfs_inode_hasattr(dp)) 503 return 0; 504 else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) 505 return xfs_attr_shortform_list(context); 506 else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) 507 return xfs_attr_leaf_list(context); 508 return xfs_attr_node_list(context); 509 } 510 511 int 512 xfs_attr_list_int( 513 xfs_attr_list_context_t *context) 514 { 515 int error; 516 xfs_inode_t *dp = context->dp; 517 uint lock_mode; 518 519 XFS_STATS_INC(dp->i_mount, xs_attr_list); 520 521 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 522 return -EIO; 523 524 lock_mode = xfs_ilock_attr_map_shared(dp); 525 error = xfs_attr_list_int_ilocked(context); 526 xfs_iunlock(dp, lock_mode); 527 return error; 528 } 529 530 #define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ 531 (((struct attrlist_ent *) 0)->a_name - (char *) 0) 532 #define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ 533 ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(uint32_t)-1) \ 534 & ~(sizeof(uint32_t)-1)) 535 536 /* 537 * Format an attribute and copy it out to the user's buffer. 538 * Take care to check values and protect against them changing later, 539 * we may be reading them directly out of a user buffer. 540 */ 541 STATIC void 542 xfs_attr_put_listent( 543 xfs_attr_list_context_t *context, 544 int flags, 545 unsigned char *name, 546 int namelen, 547 int valuelen) 548 { 549 struct attrlist *alist = (struct attrlist *)context->alist; 550 attrlist_ent_t *aep; 551 int arraytop; 552 553 ASSERT(!context->seen_enough); 554 ASSERT(!(context->flags & ATTR_KERNOVAL)); 555 ASSERT(context->count >= 0); 556 ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); 557 ASSERT(context->firstu >= sizeof(*alist)); 558 ASSERT(context->firstu <= context->bufsize); 559 560 /* 561 * Only list entries in the right namespace. 562 */ 563 if (((context->flags & ATTR_SECURE) == 0) != 564 ((flags & XFS_ATTR_SECURE) == 0)) 565 return; 566 if (((context->flags & ATTR_ROOT) == 0) != 567 ((flags & XFS_ATTR_ROOT) == 0)) 568 return; 569 570 arraytop = sizeof(*alist) + 571 context->count * sizeof(alist->al_offset[0]); 572 context->firstu -= ATTR_ENTSIZE(namelen); 573 if (context->firstu < arraytop) { 574 trace_xfs_attr_list_full(context); 575 alist->al_more = 1; 576 context->seen_enough = 1; 577 return; 578 } 579 580 aep = (attrlist_ent_t *)&context->alist[context->firstu]; 581 aep->a_valuelen = valuelen; 582 memcpy(aep->a_name, name, namelen); 583 aep->a_name[namelen] = 0; 584 alist->al_offset[context->count++] = context->firstu; 585 alist->al_count = context->count; 586 trace_xfs_attr_list_add(context); 587 return; 588 } 589 590 /* 591 * Generate a list of extended attribute names and optionally 592 * also value lengths. Positive return value follows the XFS 593 * convention of being an error, zero or negative return code 594 * is the length of the buffer returned (negated), indicating 595 * success. 596 */ 597 int 598 xfs_attr_list( 599 xfs_inode_t *dp, 600 char *buffer, 601 int bufsize, 602 int flags, 603 attrlist_cursor_kern_t *cursor) 604 { 605 xfs_attr_list_context_t context; 606 struct attrlist *alist; 607 int error; 608 609 /* 610 * Validate the cursor. 611 */ 612 if (cursor->pad1 || cursor->pad2) 613 return -EINVAL; 614 if ((cursor->initted == 0) && 615 (cursor->hashval || cursor->blkno || cursor->offset)) 616 return -EINVAL; 617 618 /* Only internal consumers can retrieve incomplete attrs. */ 619 if (flags & ATTR_INCOMPLETE) 620 return -EINVAL; 621 622 /* 623 * Check for a properly aligned buffer. 624 */ 625 if (((long)buffer) & (sizeof(int)-1)) 626 return -EFAULT; 627 if (flags & ATTR_KERNOVAL) 628 bufsize = 0; 629 630 /* 631 * Initialize the output buffer. 632 */ 633 memset(&context, 0, sizeof(context)); 634 context.dp = dp; 635 context.cursor = cursor; 636 context.resynch = 1; 637 context.flags = flags; 638 context.alist = buffer; 639 context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */ 640 context.firstu = context.bufsize; 641 context.put_listent = xfs_attr_put_listent; 642 643 alist = (struct attrlist *)context.alist; 644 alist->al_count = 0; 645 alist->al_more = 0; 646 alist->al_offset[0] = context.bufsize; 647 648 error = xfs_attr_list_int(&context); 649 ASSERT(error <= 0); 650 return error; 651 } 652