Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp1824060imm; Mon, 3 Sep 2018 10:22:36 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYaJjsCZHaC2Agk7NWLoR1SfcyfsZTtP1LKe+cx8uEhGwt6dXJoMhzWBT9cIGEhB3R0ysCo X-Received: by 2002:a17:902:42c3:: with SMTP id h61-v6mr29712972pld.319.1535995356812; Mon, 03 Sep 2018 10:22:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535995356; cv=none; d=google.com; s=arc-20160816; b=yE840lnkn8/FO6uuHnJrlcYaLYIm/01vwgByDvLbc7bDbcHCrLZaCQQV37UP71Q23q iRMvSsqNTQVE+Iupy3IHbbMRW8DYu3RyHIYKx2M+IBhReS1scBMAY+kmSEaf/FDu5RPp +JmL0TemM0RtXmLx1HcieQxTs6D2EQU5aTKCaUJ8jIMK4ZoFGRHiUpK3eIByPUtn9vl9 4aW2mTy3jOPYoMZVkp5d7IJLZn2MwQdgw4cYl+/1FDDWTOI9HXCyD+Gki1Bx8AwPljN+ hvYFIRW7LrAe3XFGsKp9+zSBK6SJQXEd3A4bJ2WYwEK+Ec7OpZs+DlaVqex4FfPO8Noa w9Wg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=qywG7H8en930MsZlAhA9mupRWAviOd/QqQ8qHV/rF6w=; b=MMe0qTuUpVlsS0kW11HiCNTBtTFivEaXlJxDIgH+WEbMU0i/IuojlT8YnFTNDYSf6o 2hT3pbMrsbotZrRw+E/QOSWTgFCue27GCmkkEwV0SIIFwCBaiat6IlHkypNeg0gjcGlt zcEuZd9pS9CksSvGLDJrnpCeTeBunFCW0c7BzKryINzvw0Iu4q1UEUDOsB4AFYb0BoEe k1VEOhBR8x2m7tMtl/xP9aT7We962NViOxOT3h3GPS7CI/zKOoidbaiesn3SUWpoSLYb UCuDuW3CeYz+8cXGR7ky8zBVhS3tNjhkevBDwEvbv0i9NopeiKRyktCkGdoZt9rtR+22 Xxrw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o9-v6si18515076pgf.331.2018.09.03.10.22.22; Mon, 03 Sep 2018 10:22:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730449AbeICVlh (ORCPT + 99 others); Mon, 3 Sep 2018 17:41:37 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:43170 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728430AbeICVkK (ORCPT ); Mon, 3 Sep 2018 17:40:10 -0400 Received: from localhost (ip-213-127-74-90.ip.prioritytelecom.net [213.127.74.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 3DD43D09; Mon, 3 Sep 2018 17:19:04 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Anatoly Trosinenko , Willy Tarreau , Al Viro , Phillip Lougher , Linus Torvalds , Sasha Levin Subject: [PATCH 4.14 072/165] squashfs metadata 2: electric boogaloo Date: Mon, 3 Sep 2018 18:55:58 +0200 Message-Id: <20180903165658.702489657@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165655.003605184@linuxfoundation.org> References: <20180903165655.003605184@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Linus Torvalds [ Upstream commit cdbb65c4c7ead680ebe54f4f0d486e2847a500ea ] Anatoly continues to find issues with fuzzed squashfs images. This time, corrupt, missing, or undersized data for the page filling wasn't checked for, because the squashfs_{copy,read}_cache() functions did the squashfs_copy_data() call without checking the resulting data size. Which could result in the page cache pages being incompletely filled in, and no error indication to the user space reading garbage data. So make a helper function for the "fill in pages" case, because the exact same incomplete sequence existed in two places. [ I should have made a squashfs branch for these things, but I didn't intend to start doing them in the first place. My historical connection through cramfs is why I got into looking at these issues at all, and every time I (continue to) think it's a one-off. Because _this_ time is always the last time. Right? - Linus ] Reported-by: Anatoly Trosinenko Tested-by: Willy Tarreau Cc: Al Viro Cc: Phillip Lougher Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/squashfs/file.c | 25 ++++++++++++++++++------- fs/squashfs/file_direct.c | 8 +------- fs/squashfs/squashfs.h | 1 + 3 files changed, 20 insertions(+), 14 deletions(-) --- a/fs/squashfs/file.c +++ b/fs/squashfs/file.c @@ -374,13 +374,29 @@ static int read_blocklist(struct inode * return squashfs_block_size(size); } +void squashfs_fill_page(struct page *page, struct squashfs_cache_entry *buffer, int offset, int avail) +{ + int copied; + void *pageaddr; + + pageaddr = kmap_atomic(page); + copied = squashfs_copy_data(pageaddr, buffer, offset, avail); + memset(pageaddr + copied, 0, PAGE_SIZE - copied); + kunmap_atomic(pageaddr); + + flush_dcache_page(page); + if (copied == avail) + SetPageUptodate(page); + else + SetPageError(page); +} + /* Copy data into page cache */ void squashfs_copy_cache(struct page *page, struct squashfs_cache_entry *buffer, int bytes, int offset) { struct inode *inode = page->mapping->host; struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; - void *pageaddr; int i, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; int start_index = page->index & ~mask, end_index = start_index | mask; @@ -406,12 +422,7 @@ void squashfs_copy_cache(struct page *pa if (PageUptodate(push_page)) goto skip_page; - pageaddr = kmap_atomic(push_page); - squashfs_copy_data(pageaddr, buffer, offset, avail); - memset(pageaddr + avail, 0, PAGE_SIZE - avail); - kunmap_atomic(pageaddr); - flush_dcache_page(push_page); - SetPageUptodate(push_page); + squashfs_fill_page(push_page, buffer, offset, avail); skip_page: unlock_page(push_page); if (i != page->index) --- a/fs/squashfs/file_direct.c +++ b/fs/squashfs/file_direct.c @@ -144,7 +144,6 @@ static int squashfs_read_cache(struct pa struct squashfs_cache_entry *buffer = squashfs_get_datablock(i->i_sb, block, bsize); int bytes = buffer->length, res = buffer->error, n, offset = 0; - void *pageaddr; if (res) { ERROR("Unable to read page, block %llx, size %x\n", block, @@ -159,12 +158,7 @@ static int squashfs_read_cache(struct pa if (page[n] == NULL) continue; - pageaddr = kmap_atomic(page[n]); - squashfs_copy_data(pageaddr, buffer, offset, avail); - memset(pageaddr + avail, 0, PAGE_SIZE - avail); - kunmap_atomic(pageaddr); - flush_dcache_page(page[n]); - SetPageUptodate(page[n]); + squashfs_fill_page(page[n], buffer, offset, avail); unlock_page(page[n]); if (page[n] != target_page) put_page(page[n]); --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h @@ -67,6 +67,7 @@ extern __le64 *squashfs_read_fragment_in u64, u64, unsigned int); /* file.c */ +void squashfs_fill_page(struct page *, struct squashfs_cache_entry *, int, int); void squashfs_copy_cache(struct page *, struct squashfs_cache_entry *, int, int);