--- /dev/null
+From 92d34134193e5b129dc24f8d79cb9196626e8d7a Mon Sep 17 00:00:00 2001
+From: Shankara Pailoor <shankarapailoor@gmail.com>
+Date: Tue, 5 Jun 2018 08:33:27 -0500
+Subject: jfs: Fix inconsistency between memory allocation and ea_buf->max_size
+
+From: Shankara Pailoor <shankarapailoor@gmail.com>
+
+commit 92d34134193e5b129dc24f8d79cb9196626e8d7a upstream.
+
+The code is assuming the buffer is max_size length, but we weren't
+allocating enough space for it.
+
+Signed-off-by: Shankara Pailoor <shankarapailoor@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jfs/xattr.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/fs/jfs/xattr.c
++++ b/fs/jfs/xattr.c
+@@ -491,15 +491,17 @@ static int ea_get(struct inode *inode, s
+ if (size > PSIZE) {
+ /*
+ * To keep the rest of the code simple. Allocate a
+- * contiguous buffer to work with
++ * contiguous buffer to work with. Make the buffer large
++ * enough to make use of the whole extent.
+ */
+- ea_buf->xattr = kmalloc(size, GFP_KERNEL);
++ ea_buf->max_size = (size + sb->s_blocksize - 1) &
++ ~(sb->s_blocksize - 1);
++
++ ea_buf->xattr = kmalloc(ea_buf->max_size, GFP_KERNEL);
+ if (ea_buf->xattr == NULL)
+ return -ENOMEM;
+
+ ea_buf->flag = EA_MALLOC;
+- ea_buf->max_size = (size + sb->s_blocksize - 1) &
+- ~(sb->s_blocksize - 1);
+
+ if (ea_size == 0)
+ return 0;
+++ /dev/null
-From 23fcb3340d033d9f081e21e6c12c2db7eaa541d3 Mon Sep 17 00:00:00 2001
-From: Dave Chinner <dchinner@redhat.com>
-Date: Thu, 21 Jun 2018 23:25:57 -0700
-Subject: xfs: More robust inode extent count validation
-
-From: Dave Chinner <dchinner@redhat.com>
-
-commit 23fcb3340d033d9f081e21e6c12c2db7eaa541d3 upstream.
-
-When the inode is in extent format, it can't have more extents that
-fit in the inode fork. We don't currenty check this, and so this
-corruption goes unnoticed by the inode verifiers. This can lead to
-crashes operating on invalid in-memory structures.
-
-Attempts to access such a inode will now error out in the verifier
-rather than allowing modification operations to proceed.
-
-Reported-by: Wen Xu <wen.xu@gatech.edu>
-Signed-off-by: Dave Chinner <dchinner@redhat.com>
-Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
-[darrick: fix a typedef, add some braces and breaks to shut up compiler warnings]
-Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-Cc: Yuki Machida <machida.yuki@jp.fujitsu.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- fs/xfs/libxfs/xfs_format.h | 3 +
- fs/xfs/libxfs/xfs_inode_buf.c | 76 +++++++++++++++++++++++++-----------------
- 2 files changed, 50 insertions(+), 29 deletions(-)
-
---- a/fs/xfs/libxfs/xfs_format.h
-+++ b/fs/xfs/libxfs/xfs_format.h
-@@ -971,6 +971,9 @@ typedef enum xfs_dinode_fmt {
- XFS_DFORK_DSIZE(dip, mp) : \
- XFS_DFORK_ASIZE(dip, mp))
-
-+#define XFS_DFORK_MAXEXT(dip, mp, w) \
-+ (XFS_DFORK_SIZE(dip, mp, w) / sizeof(struct xfs_bmbt_rec))
-+
- /*
- * Return pointers to the data or attribute forks.
- */
---- a/fs/xfs/libxfs/xfs_inode_buf.c
-+++ b/fs/xfs/libxfs/xfs_inode_buf.c
-@@ -391,6 +391,47 @@ xfs_log_dinode_to_disk(
- }
- }
-
-+static xfs_failaddr_t
-+xfs_dinode_verify_fork(
-+ struct xfs_dinode *dip,
-+ struct xfs_mount *mp,
-+ int whichfork)
-+{
-+ uint32_t di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
-+
-+ switch (XFS_DFORK_FORMAT(dip, whichfork)) {
-+ case XFS_DINODE_FMT_LOCAL:
-+ /*
-+ * no local regular files yet
-+ */
-+ if (whichfork == XFS_DATA_FORK) {
-+ if (S_ISREG(be16_to_cpu(dip->di_mode)))
-+ return __this_address;
-+ if (be64_to_cpu(dip->di_size) >
-+ XFS_DFORK_SIZE(dip, mp, whichfork))
-+ return __this_address;
-+ }
-+ if (di_nextents)
-+ return __this_address;
-+ break;
-+ case XFS_DINODE_FMT_EXTENTS:
-+ if (di_nextents > XFS_DFORK_MAXEXT(dip, mp, whichfork))
-+ return __this_address;
-+ break;
-+ case XFS_DINODE_FMT_BTREE:
-+ if (whichfork == XFS_ATTR_FORK) {
-+ if (di_nextents > MAXAEXTNUM)
-+ return __this_address;
-+ } else if (di_nextents > MAXEXTNUM) {
-+ return __this_address;
-+ }
-+ break;
-+ default:
-+ return __this_address;
-+ }
-+ return NULL;
-+}
-+
- xfs_failaddr_t
- xfs_dinode_verify(
- struct xfs_mount *mp,
-@@ -457,24 +498,9 @@ xfs_dinode_verify(
- case S_IFREG:
- case S_IFLNK:
- case S_IFDIR:
-- switch (dip->di_format) {
-- case XFS_DINODE_FMT_LOCAL:
-- /*
-- * no local regular files yet
-- */
-- if (S_ISREG(mode))
-- return __this_address;
-- if (di_size > XFS_DFORK_DSIZE(dip, mp))
-- return __this_address;
-- if (dip->di_nextents)
-- return __this_address;
-- /* fall through */
-- case XFS_DINODE_FMT_EXTENTS:
-- case XFS_DINODE_FMT_BTREE:
-- break;
-- default:
-- return __this_address;
-- }
-+ fa = xfs_dinode_verify_fork(dip, mp, XFS_DATA_FORK);
-+ if (fa)
-+ return fa;
- break;
- case 0:
- /* Uninitialized inode ok. */
-@@ -484,17 +510,9 @@ xfs_dinode_verify(
- }
-
- if (XFS_DFORK_Q(dip)) {
-- switch (dip->di_aformat) {
-- case XFS_DINODE_FMT_LOCAL:
-- if (dip->di_anextents)
-- return __this_address;
-- /* fall through */
-- case XFS_DINODE_FMT_EXTENTS:
-- case XFS_DINODE_FMT_BTREE:
-- break;
-- default:
-- return __this_address;
-- }
-+ fa = xfs_dinode_verify_fork(dip, mp, XFS_ATTR_FORK);
-+ if (fa)
-+ return fa;
- } else {
- /*
- * If there is no fork offset, this may be a freshly-made inode