From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-f195.google.com ([209.85.214.195]:47071 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726399AbeJFH4n (ORCPT ); Sat, 6 Oct 2018 03:56:43 -0400 Received: by mail-pl1-f195.google.com with SMTP id v5-v6so7532450plz.13 for ; Fri, 05 Oct 2018 17:55:31 -0700 (PDT) From: Daniel Rosenberg To: stable@vger.kernel.org Cc: Theodore Ts'o , Daniel Rosenberg Subject: [PATCH 2/2] ext4: always verify the magic number in xattr blocks Date: Fri, 5 Oct 2018 17:51:29 -0700 Message-Id: <20181006005129.166109-3-drosen@google.com> In-Reply-To: <20181006005129.166109-1-drosen@google.com> References: <20181006005129.166109-1-drosen@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: From: Theodore Ts'o commit 513f86d73855ce556ea9522b6bfd79f87356dc3a upstream. If there an inode points to a block which is also some other type of metadata block (such as a block allocation bitmap), the buffer_verified flag can be set when it was validated as that other metadata block type; however, it would make a really terrible external attribute block. The reason why we use the verified flag is to avoid constantly reverifying the block. However, it doesn't take much overhead to make sure the magic number of the xattr block is correct, and this will avoid potential crashes. This addresses CVE-2018-10879. https://bugzilla.kernel.org/show_bug.cgi?id=200001 Signed-off-by: Theodore Ts'o Reviewed-by: Andreas Dilger [Backported to 4.4: adjust context] Signed-off-by: Daniel Rosenberg --- fs/ext4/xattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b1a2d1cd23e55..ba2a12b34ff16 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -220,12 +220,12 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) { int error; - if (buffer_verified(bh)) - return 0; - if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || BHDR(bh)->h_blocks != cpu_to_le32(1)) return -EFSCORRUPTED; + if (buffer_verified(bh)) + return 0; + if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh))) return -EFSBADCRC; error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size, -- 2.19.0.605.g01d371f741-goog