From patchwork Tue Sep 1 16:57:09 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: 1355274 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 4BgtXk43JmzB3ww; Wed, 2 Sep 2020 02:57:25 +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 1kD9av-000482-LI; Tue, 01 Sep 2020 16:57:17 +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 1kD9at-00047S-Tb for kernel-team@lists.ubuntu.com; Tue, 01 Sep 2020 16:57:15 +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 1kD9at-0004LP-JR for kernel-team@lists.ubuntu.com; Tue, 01 Sep 2020 16:57:15 +0000 Received: by mail-qv1-f69.google.com with SMTP id e12so1447600qvy.13 for ; Tue, 01 Sep 2020 09:57:15 -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=k/089RtIoJ2kNNaIJP8PonxZrjQOO4HPrdRcyvYzNVk=; b=TbwbUVINAis1af1r1hgoeKTWgUk9zZpiVGxizjpQa6FPt0k5TN9ZULBfDhGq2mesg5 nDhzZVB2wgdymj7fPdb5+BXzElk7NSrXWoPo8M63WXFHHhS5xxdm37/7k6TBJp/Jj4KJ 2w4AHnwoEAwo4as1FKqYBn/kjvJu3Ag8K16PEluEjqJuPWOY16wxZ1XDArNQzzzmU8iw RqFgzsO9V/JD8r88RWvULM/emPFUl4BcFzDrDukDq6PrrlBLHZIvkGkClYrMW4jqoh0s NmFOe99H3dL095xl9y3e4tEzWxUacfWtd/hG1Q3PpvlV8zbpc5tmIITmgdMq9XNfLm/h CnQw== X-Gm-Message-State: AOAM533yrbQlwSCX7htbBEhkkxLGV4I8T57RWN+eXeuUpUdJatoJKydw i5RmluDwNtLiUa8DY/PPVPwbwQQkmPEr6sUZmETGOWPDyzl+QshE9ovMtCb9srDzeTxxMth1QO+ 5x029Lmtj8PYyeOHwirSEuV8IrlIofGk/pOQ2kR5iqA== X-Received: by 2002:a05:620a:141a:: with SMTP id d26mr2784387qkj.217.1598979434398; Tue, 01 Sep 2020 09:57:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyBMLw0rVy9b6qr24utZE4mV65FBzwY/nNBR0uITP1KiqtT67+urUGNYBBo/QtyKBGybCTwnA== X-Received: by 2002:a05:620a:141a:: with SMTP id d26mr2784359qkj.217.1598979434113; Tue, 01 Sep 2020 09:57:14 -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.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Sep 2020 09:57:13 -0700 (PDT) From: William Breathitt Gray To: kernel-team@lists.ubuntu.com Subject: [SRU][BIONIC][CVE-2018-10322][PATCH 1/1] xfs: enhance dinode verifier Date: Tue, 1 Sep 2020 12:57:09 -0400 Message-Id: <20200901165710.87830-2-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 | 48 +++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index c79a1616b79d..f1f92d1d39ff 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -160,6 +160,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; @@ -197,8 +207,33 @@ xfs_iformat_fork( xfs_ifork_init_cow(ip); } - 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); @@ -220,6 +255,17 @@ xfs_iformat_fork( break; } + 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); + error = -EFSCORRUPTED; + break; + } + error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); break; case XFS_DINODE_FMT_EXTENTS: