From patchwork Mon Dec 16 15:05:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allan McRae X-Patchwork-Id: 1409 Return-Path: Delivered-To: patchwork@archlinux.org Received: from apollo.archlinux.org (localhost [127.0.0.1]) by apollo.archlinux.org (Postfix) with ESMTP id AAC1E15AE7668 for ; Mon, 16 Dec 2019 15:05:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.3 (2019-12-06) on apollo.archlinux.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1, MAILING_LIST_MULTI=-1,RCVD_IN_DNSWL_MED=-2.3,SPF_HELO_NONE=0.001, T_DMARC_POLICY_NONE=0.01 autolearn=ham autolearn_force=no version=3.4.3 X-Spam-BL-Results: [127.0.9.2] Received: from orion.archlinux.org (orion.archlinux.org [88.198.91.70]) by apollo.archlinux.org (Postfix) with ESMTPS for ; Mon, 16 Dec 2019 15:05:42 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id A8E121745AF387; Mon, 16 Dec 2019 15:05:29 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [IPv6:2a01:4f8:160:3033::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits)) (No client certificate requested) (Authenticated sender: luna) by orion.archlinux.org (Postfix) with ESMTPSA id ABC9F1745AF371; Mon, 16 Dec 2019 15:05:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=archlinux.org; s=orion; t=1576508725; bh=PfqYQXg+0bY/6rUAI/4NoTNIZ+aCT6dHAYuqmIAehHE=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Reply-To; b=S+Rm70+aWlLMYtrX2ZTJijRNf/qh93a/7rrajNb5TJNl5kvpI1WZzyFGFcIpXAqeZ T/3kVmdhMtV+L4tcENd7iC34hSLsJOhBy4TPvs7FU8+bdxCuVsk0o0rVnKGQvTqkaU isr37dyKPtXlHABOvgb7JCo0gYFJUwPGYY0Yrm+J2BQDW+hkAIupJozvlGV3SyPXxh ynxix/zMXvbFdFjrhNLAkER4eZQhnq7wxn8EswNh5PEEy5MZ84Syf1Ua2JDU1ajunQ JNe6bXEzU9jGhYitd1XeRYPXn9wkZ5Pm2crM0QAwmWVahZ5G5+FDryA8+0eaT9Ytgr w+yHCITH8qM+YB+6R/MysKjC1jfqm+VA1n/8yaaRsq3Z1DlvGDJJj6GESM1bIZcrPD tDKNmI7RExxp+nHpO4sjcSwK7KB0KVnF8H0W5UNO62RiT+7jMq2I3FjyHSlEm2rtKw ++LvN5h8PRov9wsjyAJsmXpvBf8kXokB5x8QGwpeEYLctBHECYj/mjV5RyUdrdkQni t00edd2X95RZgPte2gRdxR3Hxwo6E7+5AtwYbt4NeipYXqtmnpOpFhnqHyKkJsAKHL iv/p9D6KDeMxLU/OcO8rLCsNZqlM6LvH6HipRoiwqbtSuw3EdsFE6bD0FaOjpuJXOy By6O215I8EhLg9+YLbbZx10M= Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 8537B2B7AD; Mon, 16 Dec 2019 15:05:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=archlinux.org; s=luna2; t=1576508725; bh=PfqYQXg+0bY/6rUAI/4NoTNIZ+aCT6dHAYuqmIAehHE=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: Reply-To; b=cltdd6udicAZ/d0ZuCPh3gqkPSEmkcZ+wWfPr3v96WlV7X3w6fMIDETzxwh9+Ggo1 uwdhPyvKZtUEflqtVKxFurua7vdvpqMoYeP0CCDieSooHEG0rXlFnwzfy0C1d+SmSF vuBunupqvO1+q4o6yVIvfid83hpOZOSoiHTBOxjRiff90QoINwL09U7MbLK40CfTvK F2bppsuCN/lTkdelnJJiI2Pk3rqQGzROLSydITx1s/LiJ/vjJ7SGeboU82HPoopdca fQnLrj6MlwFqP+g1x2wXhSQMj2wn7BX7pD5bkJomWEoszF+CV9uJNA0xqh6fHf4SmM X2qTsQ27KYYoWZ3W4dqP33doycgnqcE3zNwURt5FAAG3NVsfBAXjaome6P8OVafv/y ul8FxBCfeW06hSk0F3OSuBLVAifZ94wZyOHPLEwTmv79zaouAlX6+xfTRqXeJ7pVmu hWqlmaFHC7HLxZCWePZDYHkA0Q6AMWd/hzDdFrcnT/LNnRCz/D8srbz32VZIsYAlh2 Uew0xfug+zgT3CvIg8DiiRScejGarIKX7yDDN4xzfiTdSBlXPiflcQOGVkg+9Il33t BOrJdP7rHoBQYKOI1vrjcvvsI6puRulmFak262jDq6T/dErvobqBB0e2TjZBT2rTwb MOfCnSo8+an5xdP4CHgb7VzM= Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 47FE62B794 for ; Mon, 16 Dec 2019 15:05:23 +0000 (UTC) Received: from orion.archlinux.org (orion.archlinux.org [IPv6:2a01:4f8:160:6087::1]) by luna.archlinux.org (Postfix) with ESMTPS for ; Mon, 16 Dec 2019 15:05:23 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id 7BD6B1745AF362 for ; Mon, 16 Dec 2019 15:05:18 +0000 (UTC) Received: from kamala.localdomain (unknown [122.148.55.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: allan) by orion.archlinux.org (Postfix) with ESMTPSA id 081D01745AF35E for ; Mon, 16 Dec 2019 15:05:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=archlinux.org; s=orion; t=1576508718; bh=PfqYQXg+0bY/6rUAI/4NoTNIZ+aCT6dHAYuqmIAehHE=; h=From:To:Subject:Date:In-Reply-To:References; b=GnuBsBDqD2d5WlHtXvfJ+W0jJs/ndDUIIVah/7AwIckC4EYeWqwj4BpLDTlSjGudX vW2r2AulwoFYVn01y/t1MBGxs39QbpasdnbLdqE9cDdxRmkWBi4agAGWHO931i7Ve8 ilZvBlehdgcfieERgco4o4YsCMtxvforFnkKMF37IOvyqB11GREN7k/sJcShqB+JJW 4O30oUSBXVzjdIOQ69ehDd26qDIEI06pssjt8zL2+wbNMlmdW7azM7wHOxxC6aiNkn jKISoNtqnAWSxS/eUUdyQgBJCF9W0oC4PPETphCWip28HJEKTYDahUZIW0aU07wrfo iTdW+8VLFYFBpH5r6I3Z3pPl+nFIwa/5oWJtr7YRfEoOm2C8ieWxA6uuTSeIIIfy/n 0hH8n8ZepllseDcK9LoAl6PG5yK1P8XG1bBS9yteRrl7fklO/oxrFEx3n5H5VtnOeH uDKff8aJmDXzgutSkQVupAWCluCOnCKHIhDR31nYo0L7tweo7QkXslBc/NqeIo35d3 C6eS9fs24Wcq++zN6jzzZy7d3rlJTcCUH6xDM26xfZzmPs9Ob7VFwsvxgBDlGPGBNL LTxr4K/TEsGhPHQs5orBc5AV2CahivA1iY2e3MHZsUzsOuViLXWAFtsIcSeaVdPenI zKGqDOuyUCs97Lt29xz1AdxA= From: Allan McRae To: pacman-dev@archlinux.org Date: Tue, 17 Dec 2019 01:05:00 +1000 Message-Id: <20191216150500.213552-2-allan@archlinux.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191216150500.213552-1-allan@archlinux.org> References: <20191216150500.213552-1-allan@archlinux.org> MIME-Version: 1.0 Subject: [pacman-dev] [PATCH 2/2] Backup old database before updating and restore on failure X-BeenThere: pacman-dev@archlinux.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion list for pacman development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Discussion list for pacman development Errors-To: pacman-dev-bounces@archlinux.org Sender: "pacman-dev" If alpm_db_update() fails due to an invalid signature, then the system is left with an unusable repo database. Instead, backup the currently working database before performing the update, and restore on error. Note that the calls rename and unlink are not checked for errors. If these fail, there is nothing to be done anyway. It also allows for less complex flow, as these function fail gracefully when passed NULL arguments. Signed-off-by: Allan McRae --- That is a lot of teduim for adding ".bak" to the end of a string... I'd appreciate more eyes on these changes. lib/libalpm/be_sync.c | 58 ++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 5502d92d..ae46c120 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -136,6 +136,7 @@ valid: return 0; } + /** Update a package database * * An update of the package database \a db will be attempted. Unless @@ -173,14 +174,15 @@ valid: */ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) { - char *syncpath; - const char *dbext; + char *syncpath, *dbsig = NULL, *dbfilebak = NULL, *dbsigbak = NULL; + const char *dbext, *dbfile; alpm_list_t *i; int updated = 0; int ret = -1; mode_t oldmask; alpm_handle_t *handle; int siglevel; + size_t len; /* Sanity checks */ ASSERT(db != NULL, return -1); @@ -217,10 +219,39 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) dbext = handle->dbext; + /* create backup of current database version */ + dbfile = _alpm_db_path(db); + len = strlen(dbfile) + 5; + MALLOC(dbfilebak, len, + { + handle->pm_errno = ALPM_ERR_MEMORY; + ret = -1; + goto cleanup; + } + ); + snprintf(dbfilebak, len, "%s.bak", dbfile); + + + dbsig = _alpm_sigpath(db->handle, dbfile); + len = strlen(dbsig) + 5; + MALLOC(dbsigbak, len, + { + handle->pm_errno = ALPM_ERR_MEMORY; + ret = -1; + goto cleanup; + } + ); + snprintf(dbsigbak, len, "%s.bak", dbsig); + + /* remove any old backup files to prevent potential sig mismatch */ + unlink(dbfilebak); + unlink(dbsigbak); + _alpm_copyfile(dbfile, dbfilebak); + _alpm_copyfile(dbsig, dbsigbak); + for(i = db->servers; i; i = i->next) { const char *server = i->data, *final_db_url = NULL; struct dload_payload payload; - size_t len; int sig_ret = 0; memset(&payload, 0, sizeof(struct dload_payload)); @@ -247,17 +278,6 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) updated = (updated || ret == 0); if(ret != -1 && updated && (siglevel & ALPM_SIG_DATABASE)) { - /* an existing sig file is no good at this point */ - char *sigpath = _alpm_sigpath(handle, _alpm_db_path(db)); - if(!sigpath) { - /* pm_errno should be set */ - ret = -1; - goto cleanup; - } - unlink(sigpath); - free(sigpath); - - /* check if the final URL from internal downloader looks reasonable */ if(final_db_url != NULL) { if(strlen(final_db_url) < 3 @@ -327,13 +347,23 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) cleanup: if(ret == -1) { + rename(dbfilebak, dbfile); + rename(dbsigbak, dbsig); + /* pm_errno was set by the download code */ _alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerror(handle->pm_errno)); } else { + unlink(dbfilebak); + unlink(dbsigbak); + handle->pm_errno = ALPM_ERR_OK; } + free(dbfilebak); + free(dbsig); + free(dbsigbak); + _alpm_handle_unlock(handle); free(syncpath); umask(oldmask);