From patchwork Tue Sep 1 16:57:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 1355272 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BgtXh3BpBzB3wv; Wed, 2 Sep 2020 02:57:24 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kD9ax-00048b-QM; Tue, 01 Sep 2020 16:57:19 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kD9av-00047v-DX for kernel-team@lists.ubuntu.com; Tue, 01 Sep 2020 16:57:17 +0000 Received: from mail-qv1-f69.google.com ([209.85.219.69]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kD9av-0004LZ-2v for kernel-team@lists.ubuntu.com; Tue, 01 Sep 2020 16:57:17 +0000 Received: by mail-qv1-f69.google.com with SMTP id a13so1451407qvl.6 for ; Tue, 01 Sep 2020 09:57:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+IGFxD90lErKniR/E3zKnQ2iHrCMI0gxQVJ6LXMkggA=; b=dxPLwCmkSS1WM64YAUGX1kSbHWlVlRGfl7xizuux6BUEv4DA5FhSrl8zFXmmt2UaOv knv4yXZCHGKPS3BZgLnZCkC/QLZU0hjN1tC7IrMVrxuUpYKk+gbD1hKsSVlf4LH+12WL HfQuJHxMN1XEwdanbpfUvaGlA4YJpFfkVzEukl3udXNxB+W5VHeNrTw93nn8bHX0W6E+ Ei3Z4pXTWnT/GYQASiWsoPO6A1HFqlRFcZY7Q8121Dsz7n43/1/pa5x/nxEkuKj3WeDU ra946oXpvZ/he11WhJsJkRldVrUMLZyep91tD1jtfxHxS55VD5s8uMoC/F0RnqXsYQyA spNg== X-Gm-Message-State: AOAM531M/VqhF+iqYf+kl1OBsLt9+HFcgThAJIhvzh6fhDyx7QKypwKi o9ghgormbbs0QfNuV6qwsLQ7pvyS9nNPRiWCzoNU5S16xLumCAoB2yDBmrBBJutmvOvHEGjeA1V 99J++k/FLQZgQ8jFL7BdxmiYUCAVv1jYAIafU47qxHQ== X-Received: by 2002:a37:71c6:: with SMTP id m189mr2906457qkc.327.1598979435900; Tue, 01 Sep 2020 09:57:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzMc5eMI40WSPSMx8iMXPAdxTxs15Nuuar9ZBcDxzxQh64NKhxIdNRPdrFtIKT/I5q2qfy9pg== X-Received: by 2002:a37:71c6:: with SMTP id m189mr2906440qkc.327.1598979435645; Tue, 01 Sep 2020 09:57:15 -0700 (PDT) Received: from localhost.localdomain (072-189-064-225.res.spectrum.com. [72.189.64.225]) by smtp.gmail.com with ESMTPSA id q7sm2131024qkf.35.2020.09.01.09.57.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2020 09:57:14 -0700 (PDT) From: William Breathitt Gray To: kernel-team@lists.ubuntu.com Subject: [SRU][XENIAL][CVE-2018-10322][PATCH 1/1] xfs: enhance dinode verifier Date: Tue, 1 Sep 2020 12:57:10 -0400 Message-Id: <20200901165710.87830-3-william.gray@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200901165710.87830-1-william.gray@canonical.com> References: <20200901165710.87830-1-william.gray@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Eric Sandeen Add several more validations to xfs_dinode_verify: - For LOCAL data fork formats, di_nextents must be 0. - For LOCAL attr fork formats, di_anextents must be 0. - For inodes with no attr fork offset, - format must be XFS_DINODE_FMT_EXTENTS if set at all - di_anextents must be 0. Thanks to dchinner for pointing out a couple related checks I had forgotten to add. Signed-off-by: Eric Sandeen Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199377 Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong CVE-2018-10322 (backported from commit b42db0860e13067fcc7cbfba3966c9e652668bbc) [ vilhelmgray: adapted for affected code in xfs_inode_fork.c ] Signed-off-by: William Breathitt Gray --- fs/xfs/libxfs/xfs_inode_fork.c | 47 +++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0defbd02f62d..6c08fa1785dd 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -165,6 +165,16 @@ xfs_iformat_fork( return -EFSCORRUPTED; } + if (dip->di_nextents) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (di_nextents must be 0 for local inode).", + (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat(9)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return -EFSCORRUPTED; + } + size = (int)di_size; error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size); break; @@ -188,8 +198,33 @@ xfs_iformat_fork( if (error) { return error; } - if (!XFS_DFORK_Q(dip)) + if (!XFS_DFORK_Q(dip)) { + /* + * If there is no fork offset, this may be a freshly-made inode + * in a new disk cluster, in which case di_aformat is zeroed. + * Otherwise, such an inode must be in EXTENTS format; this goes + * for freed inodes as well. + */ + switch (dip->di_aformat) { + case 0: + case XFS_DINODE_FMT_EXTENTS: + break; + default: + XFS_ERROR_REPORT("xfs_iformat(10)", XFS_ERRLEVEL_LOW, ip->i_mount); + return -EFSCORRUPTED; + } + if (dip->di_anextents) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (di_anextents must be 0 for freshly-made inode).", + (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat(11)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return -EFSCORRUPTED; + } + return 0; + } ASSERT(ip->i_afp == NULL); ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); @@ -210,6 +245,16 @@ xfs_iformat_fork( return -EFSCORRUPTED; } + if (dip->di_anextents) { + xfs_warn(ip->i_mount, + "corrupt inode %Lu (di_anextents must be 0 for local inode).", + (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat(12)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return -EFSCORRUPTED; + } + error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); break; case XFS_DINODE_FMT_EXTENTS: