attr.c 13 KB

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