attr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2017 Oracle. All Rights Reserved.
  4. * Author: Darrick J. Wong <darrick.wong@oracle.com>
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_trans_resv.h"
  11. #include "xfs_mount.h"
  12. #include "xfs_defer.h"
  13. #include "xfs_btree.h"
  14. #include "xfs_bit.h"
  15. #include "xfs_log_format.h"
  16. #include "xfs_trans.h"
  17. #include "xfs_sb.h"
  18. #include "xfs_inode.h"
  19. #include "xfs_da_format.h"
  20. #include "xfs_da_btree.h"
  21. #include "xfs_dir2.h"
  22. #include "xfs_attr.h"
  23. #include "xfs_attr_leaf.h"
  24. #include "scrub/xfs_scrub.h"
  25. #include "scrub/scrub.h"
  26. #include "scrub/common.h"
  27. #include "scrub/dabtree.h"
  28. #include "scrub/trace.h"
  29. #include <linux/posix_acl_xattr.h>
  30. #include <linux/xattr.h>
  31. /* Set us up to scrub an inode's extended attributes. */
  32. int
  33. xchk_setup_xattr(
  34. struct xfs_scrub *sc,
  35. struct xfs_inode *ip)
  36. {
  37. size_t sz;
  38. /*
  39. * Allocate the buffer without the inode lock held. We need enough
  40. * space to read every xattr value in the file or enough space to
  41. * hold three copies of the xattr free space bitmap. (Not both at
  42. * the same time.)
  43. */
  44. sz = max_t(size_t, XATTR_SIZE_MAX, 3 * sizeof(long) *
  45. BITS_TO_LONGS(sc->mp->m_attr_geo->blksize));
  46. sc->buf = kmem_zalloc_large(sz, KM_SLEEP);
  47. if (!sc->buf)
  48. return -ENOMEM;
  49. return xchk_setup_inode_contents(sc, ip, 0);
  50. }
  51. /* Extended Attributes */
  52. struct xchk_xattr {
  53. struct xfs_attr_list_context context;
  54. struct xfs_scrub *sc;
  55. };
  56. /*
  57. * Check that an extended attribute key can be looked up by hash.
  58. *
  59. * We use the XFS attribute list iterator (i.e. xfs_attr_list_int_ilocked)
  60. * to call this function for every attribute key in an inode. Once
  61. * we're here, we load the attribute value to see if any errors happen,
  62. * or if we get more or less data than we expected.
  63. */
  64. static void
  65. xchk_xattr_listent(
  66. struct xfs_attr_list_context *context,
  67. int flags,
  68. unsigned char *name,
  69. int namelen,
  70. int valuelen)
  71. {
  72. struct xchk_xattr *sx;
  73. struct xfs_da_args args = { NULL };
  74. int error = 0;
  75. sx = container_of(context, struct xchk_xattr, context);
  76. if (flags & XFS_ATTR_INCOMPLETE) {
  77. /* Incomplete attr key, just mark the inode for preening. */
  78. xchk_ino_set_preen(sx->sc, context->dp->i_ino);
  79. return;
  80. }
  81. args.flags = ATTR_KERNOTIME;
  82. if (flags & XFS_ATTR_ROOT)
  83. args.flags |= ATTR_ROOT;
  84. else if (flags & XFS_ATTR_SECURE)
  85. args.flags |= ATTR_SECURE;
  86. args.geo = context->dp->i_mount->m_attr_geo;
  87. args.whichfork = XFS_ATTR_FORK;
  88. args.dp = context->dp;
  89. args.name = name;
  90. args.namelen = namelen;
  91. args.hashval = xfs_da_hashname(args.name, args.namelen);
  92. args.trans = context->tp;
  93. args.value = sx->sc->buf;
  94. args.valuelen = XATTR_SIZE_MAX;
  95. error = xfs_attr_get_ilocked(context->dp, &args);
  96. if (error == -EEXIST)
  97. error = 0;
  98. if (!xchk_fblock_process_error(sx->sc, XFS_ATTR_FORK, args.blkno,
  99. &error))
  100. goto fail_xref;
  101. if (args.valuelen != valuelen)
  102. xchk_fblock_set_corrupt(sx->sc, XFS_ATTR_FORK,
  103. args.blkno);
  104. fail_xref:
  105. if (sx->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  106. context->seen_enough = 1;
  107. return;
  108. }
  109. /*
  110. * Mark a range [start, start+len) in this map. Returns true if the
  111. * region was free, and false if there's a conflict or a problem.
  112. *
  113. * Within a char, the lowest bit of the char represents the byte with
  114. * the smallest address
  115. */
  116. STATIC bool
  117. xchk_xattr_set_map(
  118. struct xfs_scrub *sc,
  119. unsigned long *map,
  120. unsigned int start,
  121. unsigned int len)
  122. {
  123. unsigned int mapsize = sc->mp->m_attr_geo->blksize;
  124. bool ret = true;
  125. if (start >= mapsize)
  126. return false;
  127. if (start + len > mapsize) {
  128. len = mapsize - start;
  129. ret = false;
  130. }
  131. if (find_next_bit(map, mapsize, start) < start + len)
  132. ret = false;
  133. bitmap_set(map, start, len);
  134. return ret;
  135. }
  136. /*
  137. * Check the leaf freemap from the usage bitmap. Returns false if the
  138. * attr freemap has problems or points to used space.
  139. */
  140. STATIC bool
  141. xchk_xattr_check_freemap(
  142. struct xfs_scrub *sc,
  143. unsigned long *map,
  144. struct xfs_attr3_icleaf_hdr *leafhdr)
  145. {
  146. unsigned long *freemap;
  147. unsigned long *dstmap;
  148. unsigned int mapsize = sc->mp->m_attr_geo->blksize;
  149. int i;
  150. /* Construct bitmap of freemap contents. */
  151. freemap = (unsigned long *)sc->buf + BITS_TO_LONGS(mapsize);
  152. bitmap_zero(freemap, mapsize);
  153. for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
  154. if (!xchk_xattr_set_map(sc, freemap,
  155. leafhdr->freemap[i].base,
  156. leafhdr->freemap[i].size))
  157. return false;
  158. }
  159. /* Look for bits that are set in freemap and are marked in use. */
  160. dstmap = freemap + BITS_TO_LONGS(mapsize);
  161. return bitmap_and(dstmap, freemap, map, mapsize) == 0;
  162. }
  163. /*
  164. * Check this leaf entry's relations to everything else.
  165. * Returns the number of bytes used for the name/value data.
  166. */
  167. STATIC void
  168. xchk_xattr_entry(
  169. struct xchk_da_btree *ds,
  170. int level,
  171. char *buf_end,
  172. struct xfs_attr_leafblock *leaf,
  173. struct xfs_attr3_icleaf_hdr *leafhdr,
  174. unsigned long *usedmap,
  175. struct xfs_attr_leaf_entry *ent,
  176. int idx,
  177. unsigned int *usedbytes,
  178. __u32 *last_hashval)
  179. {
  180. struct xfs_mount *mp = ds->state->mp;
  181. char *name_end;
  182. struct xfs_attr_leaf_name_local *lentry;
  183. struct xfs_attr_leaf_name_remote *rentry;
  184. unsigned int nameidx;
  185. unsigned int namesize;
  186. if (ent->pad2 != 0)
  187. xchk_da_set_corrupt(ds, level);
  188. /* Hash values in order? */
  189. if (be32_to_cpu(ent->hashval) < *last_hashval)
  190. xchk_da_set_corrupt(ds, level);
  191. *last_hashval = be32_to_cpu(ent->hashval);
  192. nameidx = be16_to_cpu(ent->nameidx);
  193. if (nameidx < leafhdr->firstused ||
  194. nameidx >= mp->m_attr_geo->blksize) {
  195. xchk_da_set_corrupt(ds, level);
  196. return;
  197. }
  198. /* Check the name information. */
  199. if (ent->flags & XFS_ATTR_LOCAL) {
  200. lentry = xfs_attr3_leaf_name_local(leaf, idx);
  201. namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
  202. be16_to_cpu(lentry->valuelen));
  203. name_end = (char *)lentry + namesize;
  204. if (lentry->namelen == 0)
  205. xchk_da_set_corrupt(ds, level);
  206. } else {
  207. rentry = xfs_attr3_leaf_name_remote(leaf, idx);
  208. namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
  209. name_end = (char *)rentry + namesize;
  210. if (rentry->namelen == 0 || rentry->valueblk == 0)
  211. xchk_da_set_corrupt(ds, level);
  212. }
  213. if (name_end > buf_end)
  214. xchk_da_set_corrupt(ds, level);
  215. if (!xchk_xattr_set_map(ds->sc, usedmap, nameidx, namesize))
  216. xchk_da_set_corrupt(ds, level);
  217. if (!(ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
  218. *usedbytes += namesize;
  219. }
  220. /* Scrub an attribute leaf. */
  221. STATIC int
  222. xchk_xattr_block(
  223. struct xchk_da_btree *ds,
  224. int level)
  225. {
  226. struct xfs_attr3_icleaf_hdr leafhdr;
  227. struct xfs_mount *mp = ds->state->mp;
  228. struct xfs_da_state_blk *blk = &ds->state->path.blk[level];
  229. struct xfs_buf *bp = blk->bp;
  230. xfs_dablk_t *last_checked = ds->private;
  231. struct xfs_attr_leafblock *leaf = bp->b_addr;
  232. struct xfs_attr_leaf_entry *ent;
  233. struct xfs_attr_leaf_entry *entries;
  234. unsigned long *usedmap = ds->sc->buf;
  235. char *buf_end;
  236. size_t off;
  237. __u32 last_hashval = 0;
  238. unsigned int usedbytes = 0;
  239. unsigned int hdrsize;
  240. int i;
  241. if (*last_checked == blk->blkno)
  242. return 0;
  243. *last_checked = blk->blkno;
  244. bitmap_zero(usedmap, mp->m_attr_geo->blksize);
  245. /* Check all the padding. */
  246. if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb)) {
  247. struct xfs_attr3_leafblock *leaf = bp->b_addr;
  248. if (leaf->hdr.pad1 != 0 || leaf->hdr.pad2 != 0 ||
  249. leaf->hdr.info.hdr.pad != 0)
  250. xchk_da_set_corrupt(ds, level);
  251. } else {
  252. if (leaf->hdr.pad1 != 0 || leaf->hdr.info.pad != 0)
  253. xchk_da_set_corrupt(ds, level);
  254. }
  255. /* Check the leaf header */
  256. xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
  257. hdrsize = xfs_attr3_leaf_hdr_size(leaf);
  258. if (leafhdr.usedbytes > mp->m_attr_geo->blksize)
  259. xchk_da_set_corrupt(ds, level);
  260. if (leafhdr.firstused > mp->m_attr_geo->blksize)
  261. xchk_da_set_corrupt(ds, level);
  262. if (leafhdr.firstused < hdrsize)
  263. xchk_da_set_corrupt(ds, level);
  264. if (!xchk_xattr_set_map(ds->sc, usedmap, 0, hdrsize))
  265. xchk_da_set_corrupt(ds, level);
  266. if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  267. goto out;
  268. entries = xfs_attr3_leaf_entryp(leaf);
  269. if ((char *)&entries[leafhdr.count] > (char *)leaf + leafhdr.firstused)
  270. xchk_da_set_corrupt(ds, level);
  271. buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
  272. for (i = 0, ent = entries; i < leafhdr.count; ent++, i++) {
  273. /* Mark the leaf entry itself. */
  274. off = (char *)ent - (char *)leaf;
  275. if (!xchk_xattr_set_map(ds->sc, usedmap, off,
  276. sizeof(xfs_attr_leaf_entry_t))) {
  277. xchk_da_set_corrupt(ds, level);
  278. goto out;
  279. }
  280. /* Check the entry and nameval. */
  281. xchk_xattr_entry(ds, level, buf_end, leaf, &leafhdr,
  282. usedmap, ent, i, &usedbytes, &last_hashval);
  283. if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  284. goto out;
  285. }
  286. if (!xchk_xattr_check_freemap(ds->sc, usedmap, &leafhdr))
  287. xchk_da_set_corrupt(ds, level);
  288. if (leafhdr.usedbytes != usedbytes)
  289. xchk_da_set_corrupt(ds, level);
  290. out:
  291. return 0;
  292. }
  293. /* Scrub a attribute btree record. */
  294. STATIC int
  295. xchk_xattr_rec(
  296. struct xchk_da_btree *ds,
  297. int level,
  298. void *rec)
  299. {
  300. struct xfs_mount *mp = ds->state->mp;
  301. struct xfs_attr_leaf_entry *ent = rec;
  302. struct xfs_da_state_blk *blk;
  303. struct xfs_attr_leaf_name_local *lentry;
  304. struct xfs_attr_leaf_name_remote *rentry;
  305. struct xfs_buf *bp;
  306. xfs_dahash_t calc_hash;
  307. xfs_dahash_t hash;
  308. int nameidx;
  309. int hdrsize;
  310. unsigned int badflags;
  311. int error;
  312. blk = &ds->state->path.blk[level];
  313. /* Check the whole block, if necessary. */
  314. error = xchk_xattr_block(ds, level);
  315. if (error)
  316. goto out;
  317. if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  318. goto out;
  319. /* Check the hash of the entry. */
  320. error = xchk_da_btree_hash(ds, level, &ent->hashval);
  321. if (error)
  322. goto out;
  323. /* Find the attr entry's location. */
  324. bp = blk->bp;
  325. hdrsize = xfs_attr3_leaf_hdr_size(bp->b_addr);
  326. nameidx = be16_to_cpu(ent->nameidx);
  327. if (nameidx < hdrsize || nameidx >= mp->m_attr_geo->blksize) {
  328. xchk_da_set_corrupt(ds, level);
  329. goto out;
  330. }
  331. /* Retrieve the entry and check it. */
  332. hash = be32_to_cpu(ent->hashval);
  333. badflags = ~(XFS_ATTR_LOCAL | XFS_ATTR_ROOT | XFS_ATTR_SECURE |
  334. XFS_ATTR_INCOMPLETE);
  335. if ((ent->flags & badflags) != 0)
  336. xchk_da_set_corrupt(ds, level);
  337. if (ent->flags & XFS_ATTR_LOCAL) {
  338. lentry = (struct xfs_attr_leaf_name_local *)
  339. (((char *)bp->b_addr) + nameidx);
  340. if (lentry->namelen <= 0) {
  341. xchk_da_set_corrupt(ds, level);
  342. goto out;
  343. }
  344. calc_hash = xfs_da_hashname(lentry->nameval, lentry->namelen);
  345. } else {
  346. rentry = (struct xfs_attr_leaf_name_remote *)
  347. (((char *)bp->b_addr) + nameidx);
  348. if (rentry->namelen <= 0) {
  349. xchk_da_set_corrupt(ds, level);
  350. goto out;
  351. }
  352. calc_hash = xfs_da_hashname(rentry->name, rentry->namelen);
  353. }
  354. if (calc_hash != hash)
  355. xchk_da_set_corrupt(ds, level);
  356. out:
  357. return error;
  358. }
  359. /* Scrub the extended attribute metadata. */
  360. int
  361. xchk_xattr(
  362. struct xfs_scrub *sc)
  363. {
  364. struct xchk_xattr sx;
  365. struct attrlist_cursor_kern cursor = { 0 };
  366. xfs_dablk_t last_checked = -1U;
  367. int error = 0;
  368. if (!xfs_inode_hasattr(sc->ip))
  369. return -ENOENT;
  370. memset(&sx, 0, sizeof(sx));
  371. /* Check attribute tree structure */
  372. error = xchk_da_btree(sc, XFS_ATTR_FORK, xchk_xattr_rec,
  373. &last_checked);
  374. if (error)
  375. goto out;
  376. if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  377. goto out;
  378. /* Check that every attr key can also be looked up by hash. */
  379. sx.context.dp = sc->ip;
  380. sx.context.cursor = &cursor;
  381. sx.context.resynch = 1;
  382. sx.context.put_listent = xchk_xattr_listent;
  383. sx.context.tp = sc->tp;
  384. sx.context.flags = ATTR_INCOMPLETE;
  385. sx.sc = sc;
  386. /*
  387. * Look up every xattr in this file by name.
  388. *
  389. * Use the backend implementation of xfs_attr_list to call
  390. * xchk_xattr_listent on every attribute key in this inode.
  391. * In other words, we use the same iterator/callback mechanism
  392. * that listattr uses to scrub extended attributes, though in our
  393. * _listent function, we check the value of the attribute.
  394. *
  395. * The VFS only locks i_rwsem when modifying attrs, so keep all
  396. * three locks held because that's the only way to ensure we're
  397. * the only thread poking into the da btree. We traverse the da
  398. * btree while holding a leaf buffer locked for the xattr name
  399. * iteration, which doesn't really follow the usual buffer
  400. * locking order.
  401. */
  402. error = xfs_attr_list_int_ilocked(&sx.context);
  403. if (!xchk_fblock_process_error(sc, XFS_ATTR_FORK, 0, &error))
  404. goto out;
  405. out:
  406. return error;
  407. }