mbox series

[SRU,B/X,CVE-2018-10322,v2,0/4] XFS xfs_dinode_verify() DOS

Message ID 20200902194139.67480-1-william.gray@canonical.com
Headers show
Series XFS xfs_dinode_verify() DOS | expand

Message

William Breathitt Gray Sept. 2, 2020, 7:41 p.m. UTC
SRU Justification
=================

[Impact]

The xfs_dinode_verify function in fs/xfs/libxfs/xfs_inode_buf.c in the
Linux kernel through 4.16.3 allows local users to cause a denial of
service (xfs_ilock_attr_map_shared invalid pointer dereference) via a
crafted xfs image.

[Test Case]

The upstream bugzilla page provides a test case to check if a kernel is
affected by this issue:
<https://bugzilla.kernel.org/show_bug.cgi?id=199377>

- Overview
Invalid pointer dereference in xfs_ilock_attr_map_shared() when mounting
and operating a crafted xfs image

- Reproduce
# mkdir mnt
# mount -t xfs 120.img mnt
# gcc -o poc poc.c
# ./poc ./mnt

- Reason
static int
xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
		struct inode *inode, const char *name, void *value, size_t size)
{
	int xflags = handler->flags;
	struct xfs_inode *ip = XFS_I(inode);
	int error, asize = size;

	/* Convert Linux syscall to XFS internal ATTR flags */
	if (!size) {
		xflags |= ATTR_KERNOVAL;
		value = NULL;
	}

	error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags);
	if (error)
		return error;
	return asize;
}

ip is invalid (0x8) returned from XFS_I.

[Regression Potential]

Regression potential is low; the changes necessary to backport consist of simple
context adjustments from the upstream patches.

[Miscellaneous]

Backports of commit 420fbeb4 and commit 3c6f46ea for Xenial are provided in
order to simplify the context adjustments of the subsequent patches.

Amir Goldstein (1):
  xfs: sanity check directory inode di_size

Darrick J. Wong (2):
  libxfs: synchronize dinode_verify with userspace
  xfs: move inode fork verifiers to xfs_dinode_verify

Eric Sandeen (1):
  xfs: enhance dinode verifier

 fs/xfs/libxfs/xfs_dir2.c       |   3 +-
 fs/xfs/libxfs/xfs_inode_buf.c  | 101 +++++++++++++++++++++++++++++++--
 fs/xfs/libxfs/xfs_inode_fork.c |  67 ----------------------
 3 files changed, 97 insertions(+), 74 deletions(-)

Comments

Stefan Bader Sept. 3, 2020, 9 a.m. UTC | #1
On 02.09.20 21:41, William Breathitt Gray wrote:
> SRU Justification
> =================
> 
> [Impact]
> 
> The xfs_dinode_verify function in fs/xfs/libxfs/xfs_inode_buf.c in the
> Linux kernel through 4.16.3 allows local users to cause a denial of
> service (xfs_ilock_attr_map_shared invalid pointer dereference) via a
> crafted xfs image.
> 
> [Test Case]
> 
> The upstream bugzilla page provides a test case to check if a kernel is
> affected by this issue:
> <https://bugzilla.kernel.org/show_bug.cgi?id=199377>
> 
> - Overview
> Invalid pointer dereference in xfs_ilock_attr_map_shared() when mounting
> and operating a crafted xfs image
> 
> - Reproduce
> # mkdir mnt
> # mount -t xfs 120.img mnt
> # gcc -o poc poc.c
> # ./poc ./mnt
> 
> - Reason
> static int
> xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
> 		struct inode *inode, const char *name, void *value, size_t size)
> {
> 	int xflags = handler->flags;
> 	struct xfs_inode *ip = XFS_I(inode);
> 	int error, asize = size;
> 
> 	/* Convert Linux syscall to XFS internal ATTR flags */
> 	if (!size) {
> 		xflags |= ATTR_KERNOVAL;
> 		value = NULL;
> 	}
> 
> 	error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags);
> 	if (error)
> 		return error;
> 	return asize;
> }
> 
> ip is invalid (0x8) returned from XFS_I.
> 
> [Regression Potential]
> 
> Regression potential is low; the changes necessary to backport consist of simple
> context adjustments from the upstream patches.
> 
> [Miscellaneous]
> 
> Backports of commit 420fbeb4 and commit 3c6f46ea for Xenial are provided in
> order to simplify the context adjustments of the subsequent patches.
> 
> Amir Goldstein (1):
>   xfs: sanity check directory inode di_size
> 
> Darrick J. Wong (2):
>   libxfs: synchronize dinode_verify with userspace
>   xfs: move inode fork verifiers to xfs_dinode_verify
> 
> Eric Sandeen (1):
>   xfs: enhance dinode verifier
> 
>  fs/xfs/libxfs/xfs_dir2.c       |   3 +-
>  fs/xfs/libxfs/xfs_inode_buf.c  | 101 +++++++++++++++++++++++++++++++--
>  fs/xfs/libxfs/xfs_inode_fork.c |  67 ----------------------
>  3 files changed, 97 insertions(+), 74 deletions(-)
> 
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Thadeu Lima de Souza Cascardo Sept. 8, 2020, 10:16 p.m. UTC | #2
Changes limited to XFS, tested to fix the issue, very close backport.

Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Khalid Elmously Sept. 16, 2020, 5:01 a.m. UTC | #3
On 2020-09-02 15:41:34 , William Breathitt Gray wrote:
> SRU Justification
> =================
> 
> [Impact]
> 
> The xfs_dinode_verify function in fs/xfs/libxfs/xfs_inode_buf.c in the
> Linux kernel through 4.16.3 allows local users to cause a denial of
> service (xfs_ilock_attr_map_shared invalid pointer dereference) via a
> crafted xfs image.
> 
> [Test Case]
> 
> The upstream bugzilla page provides a test case to check if a kernel is
> affected by this issue:
> <https://bugzilla.kernel.org/show_bug.cgi?id=199377>
> 
> - Overview
> Invalid pointer dereference in xfs_ilock_attr_map_shared() when mounting
> and operating a crafted xfs image
> 
> - Reproduce
> # mkdir mnt
> # mount -t xfs 120.img mnt
> # gcc -o poc poc.c
> # ./poc ./mnt
> 
> - Reason
> static int
> xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
> 		struct inode *inode, const char *name, void *value, size_t size)
> {
> 	int xflags = handler->flags;
> 	struct xfs_inode *ip = XFS_I(inode);
> 	int error, asize = size;
> 
> 	/* Convert Linux syscall to XFS internal ATTR flags */
> 	if (!size) {
> 		xflags |= ATTR_KERNOVAL;
> 		value = NULL;
> 	}
> 
> 	error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags);
> 	if (error)
> 		return error;
> 	return asize;
> }
> 
> ip is invalid (0x8) returned from XFS_I.
> 
> [Regression Potential]
> 
> Regression potential is low; the changes necessary to backport consist of simple
> context adjustments from the upstream patches.
> 
> [Miscellaneous]
> 
> Backports of commit 420fbeb4 and commit 3c6f46ea for Xenial are provided in
> order to simplify the context adjustments of the subsequent patches.
> 
> Amir Goldstein (1):
>   xfs: sanity check directory inode di_size
> 
> Darrick J. Wong (2):
>   libxfs: synchronize dinode_verify with userspace
>   xfs: move inode fork verifiers to xfs_dinode_verify
> 
> Eric Sandeen (1):
>   xfs: enhance dinode verifier
> 
>  fs/xfs/libxfs/xfs_dir2.c       |   3 +-
>  fs/xfs/libxfs/xfs_inode_buf.c  | 101 +++++++++++++++++++++++++++++++--
>  fs/xfs/libxfs/xfs_inode_fork.c |  67 ----------------------
>  3 files changed, 97 insertions(+), 74 deletions(-)
> 
> -- 
> 2.25.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Khalid Elmously Sept. 16, 2020, 5:14 a.m. UTC | #4
On 2020-09-02 15:41:34 , William Breathitt Gray wrote:
> SRU Justification
> =================
> 
> [Impact]
> 
> The xfs_dinode_verify function in fs/xfs/libxfs/xfs_inode_buf.c in the
> Linux kernel through 4.16.3 allows local users to cause a denial of
> service (xfs_ilock_attr_map_shared invalid pointer dereference) via a
> crafted xfs image.
> 
> [Test Case]
> 
> The upstream bugzilla page provides a test case to check if a kernel is
> affected by this issue:
> <https://bugzilla.kernel.org/show_bug.cgi?id=199377>
> 
> - Overview
> Invalid pointer dereference in xfs_ilock_attr_map_shared() when mounting
> and operating a crafted xfs image
> 
> - Reproduce
> # mkdir mnt
> # mount -t xfs 120.img mnt
> # gcc -o poc poc.c
> # ./poc ./mnt
> 
> - Reason
> static int
> xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
> 		struct inode *inode, const char *name, void *value, size_t size)
> {
> 	int xflags = handler->flags;
> 	struct xfs_inode *ip = XFS_I(inode);
> 	int error, asize = size;
> 
> 	/* Convert Linux syscall to XFS internal ATTR flags */
> 	if (!size) {
> 		xflags |= ATTR_KERNOVAL;
> 		value = NULL;
> 	}
> 
> 	error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags);
> 	if (error)
> 		return error;
> 	return asize;
> }
> 
> ip is invalid (0x8) returned from XFS_I.
> 
> [Regression Potential]
> 
> Regression potential is low; the changes necessary to backport consist of simple
> context adjustments from the upstream patches.
> 
> [Miscellaneous]
> 
> Backports of commit 420fbeb4 and commit 3c6f46ea for Xenial are provided in
> order to simplify the context adjustments of the subsequent patches.
> 
> Amir Goldstein (1):
>   xfs: sanity check directory inode di_size
> 
> Darrick J. Wong (2):
>   libxfs: synchronize dinode_verify with userspace
>   xfs: move inode fork verifiers to xfs_dinode_verify
> 
> Eric Sandeen (1):
>   xfs: enhance dinode verifier
> 
>  fs/xfs/libxfs/xfs_dir2.c       |   3 +-
>  fs/xfs/libxfs/xfs_inode_buf.c  | 101 +++++++++++++++++++++++++++++++--
>  fs/xfs/libxfs/xfs_inode_fork.c |  67 ----------------------
>  3 files changed, 97 insertions(+), 74 deletions(-)
> 
> -- 
> 2.25.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team