From patchwork Thu Jan 26 01:17:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Sandeen X-Patchwork-Id: 9538279 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4F7D6604A7 for ; Thu, 26 Jan 2017 01:18:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3E64127D4A for ; Thu, 26 Jan 2017 01:18:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 311D927E33; Thu, 26 Jan 2017 01:18:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C509527D4A for ; Thu, 26 Jan 2017 01:18:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752427AbdAZBR6 (ORCPT ); Wed, 25 Jan 2017 20:17:58 -0500 Received: from sandeen.net ([63.231.237.45]:35344 "EHLO sandeen.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752424AbdAZBR6 (ORCPT ); Wed, 25 Jan 2017 20:17:58 -0500 Received: from [10.0.0.4] (liberator [10.0.0.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 984CE2B46; Wed, 25 Jan 2017 19:16:50 -0600 (CST) Subject: [PATCH v10 1/5] xfs_db: sanitize agcount on load To: "Darrick J. Wong" , sandeen@redhat.com References: <148494391629.5256.3328772079712970611.stgit@birch.djwong.org> <148494392247.5256.10692618169002348643.stgit@birch.djwong.org> <20170123213108.GD31202@birch.djwong.org> <6ad3798a-c3f5-fd8f-ab05-62c0f878290c@sandeen.net> <17bbf8d4-39f7-a542-6c9d-3cd96e865ddf@sandeen.net> <886473a5-c0ff-a5b7-38bc-13d4d5d13c3c@sandeen.net> Cc: linux-xfs@vger.kernel.org From: Eric Sandeen Message-ID: Date: Wed, 25 Jan 2017 19:17:56 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: <886473a5-c0ff-a5b7-38bc-13d4d5d13c3c@sandeen.net> Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Before we get into libxfs_initialize_perag and try to blindly allocate a perag struct for every (possibly corrupted number of) AGs, see if we can read the last one. If not, assume it's corrupt, and load only the first AG. Do this only for an arbitrarily high-ish agcount, so that normal-ish geometry on a possibly truncated file or device will still do its best to make all readable AGs available. Set xfs_db's exitcode to 1 if this happens. Also teach metadump to detect this and exit appropriately if truncated, as it resets exitcode to 0 for its own purposes internally. Signed-off-by: Eric Sandeen Reviewed-by: Darrick J. Wong --- v1->v6: Tale of woe. v7: blow it all up v8: use bare libxfs_readbuf so verifiers don't matter, "ours goes to 1 million!" v9: Fix printf format, exit metadump with error if things look wonky. v10: set exitcode to 1 in init(). -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/db/init.c b/db/init.c index ec1e274..59fc3e0 100644 --- a/db/init.c +++ b/db/init.c @@ -58,6 +58,7 @@ init( { struct xfs_sb *sbp; struct xfs_buf *bp; + unsigned int agcount; int c; setlocale(LC_ALL, ""); @@ -148,6 +149,7 @@ init( } } + agcount = sbp->sb_agcount; mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, LIBXFS_MOUNT_DEBUGGER); if (!mp) { @@ -159,6 +161,10 @@ init( mp->m_log = &xlog; blkbb = 1 << mp->m_blkbb_log; + /* Did we limit a broken agcount in libxfs_mount? */ + if (sbp->sb_agcount != agcount) + exitcode = 1; + /* * xfs_check needs corrected incore superblock values */ diff --git a/db/metadump.c b/db/metadump.c index 1ba6b38..38519f1 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -2760,6 +2760,16 @@ metadump_f( return 0; } + /* + * on load, we sanity-checked agcount and possibly set to 1 + * if it was corrupted and large. + */ + if (mp->m_sb.sb_agcount == 1 && + XFS_MAX_DBLOCKS(&mp->m_sb) < mp->m_sb.sb_dblocks) { + print_warning("truncated agcount, giving up"); + return 0; + } + while ((c = getopt(argc, argv, "aegm:ow")) != EOF) { switch (c) { case 'a': diff --git a/libxfs/init.c b/libxfs/init.c index a08575a..85e0d15 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -817,6 +817,29 @@ libxfs_mount( return NULL; } + /* + * libxfs_initialize_perag will allocate a perag structure for each ag. + * If agcount is corrupted and insanely high, this will OOM the box. + * If the agount seems (arbitrarily) high, try to read what would be + * the last AG, and if that fails for a relatively high agcount, just + * read the first one and let the user know to check the geometry. + */ + if (sbp->sb_agcount > 1000000) { + bp = libxfs_readbuf(mp->m_dev, + XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1, + !(flags & LIBXFS_MOUNT_DEBUGGER), NULL); + if (bp->b_error) { + fprintf(stderr, _("%s: read of AG %u failed\n"), + progname, sbp->sb_agcount); + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; + fprintf(stderr, _("%s: limiting reads to AG 0\n"), + progname); + sbp->sb_agcount = 1; + } + libxfs_putbuf(bp); + } + error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); if (error) { fprintf(stderr, _("%s: perag init failed\n"),