From patchwork Tue Aug 8 12:03:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gilad Ben-Yossef X-Patchwork-Id: 109625 Delivered-To: patch@linaro.org Received: by 10.182.109.195 with SMTP id hu3csp3985304obb; Tue, 8 Aug 2017 05:07:02 -0700 (PDT) X-Received: by 10.99.115.8 with SMTP id o8mr3919277pgc.38.1502194022051; Tue, 08 Aug 2017 05:07:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502194022; cv=none; d=google.com; s=arc-20160816; b=fpf4pcnc2I2/KoESaII92a71WLJHfBnebv6D3mICSq7wsRe8HrZYEc35+I6dDR806R +IAW7U8BAvdmZhYwiVhYeC5kLLSJDHbk3wvCCGs+C5QmTA5jHAXKJCNPvM7gG7PrlAY0 LWZHrufdSR3AIpV66qf22y8J8TV9c3iTz/6VhaPkGxsLcJ7rEtDi3c072MJt3L7tYYD8 CLx6ywrIs4Z3ALHTbqx8EOQJ2KkT6yWkWY8T5U1fCSI/PKTE/DGbiEj18x0dEi+YoE4j CPW1xaX8wugzoiDE9jDIxZkVZ5HYZFRtSPjeXBdAVz3krhYwQUCsdT0Xq05OYf/J/ydb r/Sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=dMPIStMFhs+gwL/2WEhcUWzuItmuYVTSDpTltzsKn18=; b=Si5ilFmT9RLyy3x28VHzc8y7xtLHRTX1dFzlh1RD3J/0X6SPJMtF98Dsjxx1mh2WpI cLeYADbBhAf7qQ+S5+TfFgkXZr6Ly6vooxnetn8WuJ125AV2q37AkYZQWDyNeZ1MkJZa lN+7Qw4rm602L/n6sdC4RrkY4YJI7Dy1Odjy36LOjNr6rxZT87TLvU0w+2DvmHdTTKGE HR4rxMybGp8Ee/dShhpVDevF5rO6vNgjV/F+9mKmNo2vpzrvHFI9loeS6c5p2+Bs/Iq3 Y5ex/BIrxPz8mTUN29VOm6MLEzZ14HivHk+4ULlTdqxj+VCXG84z2Bu2NCdIaNhDS0Kr EM6Q== 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 h69si728443pge.162.2017.08.08.05.07.01; Tue, 08 Aug 2017 05:07:02 -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 S1752744AbdHHMG6 (ORCPT + 25 others); Tue, 8 Aug 2017 08:06:58 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:33836 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752137AbdHHMGy (ORCPT ); Tue, 8 Aug 2017 08:06:54 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CB7271A3B; Tue, 8 Aug 2017 05:06:53 -0700 (PDT) Received: from gby.kfn.arm.com (unknown [10.45.48.154]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 63DD63F577; Tue, 8 Aug 2017 05:06:44 -0700 (PDT) From: Gilad Ben-Yossef To: Herbert Xu , "David S. Miller" , Jonathan Corbet , David Howells , Tom Lendacky , Gary Hook , Boris Brezillon , Arnaud Ebalard , Matthias Brugger , Alasdair Kergon , Mike Snitzer , dm-devel@redhat.com, Shaohua Li , Steve French , "Theodore Y. Ts'o" , Jaegeuk Kim , Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , linux-crypto@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-raid@vger.kernel.org, linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-fscrypt@vger.kernel.org, linux-ima-devel@lists.sourceforge.net, linux-ima-user@lists.sourceforge.net, linux-security-module@vger.kernel.org Cc: Ofir Drang Subject: [PATCH v4 12/19] dm: move dm-verity to generic async completion Date: Tue, 8 Aug 2017 15:03:43 +0300 Message-Id: <1502193834-11289-13-git-send-email-gilad@benyossef.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1502193834-11289-1-git-send-email-gilad@benyossef.com> References: <1502193834-11289-1-git-send-email-gilad@benyossef.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org dm-verity is starting async. crypto ops and waiting for them to complete. Move it over to generic code doing the same. This also fixes a possible data coruption bug created by the use of wait_for_completion_interruptible() without dealing correctly with an interrupt aborting the wait prior to the async op finishing. Signed-off-by: Gilad Ben-Yossef --- drivers/md/dm-verity-target.c | 81 +++++++++++-------------------------------- drivers/md/dm-verity.h | 5 --- 2 files changed, 20 insertions(+), 66 deletions(-) -- 2.1.4 diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 79f18d4..8df08a8 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -92,74 +92,33 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block, return block >> (level * v->hash_per_block_bits); } -/* - * Callback function for asynchrnous crypto API completion notification - */ -static void verity_op_done(struct crypto_async_request *base, int err) -{ - struct verity_result *res = (struct verity_result *)base->data; - - if (err == -EINPROGRESS) - return; - - res->err = err; - complete(&res->completion); -} - -/* - * Wait for async crypto API callback - */ -static inline int verity_complete_op(struct verity_result *res, int ret) -{ - switch (ret) { - case 0: - break; - - case -EINPROGRESS: - case -EBUSY: - ret = wait_for_completion_interruptible(&res->completion); - if (!ret) - ret = res->err; - reinit_completion(&res->completion); - break; - - default: - DMERR("verity_wait_hash: crypto op submission failed: %d", ret); - } - - if (unlikely(ret < 0)) - DMERR("verity_wait_hash: crypto op failed: %d", ret); - - return ret; -} - static int verity_hash_update(struct dm_verity *v, struct ahash_request *req, const u8 *data, size_t len, - struct verity_result *res) + struct crypto_wait *wait) { struct scatterlist sg; sg_init_one(&sg, data, len); ahash_request_set_crypt(req, &sg, NULL, len); - return verity_complete_op(res, crypto_ahash_update(req)); + return crypto_wait_req(crypto_ahash_update(req), wait); } /* * Wrapper for crypto_ahash_init, which handles verity salting. */ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req, - struct verity_result *res) + struct crypto_wait *wait) { int r; ahash_request_set_tfm(req, v->tfm); ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | CRYPTO_TFM_REQ_MAY_BACKLOG, - verity_op_done, (void *)res); - init_completion(&res->completion); + crypto_req_done, (void *)wait); + crypto_init_wait(wait); - r = verity_complete_op(res, crypto_ahash_init(req)); + r = crypto_wait_req(crypto_ahash_init(req), wait); if (unlikely(r < 0)) { DMERR("crypto_ahash_init failed: %d", r); @@ -167,18 +126,18 @@ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req, } if (likely(v->salt_size && (v->version >= 1))) - r = verity_hash_update(v, req, v->salt, v->salt_size, res); + r = verity_hash_update(v, req, v->salt, v->salt_size, wait); return r; } static int verity_hash_final(struct dm_verity *v, struct ahash_request *req, - u8 *digest, struct verity_result *res) + u8 *digest, struct crypto_wait *wait) { int r; if (unlikely(v->salt_size && (!v->version))) { - r = verity_hash_update(v, req, v->salt, v->salt_size, res); + r = verity_hash_update(v, req, v->salt, v->salt_size, wait); if (r < 0) { DMERR("verity_hash_final failed updating salt: %d", r); @@ -187,7 +146,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req, } ahash_request_set_crypt(req, NULL, digest, 0); - r = verity_complete_op(res, crypto_ahash_final(req)); + r = crypto_wait_req(crypto_ahash_final(req), wait); out: return r; } @@ -196,17 +155,17 @@ int verity_hash(struct dm_verity *v, struct ahash_request *req, const u8 *data, size_t len, u8 *digest) { int r; - struct verity_result res; + struct crypto_wait wait; - r = verity_hash_init(v, req, &res); + r = verity_hash_init(v, req, &wait); if (unlikely(r < 0)) goto out; - r = verity_hash_update(v, req, data, len, &res); + r = verity_hash_update(v, req, data, len, &wait); if (unlikely(r < 0)) goto out; - r = verity_hash_final(v, req, digest, &res); + r = verity_hash_final(v, req, digest, &wait); out: return r; @@ -389,7 +348,7 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io, * Calculates the digest for the given bio */ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io, - struct bvec_iter *iter, struct verity_result *res) + struct bvec_iter *iter, struct crypto_wait *wait) { unsigned int todo = 1 << v->data_dev_block_bits; struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); @@ -414,7 +373,7 @@ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io, */ sg_set_page(&sg, bv.bv_page, len, bv.bv_offset); ahash_request_set_crypt(req, &sg, NULL, len); - r = verity_complete_op(res, crypto_ahash_update(req)); + r = crypto_wait_req(crypto_ahash_update(req), wait); if (unlikely(r < 0)) { DMERR("verity_for_io_block crypto op failed: %d", r); @@ -482,7 +441,7 @@ static int verity_verify_io(struct dm_verity_io *io) struct dm_verity *v = io->v; struct bvec_iter start; unsigned b; - struct verity_result res; + struct crypto_wait wait; for (b = 0; b < io->n_blocks; b++) { int r; @@ -507,17 +466,17 @@ static int verity_verify_io(struct dm_verity_io *io) continue; } - r = verity_hash_init(v, req, &res); + r = verity_hash_init(v, req, &wait); if (unlikely(r < 0)) return r; start = io->iter; - r = verity_for_io_block(v, io, &io->iter, &res); + r = verity_for_io_block(v, io, &io->iter, &wait); if (unlikely(r < 0)) return r; r = verity_hash_final(v, req, verity_io_real_digest(v, io), - &res); + &wait); if (unlikely(r < 0)) return r; diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h index a59e0ad..b675bc0 100644 --- a/drivers/md/dm-verity.h +++ b/drivers/md/dm-verity.h @@ -90,11 +90,6 @@ struct dm_verity_io { */ }; -struct verity_result { - struct completion completion; - int err; -}; - static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v, struct dm_verity_io *io) {