Received: by 10.223.185.116 with SMTP id b49csp6257784wrg; Thu, 8 Mar 2018 04:36:20 -0800 (PST) X-Google-Smtp-Source: AG47ELspTICgYeO1eTckiQT93mMiTpyc7zq+zlNmltaCRMFsevYmmHkSoFLB+GGHOOMIVBecBm2C X-Received: by 10.98.138.66 with SMTP id y63mr26168799pfd.12.1520512580300; Thu, 08 Mar 2018 04:36:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520512580; cv=none; d=google.com; s=arc-20160816; b=R7KNsLzxo3fAHUMMLtnjxxNFaHiHpzH0BZGQmUyvTpBFinLpmiJ+Z1XGc3Eo+fkH6a oaWES81l5e5xEqhSdRVwE+1DUPAUC+7cKiwe/i0ErQGlOk1MtrcgBKgAL6DF1FyuBRnP IiTs0D2tM0SU3DX5UfYqiVTWL2pQ+udIcsYrUhJ2JbkZbmTGpdPamxRMXUEJPI5dMha7 3xUDGF7Jh2LxmmOl1D3ek4rbr/r5JN35/IET5ywJJ20dIr/ViU9l106Vt04NipY2y6kf TKrWvIXLzhBWbg45RffThXTccdYxDWb30cpLCT7SmmSNJow9JtRmxxjKYX03NjhX0YKl SSxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature :arc-authentication-results; bh=9/NtJB2aVjssNgbXkyZe68sQb4CSsliol/+i5INDHQs=; b=oMDxUemS5n0AWi892swkLV5N5UopZFzDGWKmwPFMK/JtYzYKZDFvFOO2zVch6W3EIb HMw6SHYV7j3nEo9YowNZK42ovf+6w4Um68Tm2jqXicDi0O/wQ7ZTD1QvbKUlp8esD8Go 8Nls05cGveJwj+9ts4p9pCnl8+7vZt+vGWAUDrzPV/hkT3hmwWoDZhIVB6+8o9rkV94V 5H3ONg1+y6rsKpiPjKgFOUlxtYn75VGXwJNGrobnXIqKJ21qVaQXiW6oXj6Xt7jxrVSt n+XW8b77U4/qIj3HWXGVwb4itIgmRG0VmOCeR7tRvye12HDjBU/L+PzrAIO9iNRXk6+1 6ktw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=szyJjMmZ; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o86si15767756pfi.253.2018.03.08.04.36.05; Thu, 08 Mar 2018 04:36:20 -0800 (PST) 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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=szyJjMmZ; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933757AbeCHMfM (ORCPT + 99 others); Thu, 8 Mar 2018 07:35:12 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:38544 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755009AbeCHMfI (ORCPT ); Thu, 8 Mar 2018 07:35:08 -0500 Received: by mail-wm0-f66.google.com with SMTP id z9so10692441wmb.3 for ; Thu, 08 Mar 2018 04:35:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=9/NtJB2aVjssNgbXkyZe68sQb4CSsliol/+i5INDHQs=; b=szyJjMmZTsU+NSLE+BxIhNlfstyoi7MMLQeuC8VeO8GOUyxQtgz7WbVEpKKhjaK1kN 5B5xPdqsiwvnUcElql52KoB9jt3i8fKkJoNwdysjYufO0dMDcxosjqq8kOqbNV8u2sCt CU/DAJqOWPRPVSggFEOGV8IPVefrSmqod7vkdvReIKUrBp2YYQPYc4WIZuwQLfWSYM2Y sMyRoo7xtV/ktuh3tmisRvfL3RHq4GhYDQ83aRc4YZRFfIn70DduHD0zEEyC2nIfYlCP FvRNo1jty94Xqqm5DJuNtAeuAUGDRg4WGmreKBSgK1AILr7NI0irS8cI5m8LVr1KBkDr c4NQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=9/NtJB2aVjssNgbXkyZe68sQb4CSsliol/+i5INDHQs=; b=CRl8R+3mTUtw2ezFeiX1KukVYlWUMq3zY98jKxJ4krDjsv0H0ymlhS7QvSz/6OGVDk e1rlxvfJuZa7xrcgOjpKmMZEVgZ4vfsV4nCXJnuJIhXgqLgdELHnQ+s/ayb9dhYqTrbu VsqwQznURLdy188Uwo6x4As7i9dtTpSl/NLxgWDpfpZ2adXwUyDKi9+2DpwcQ0WLIUUs pjcZPXCqZBzPIHVCiT7BlEGiCYANtlMxsoIUprbWnbGQuMekI2q1c7tLBRW+O+nlBWjs jiflIZBkhdcwIf08+rGrvFn4z+Yt6U1EkA90vvqfYg6AGe4IKYWpgHlnGnd4S0BW4V8o tsZw== X-Gm-Message-State: AElRT7EIrJ9hcl7QuQJjAFqlg1HjFJnBbqPAbWb+L7Xnpfi3Q0lI4uoB LXv3sE9lkJo7OgydKAIMy7Y= X-Received: by 10.28.144.82 with SMTP id s79mr15799889wmd.4.1520512507394; Thu, 08 Mar 2018 04:35:07 -0800 (PST) Received: from [10.43.17.166] (nat-pool-brq-t.redhat.com. [213.175.37.10]) by smtp.gmail.com with ESMTPSA id n64sm14225529wmd.11.2018.03.08.04.35.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Mar 2018 04:35:06 -0800 (PST) Subject: Re: [PATCH] Add an option to dm-verity to validate hashes at most once To: Patrik Torstensson , Alasdair Kergon , Mike Snitzer , dm-devel@redhat.com Cc: linux-kernel@vger.kernel.org, ebiggers@google.com, samitolvanen@google.com, gkaiser@google.com, paulcrowley@google.com References: <20180306231456.210504-1-totte@google.com> From: Milan Broz Message-ID: Date: Thu, 8 Mar 2018 13:35:05 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 In-Reply-To: <20180306231456.210504-1-totte@google.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 03/07/2018 12:14 AM, Patrik Torstensson wrote: > Add an option to dm-verity to validate hashes at most once > to allow platforms that is CPU/memory contraint to be > protected by dm-verity against offline attacks. > > The option introduces a bitset that is used to check if > a block has been validated before or not. A block can > be validated more than once as there is no thread protection > for the bitset. Hi, what happens, if a block is read, validated, marked in bitset and 1) something changes in the underlying device (data corruption, FTL hiccup, intentional remapping to different device-mapper device through table change) 2) user flushes all page caches 3) the same block is read again. Does it read and use unverified block from the corrupted device in this case? (In general, just reading the whole device means de-facto verification deactivation.) If so, your thread model assumes that you cannot attack underlying storage while it is in operation, is it the correct assumption? Milan > > This patch has been developed and tested on entry-level > Android Go devices. > > Signed-off-by: Patrik Torstensson > --- > drivers/md/dm-verity-target.c | 58 +++++++++++++++++++++++++++++++++-- > drivers/md/dm-verity.h | 1 + > 2 files changed, 56 insertions(+), 3 deletions(-) > > diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c > index aedb8222836b..479d0af212bf 100644 > --- a/drivers/md/dm-verity-target.c > +++ b/drivers/md/dm-verity-target.c > @@ -32,6 +32,7 @@ > #define DM_VERITY_OPT_LOGGING "ignore_corruption" > #define DM_VERITY_OPT_RESTART "restart_on_corruption" > #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" > +#define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" > > #define DM_VERITY_OPTS_MAX (2 + DM_VERITY_OPTS_FEC) > > @@ -432,6 +433,19 @@ static int verity_bv_zero(struct dm_verity *v, struct dm_verity_io *io, > return 0; > } > > +/* > + * Moves the bio iter one data block forward. > + */ > +static inline void verity_bv_skip_block(struct dm_verity *v, > + struct dm_verity_io *io, > + struct bvec_iter *iter) > +{ > + struct bio *bio = dm_bio_from_per_bio_data(io, > + v->ti->per_io_data_size); > + > + bio_advance_iter(bio, iter, 1 << v->data_dev_block_bits); > +} > + > /* > * Verify one "dm_verity_io" structure. > */ > @@ -445,8 +459,15 @@ static int verity_verify_io(struct dm_verity_io *io) > > for (b = 0; b < io->n_blocks; b++) { > int r; > + sector_t cur_block = io->block + b; > struct ahash_request *req = verity_io_hash_req(v, io); > > + if (v->validated_blocks && > + likely(test_bit(cur_block, v->validated_blocks))) { > + verity_bv_skip_block(v, io, &io->iter); > + continue; > + } > + > r = verity_hash_for_block(v, io, io->block + b, > verity_io_want_digest(v, io), > &is_zero); > @@ -481,13 +502,17 @@ static int verity_verify_io(struct dm_verity_io *io) > return r; > > if (likely(memcmp(verity_io_real_digest(v, io), > - verity_io_want_digest(v, io), v->digest_size) == 0)) > + verity_io_want_digest(v, io), > + v->digest_size) == 0)) { > + if (v->validated_blocks) > + set_bit(cur_block, v->validated_blocks); > continue; > + } > else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, > - io->block + b, NULL, &start) == 0) > + cur_block, NULL, &start) == 0) > continue; > else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, > - io->block + b)) > + cur_block)) > return -EIO; > } > > @@ -740,6 +765,7 @@ static void verity_dtr(struct dm_target *ti) > if (v->bufio) > dm_bufio_client_destroy(v->bufio); > > + kvfree(v->validated_blocks); > kfree(v->salt); > kfree(v->root_digest); > kfree(v->zero_digest); > @@ -760,6 +786,26 @@ static void verity_dtr(struct dm_target *ti) > kfree(v); > } > > +static int verity_alloc_most_once(struct dm_verity *v) > +{ > + struct dm_target *ti = v->ti; > + > + /* the bitset can only handle INT_MAX blocks */ > + if (v->data_blocks > INT_MAX) { > + ti->error = "device too large to use check_at_most_once"; > + return -E2BIG; > + } > + > + v->validated_blocks = kvzalloc(BITS_TO_LONGS(v->data_blocks) > + * sizeof(unsigned long), GFP_KERNEL); > + if (!v->validated_blocks) { > + ti->error = "failed to allocate bitset for check_at_most_once"; > + return -ENOMEM; > + } > + > + return 0; > +} > + > static int verity_alloc_zero_digest(struct dm_verity *v) > { > int r = -ENOMEM; > @@ -829,6 +875,12 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v) > } > continue; > > + } else if (!strcasecmp(arg_name, DM_VERITY_OPT_AT_MOST_ONCE)) { > + r = verity_alloc_most_once(v); > + if (r) > + return r; > + continue; > + > } else if (verity_is_fec_opt_arg(arg_name)) { > r = verity_fec_parse_opt_args(as, v, &argc, arg_name); > if (r) > diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h > index b675bc015512..ace5ec781b5f 100644 > --- a/drivers/md/dm-verity.h > +++ b/drivers/md/dm-verity.h > @@ -63,6 +63,7 @@ struct dm_verity { > sector_t hash_level_block[DM_VERITY_MAX_LEVELS]; > > struct dm_verity_fec *fec; /* forward error correction */ > + unsigned long *validated_blocks; /* bitset blocks validated */ > }; > > struct dm_verity_io { >