Browse Source

Merge tag 'usercopy-fix-v4.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull usercopy whitelisting fix from Kees Cook:
 "Bart Massey discovered that the usercopy whitelist for JFS was
  incomplete: the inline inode data may intentionally "overflow" into
  the neighboring "extended area", so the size of the whitelist needed
  to be raised to include the neighboring field"

* tag 'usercopy-fix-v4.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  jfs: Fix usercopy whitelist for inline inode data
Linus Torvalds 7 years ago
parent
commit
60f5a21736
3 changed files with 9 additions and 2 deletions
  1. 7 0
      fs/jfs/jfs_dinode.h
  2. 1 0
      fs/jfs/jfs_incore.h
  3. 1 2
      fs/jfs/super.c

+ 7 - 0
fs/jfs/jfs_dinode.h

@@ -115,6 +115,13 @@ struct dinode {
 					dxd_t _dxd;	/* 16: */
 					dxd_t _dxd;	/* 16: */
 					union {
 					union {
 						__le32 _rdev;	/* 4: */
 						__le32 _rdev;	/* 4: */
+						/*
+						 * The fast symlink area
+						 * is expected to overflow
+						 * into _inlineea when
+						 * needed (which will clear
+						 * INLINEEA).
+						 */
 						u8 _fastsymlink[128];
 						u8 _fastsymlink[128];
 					} _u;
 					} _u;
 					u8 _inlineea[128];
 					u8 _inlineea[128];

+ 1 - 0
fs/jfs/jfs_incore.h

@@ -87,6 +87,7 @@ struct jfs_inode_info {
 		struct {
 		struct {
 			unchar _unused[16];	/* 16: */
 			unchar _unused[16];	/* 16: */
 			dxd_t _dxd;		/* 16: */
 			dxd_t _dxd;		/* 16: */
+			/* _inline may overflow into _inline_ea when needed */
 			unchar _inline[128];	/* 128: inline symlink */
 			unchar _inline[128];	/* 128: inline symlink */
 			/* _inline_ea may overlay the last part of
 			/* _inline_ea may overlay the last part of
 			 * file._xtroot if maxentry = XTROOTINITSLOT
 			 * file._xtroot if maxentry = XTROOTINITSLOT

+ 1 - 2
fs/jfs/super.c

@@ -967,8 +967,7 @@ static int __init init_jfs_fs(void)
 	jfs_inode_cachep =
 	jfs_inode_cachep =
 	    kmem_cache_create_usercopy("jfs_ip", sizeof(struct jfs_inode_info),
 	    kmem_cache_create_usercopy("jfs_ip", sizeof(struct jfs_inode_info),
 			0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT,
 			0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT,
-			offsetof(struct jfs_inode_info, i_inline),
-			sizeof_field(struct jfs_inode_info, i_inline),
+			offsetof(struct jfs_inode_info, i_inline), IDATASIZE,
 			init_once);
 			init_once);
 	if (jfs_inode_cachep == NULL)
 	if (jfs_inode_cachep == NULL)
 		return -ENOMEM;
 		return -ENOMEM;