Merge tag 'xfs-4.11-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull XFS fixes from Darrick Wong:
"Here are three more fixes for 4.11.

The first one reworks the inline directory verifier to check the
working copy of the directory metadata and to avoid triggering a
periodic crash in xfs/348. The second patch fixes a regression in hole
punching at EOF that corrupts files; and the third patch closes a
kernel memory disclosure bug.

Summary:

- rework the inline directory verifier to avoid crashes on disk
corruption

- don't change file size when punching holes w/ KEEP_SIZE

- close a kernel memory exposure bug"

* tag 'xfs-4.11-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: fix kernel memory exposure problems
xfs: Honor FALLOC_FL_KEEP_SIZE when punching ends of files
xfs: rework the inline directory verifiers

+76 -58
+1 -2
fs/xfs/libxfs/xfs_dir2_priv.h
··· 125 125 extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); 126 126 extern int xfs_dir2_sf_removename(struct xfs_da_args *args); 127 127 extern int xfs_dir2_sf_replace(struct xfs_da_args *args); 128 - extern int xfs_dir2_sf_verify(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *sfp, 129 - int size); 128 + extern int xfs_dir2_sf_verify(struct xfs_inode *ip); 130 129 131 130 /* xfs_dir2_readdir.c */ 132 131 extern int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx,
+41 -22
fs/xfs/libxfs/xfs_dir2_sf.c
··· 632 632 /* Verify the consistency of an inline directory. */ 633 633 int 634 634 xfs_dir2_sf_verify( 635 - struct xfs_mount *mp, 636 - struct xfs_dir2_sf_hdr *sfp, 637 - int size) 635 + struct xfs_inode *ip) 638 636 { 637 + struct xfs_mount *mp = ip->i_mount; 638 + struct xfs_dir2_sf_hdr *sfp; 639 639 struct xfs_dir2_sf_entry *sfep; 640 640 struct xfs_dir2_sf_entry *next_sfep; 641 641 char *endp; 642 642 const struct xfs_dir_ops *dops; 643 + struct xfs_ifork *ifp; 643 644 xfs_ino_t ino; 644 645 int i; 645 646 int i8count; 646 647 int offset; 648 + int size; 649 + int error; 647 650 __uint8_t filetype; 648 651 652 + ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); 653 + /* 654 + * xfs_iread calls us before xfs_setup_inode sets up ip->d_ops, 655 + * so we can only trust the mountpoint to have the right pointer. 656 + */ 649 657 dops = xfs_dir_get_ops(mp, NULL); 658 + 659 + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 660 + sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; 661 + size = ifp->if_bytes; 650 662 651 663 /* 652 664 * Give up if the directory is way too short. 653 665 */ 654 - XFS_WANT_CORRUPTED_RETURN(mp, size > 655 - offsetof(struct xfs_dir2_sf_hdr, parent)); 656 - XFS_WANT_CORRUPTED_RETURN(mp, size >= 657 - xfs_dir2_sf_hdr_size(sfp->i8count)); 666 + if (size <= offsetof(struct xfs_dir2_sf_hdr, parent) || 667 + size < xfs_dir2_sf_hdr_size(sfp->i8count)) 668 + return -EFSCORRUPTED; 658 669 659 670 endp = (char *)sfp + size; 660 671 661 672 /* Check .. entry */ 662 673 ino = dops->sf_get_parent_ino(sfp); 663 674 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 664 - XFS_WANT_CORRUPTED_RETURN(mp, !xfs_dir_ino_validate(mp, ino)); 675 + error = xfs_dir_ino_validate(mp, ino); 676 + if (error) 677 + return error; 665 678 offset = dops->data_first_offset; 666 679 667 680 /* Check all reported entries */ ··· 685 672 * Check the fixed-offset parts of the structure are 686 673 * within the data buffer. 687 674 */ 688 - XFS_WANT_CORRUPTED_RETURN(mp, 689 - ((char *)sfep + sizeof(*sfep)) < endp); 675 + if (((char *)sfep + sizeof(*sfep)) >= endp) 676 + return -EFSCORRUPTED; 690 677 691 678 /* Don't allow names with known bad length. */ 692 - XFS_WANT_CORRUPTED_RETURN(mp, sfep->namelen > 0); 693 - XFS_WANT_CORRUPTED_RETURN(mp, sfep->namelen < MAXNAMELEN); 679 + if (sfep->namelen == 0) 680 + return -EFSCORRUPTED; 694 681 695 682 /* 696 683 * Check that the variable-length part of the structure is ··· 698 685 * name component, so nextentry is an acceptable test. 699 686 */ 700 687 next_sfep = dops->sf_nextentry(sfp, sfep); 701 - XFS_WANT_CORRUPTED_RETURN(mp, endp >= (char *)next_sfep); 688 + if (endp < (char *)next_sfep) 689 + return -EFSCORRUPTED; 702 690 703 691 /* Check that the offsets always increase. */ 704 - XFS_WANT_CORRUPTED_RETURN(mp, 705 - xfs_dir2_sf_get_offset(sfep) >= offset); 692 + if (xfs_dir2_sf_get_offset(sfep) < offset) 693 + return -EFSCORRUPTED; 706 694 707 695 /* Check the inode number. */ 708 696 ino = dops->sf_get_ino(sfp, sfep); 709 697 i8count += ino > XFS_DIR2_MAX_SHORT_INUM; 710 - XFS_WANT_CORRUPTED_RETURN(mp, !xfs_dir_ino_validate(mp, ino)); 698 + error = xfs_dir_ino_validate(mp, ino); 699 + if (error) 700 + return error; 711 701 712 702 /* Check the file type. */ 713 703 filetype = dops->sf_get_ftype(sfep); 714 - XFS_WANT_CORRUPTED_RETURN(mp, filetype < XFS_DIR3_FT_MAX); 704 + if (filetype >= XFS_DIR3_FT_MAX) 705 + return -EFSCORRUPTED; 715 706 716 707 offset = xfs_dir2_sf_get_offset(sfep) + 717 708 dops->data_entsize(sfep->namelen); 718 709 719 710 sfep = next_sfep; 720 711 } 721 - XFS_WANT_CORRUPTED_RETURN(mp, i8count == sfp->i8count); 722 - XFS_WANT_CORRUPTED_RETURN(mp, (void *)sfep == (void *)endp); 712 + if (i8count != sfp->i8count) 713 + return -EFSCORRUPTED; 714 + if ((void *)sfep != (void *)endp) 715 + return -EFSCORRUPTED; 723 716 724 717 /* Make sure this whole thing ought to be in local format. */ 725 - XFS_WANT_CORRUPTED_RETURN(mp, offset + 726 - (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + 727 - (uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dir_geo->blksize); 718 + if (offset + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + 719 + (uint)sizeof(xfs_dir2_block_tail_t) > mp->m_dir_geo->blksize) 720 + return -EFSCORRUPTED; 728 721 729 722 return 0; 730 723 }
+13 -22
fs/xfs/libxfs/xfs_inode_fork.c
··· 212 212 if (error) 213 213 return error; 214 214 215 + /* Check inline dir contents. */ 216 + if (S_ISDIR(VFS_I(ip)->i_mode) && 217 + dip->di_format == XFS_DINODE_FMT_LOCAL) { 218 + error = xfs_dir2_sf_verify(ip); 219 + if (error) { 220 + xfs_idestroy_fork(ip, XFS_DATA_FORK); 221 + return error; 222 + } 223 + } 224 + 215 225 if (xfs_is_reflink_inode(ip)) { 216 226 ASSERT(ip->i_cowfp == NULL); 217 227 xfs_ifork_init_cow(ip); ··· 332 322 int whichfork, 333 323 int size) 334 324 { 335 - int error; 336 - 337 325 /* 338 326 * If the size is unreasonable, then something 339 327 * is wrong and we just bail out rather than crash in ··· 345 337 XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, 346 338 ip->i_mount, dip); 347 339 return -EFSCORRUPTED; 348 - } 349 - 350 - if (S_ISDIR(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK) { 351 - error = xfs_dir2_sf_verify(ip->i_mount, 352 - (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip), 353 - size); 354 - if (error) 355 - return error; 356 340 } 357 341 358 342 xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size); ··· 867 867 * In these cases, the format always takes precedence, because the 868 868 * format indicates the current state of the fork. 869 869 */ 870 - int 870 + void 871 871 xfs_iflush_fork( 872 872 xfs_inode_t *ip, 873 873 xfs_dinode_t *dip, ··· 877 877 char *cp; 878 878 xfs_ifork_t *ifp; 879 879 xfs_mount_t *mp; 880 - int error; 881 880 static const short brootflag[2] = 882 881 { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; 883 882 static const short dataflag[2] = ··· 885 886 { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; 886 887 887 888 if (!iip) 888 - return 0; 889 + return; 889 890 ifp = XFS_IFORK_PTR(ip, whichfork); 890 891 /* 891 892 * This can happen if we gave up in iformat in an error path, ··· 893 894 */ 894 895 if (!ifp) { 895 896 ASSERT(whichfork == XFS_ATTR_FORK); 896 - return 0; 897 + return; 897 898 } 898 899 cp = XFS_DFORK_PTR(dip, whichfork); 899 900 mp = ip->i_mount; 900 901 switch (XFS_IFORK_FORMAT(ip, whichfork)) { 901 902 case XFS_DINODE_FMT_LOCAL: 902 - if (S_ISDIR(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK) { 903 - error = xfs_dir2_sf_verify(mp, 904 - (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data, 905 - ifp->if_bytes); 906 - if (error) 907 - return error; 908 - } 909 903 if ((iip->ili_fields & dataflag[whichfork]) && 910 904 (ifp->if_bytes > 0)) { 911 905 ASSERT(ifp->if_u1.if_data != NULL); ··· 951 959 ASSERT(0); 952 960 break; 953 961 } 954 - return 0; 955 962 } 956 963 957 964 /*
+1 -1
fs/xfs/libxfs/xfs_inode_fork.h
··· 140 140 struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); 141 141 142 142 int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); 143 - int xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 143 + void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 144 144 struct xfs_inode_log_item *, int); 145 145 void xfs_idestroy_fork(struct xfs_inode *, int); 146 146 void xfs_idata_realloc(struct xfs_inode *, int, int);
+9 -1
fs/xfs/xfs_bmap_util.c
··· 1311 1311 /* 1312 1312 * Now that we've unmap all full blocks we'll have to zero out any 1313 1313 * partial block at the beginning and/or end. xfs_zero_range is 1314 - * smart enough to skip any holes, including those we just created. 1314 + * smart enough to skip any holes, including those we just created, 1315 + * but we must take care not to zero beyond EOF and enlarge i_size. 1315 1316 */ 1317 + 1318 + if (offset >= XFS_ISIZE(ip)) 1319 + return 0; 1320 + 1321 + if (offset + len > XFS_ISIZE(ip)) 1322 + len = XFS_ISIZE(ip) - offset; 1323 + 1316 1324 return xfs_zero_range(ip, offset, len, NULL); 1317 1325 } 1318 1326
+10 -9
fs/xfs/xfs_inode.c
··· 50 50 #include "xfs_log.h" 51 51 #include "xfs_bmap_btree.h" 52 52 #include "xfs_reflink.h" 53 + #include "xfs_dir2_priv.h" 53 54 54 55 kmem_zone_t *xfs_inode_zone; 55 56 ··· 3476 3475 struct xfs_inode_log_item *iip = ip->i_itemp; 3477 3476 struct xfs_dinode *dip; 3478 3477 struct xfs_mount *mp = ip->i_mount; 3479 - int error; 3480 3478 3481 3479 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 3482 3480 ASSERT(xfs_isiflocked(ip)); ··· 3547 3547 if (ip->i_d.di_version < 3) 3548 3548 ip->i_d.di_flushiter++; 3549 3549 3550 + /* Check the inline directory data. */ 3551 + if (S_ISDIR(VFS_I(ip)->i_mode) && 3552 + ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && 3553 + xfs_dir2_sf_verify(ip)) 3554 + goto corrupt_out; 3555 + 3550 3556 /* 3551 3557 * Copy the dirty parts of the inode into the on-disk inode. We always 3552 3558 * copy out the core of the inode, because if the inode is dirty at all ··· 3564 3558 if (ip->i_d.di_flushiter == DI_MAX_FLUSH) 3565 3559 ip->i_d.di_flushiter = 0; 3566 3560 3567 - error = xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); 3568 - if (error) 3569 - return error; 3570 - if (XFS_IFORK_Q(ip)) { 3571 - error = xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); 3572 - if (error) 3573 - return error; 3574 - } 3561 + xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); 3562 + if (XFS_IFORK_Q(ip)) 3563 + xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); 3575 3564 xfs_inobp_check(mp, bp); 3576 3565 3577 3566 /*
+1 -1
fs/xfs/xfs_itable.c
··· 583 583 return error; 584 584 585 585 bcount = MIN(left, (int)(PAGE_SIZE / sizeof(*buffer))); 586 - buffer = kmem_alloc(bcount * sizeof(*buffer), KM_SLEEP); 586 + buffer = kmem_zalloc(bcount * sizeof(*buffer), KM_SLEEP); 587 587 do { 588 588 struct xfs_inobt_rec_incore r; 589 589 int stat;