Received: by 2002:a05:6a10:a852:0:0:0:0 with SMTP id d18csp691325pxy; Wed, 5 May 2021 11:20:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyDjgh1p2htpDlKs6Jmsh9orGXdsjkbkw4uJNwPh2IM8UUyCg94uwHneJwFVX6KMHLtXEJ8 X-Received: by 2002:a62:6301:0:b029:28c:d3cb:7a8c with SMTP id x1-20020a6263010000b029028cd3cb7a8cmr150229pfb.4.1620238810805; Wed, 05 May 2021 11:20:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620238810; cv=none; d=google.com; s=arc-20160816; b=yZuCRP9eE9Y2qfCNUsTB9rn4s60CdW1Bef2Dvxbd7eDHe5FTZx+vCoKGE4qgqBjxOQ xx/qIJseqENUY+0lX1rKdkZW1vwj5lN5e8prSc+ukl6M+H2SHfNIccgAiWpNjS1Wsxwg HdcpA7QPbSZaWWbnXJtBbnD0pWr8l1Zp7YMVOxW/oOH7KVrWl90lNKc2nrYqzqcXyd0m D4/rSxvcuVMXSbzjCtvp84i7S7M2J1vMHNwDmrIdC6XbXfzdx7q1wM6nwiy/VJE8ItrN a08xEgll+ijFZzs3XxrAtPUmzRH6RSonh4vV6uSA/lYU8vuXvFF8ZVML7TNf67tr7Ygz 6Slw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=+IwZXLRXE7YG5YvYLQLnS3XtjuwltWw/8OV4sZc7FtQ=; b=RXCjtvz+zGVu2lisqNynri8QM+Hm61SVOxsBfU68sDC5k7xA29gHNP4esFi0Mql1Bc bUpTC7RUD/4xPxYlsmnACIkSgD8MrX5MXT5J+bvAX0bQ1aiuE+c1JmE8MdSQWaJAL64n rFCbxjedRbnfGQt+yZmbwrIS2wsDqDNcU6gLuaj0TI4k6U00hJdx0K4kyIt9r23VWdF7 7HK1sWFOKqufLSb13KkUffZNZp+I/xfvaXHIMh/7gEP9oLc5m0ssJq1zJMF80K2uRnkt d8Yvyzuw45Jg0N5MIK8vU0TXIS7cvT68axQ7LuObZgFUlB+oviHwVas75rwjYp/FVvbo vxOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=cYMtDHKC; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x3si5272514plb.436.2021.05.05.11.19.57; Wed, 05 May 2021 11:20:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=cYMtDHKC; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230395AbhEESTw (ORCPT + 99 others); Wed, 5 May 2021 14:19:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229901AbhEESTv (ORCPT ); Wed, 5 May 2021 14:19:51 -0400 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2251CC061574 for ; Wed, 5 May 2021 11:18:54 -0700 (PDT) Received: by mail-oi1-x230.google.com with SMTP id i81so3027999oif.6 for ; Wed, 05 May 2021 11:18:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=+IwZXLRXE7YG5YvYLQLnS3XtjuwltWw/8OV4sZc7FtQ=; b=cYMtDHKCglXEKCG8XFCDw0mo6ut3vuH0OSwu3mg8bbcS7aam9fkng1amjKuyWy10gd pkqctId/qGP2+eknKgPx5r2246N18DmMuTnicvkkmVtsBT1oL6PveOm2wAvFLXjhYPlA gSMZ4vYuD/VbxHvkEziYMpUWpKR8r79Q+Xdgc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=+IwZXLRXE7YG5YvYLQLnS3XtjuwltWw/8OV4sZc7FtQ=; b=QpWpTiq2QWKcXHpyNgbNnSx3FlQSUkSs5t6+BqOa1IP1mmgPDWzvUIgXv1F+1Wibqp lcZJSQ7SyBkXnGLAH2OepNi4Z+Zs+bHN/zEsEUFjeLTCQRfWLcCxXredgSmBszXVbgDb EP8BYMqSwktBTZSv18Tw5DrEFMDWTlBdyC2eVLlNRTcXjpUoNj/HwnYB1FzhAy/O/zHl QnKq3Z0bKjDe0N+7PB/dwIHA/qzvgPPlGShhKXkTa/6TKGOIsUVXa1ZNuBZmoE7kdRfB eghfTdEXUswTbEJrYa8oPOjvB1S0T5a1DEdcc97dbU9d7KjxSPTlp8uKQGCb5WoY6LL5 7pDQ== X-Gm-Message-State: AOAM532fkehRz6aEoffl3bFL4WlsD1pvwuuBHifL5fgYoJj0VW2F3aB3 b1y9/Fo/6CGZqKoxvVXPcxECpNGOz8HaVA== X-Received: by 2002:aca:4887:: with SMTP id v129mr144781oia.137.1620238733271; Wed, 05 May 2021 11:18:53 -0700 (PDT) Received: from mail-ot1-f54.google.com (mail-ot1-f54.google.com. [209.85.210.54]) by smtp.gmail.com with ESMTPSA id o1sm48253otj.39.2021.05.05.11.18.52 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 05 May 2021 11:18:53 -0700 (PDT) Received: by mail-ot1-f54.google.com with SMTP id f75-20020a9d03d10000b0290280def9ab76so2516814otf.12 for ; Wed, 05 May 2021 11:18:52 -0700 (PDT) X-Received: by 2002:a9d:425:: with SMTP id 34mr25334436otc.25.1620238732448; Wed, 05 May 2021 11:18:52 -0700 (PDT) MIME-Version: 1.0 References: <20210220013255.1083202-1-matthewgarrett@google.com> <20210220013255.1083202-7-matthewgarrett@google.com> In-Reply-To: <20210220013255.1083202-7-matthewgarrett@google.com> From: Evan Green Date: Wed, 5 May 2021 11:18:16 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH 6/9] pm: hibernate: Optionally store and verify a hash of the image To: Matthew Garrett Cc: LKML , linux-integrity@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, zohar@linux.ibm.com, "James E.J. Bottomley" , Jarkko Sakkinen , Jonathan Corbet , rjw@rjwysocki.net, Matthew Garrett Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Feb 19, 2021 at 5:36 PM Matthew Garrett wrote: > > Calculate and store a cryptographically secure hash of the hibernation > image if SF_VERIFY_IMAGE is set in the hibernation flags. This allows > detection of a corrupt image, but has the disadvantage that it requires > the blocks be read in in linear order. > > Signed-off-by: Matthew Garrett > --- > kernel/power/power.h | 1 + > kernel/power/swap.c | 131 +++++++++++++++++++++++++++++++++++-------- > 2 files changed, 110 insertions(+), 22 deletions(-) > > diff --git a/kernel/power/power.h b/kernel/power/power.h > index 778bf431ec02..b8e00b9dcee8 100644 > --- a/kernel/power/power.h > +++ b/kernel/power/power.h > @@ -168,6 +168,7 @@ extern int swsusp_swap_in_use(void); > #define SF_PLATFORM_MODE 1 > #define SF_NOCOMPRESS_MODE 2 > #define SF_CRC32_MODE 4 > +#define SF_VERIFY_IMAGE 8 > > /* kernel/power/hibernate.c */ > extern int swsusp_check(void); > diff --git a/kernel/power/swap.c b/kernel/power/swap.c > index 72e33054a2e1..a13241a20567 100644 > --- a/kernel/power/swap.c > +++ b/kernel/power/swap.c > @@ -31,6 +31,8 @@ > #include > #include > #include > +#include > +#include > > #include "power.h" > > @@ -95,17 +97,20 @@ struct swap_map_page_list { > struct swap_map_handle { > struct swap_map_page *cur; > struct swap_map_page_list *maps; > + struct shash_desc *desc; > sector_t cur_swap; > sector_t first_sector; > unsigned int k; > unsigned long reqd_free_pages; > u32 crc32; > + u8 digest[SHA256_DIGEST_SIZE]; > }; > > struct swsusp_header { > char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int) - > - sizeof(u32)]; > + sizeof(u32) - SHA256_DIGEST_SIZE]; > u32 crc32; > + u8 digest[SHA256_DIGEST_SIZE]; > sector_t image; > unsigned int flags; /* Flags to pass to the "boot" kernel */ > char orig_sig[10]; > @@ -305,6 +310,9 @@ static blk_status_t hib_wait_io(struct hib_bio_batch *hb) > * We are relying on the behavior of blk_plug that a thread with > * a plug will flush the plug list before sleeping. > */ > + if (!hb) > + return 0; > + > wait_event(hb->wait, atomic_read(&hb->count) == 0); > return blk_status_to_errno(hb->error); > } > @@ -327,6 +335,8 @@ static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags) > swsusp_header->flags = flags; > if (flags & SF_CRC32_MODE) > swsusp_header->crc32 = handle->crc32; > + memcpy(swsusp_header->digest, handle->digest, > + SHA256_DIGEST_SIZE); > error = hib_submit_io(REQ_OP_WRITE, REQ_SYNC, > swsusp_resume_block, swsusp_header, NULL); > } else { > @@ -417,6 +427,7 @@ static void release_swap_writer(struct swap_map_handle *handle) > static int get_swap_writer(struct swap_map_handle *handle) > { > int ret; > + struct crypto_shash *tfm; > > ret = swsusp_swap_check(); > if (ret) { > @@ -437,7 +448,28 @@ static int get_swap_writer(struct swap_map_handle *handle) > handle->k = 0; > handle->reqd_free_pages = reqd_free_pages(); > handle->first_sector = handle->cur_swap; > + > + tfm = crypto_alloc_shash("sha256", 0, 0); > + if (IS_ERR(tfm)) { > + ret = -EINVAL; > + goto err_rel; > + } > + handle->desc = kmalloc(sizeof(struct shash_desc) + > + crypto_shash_descsize(tfm), GFP_KERNEL); > + if (!handle->desc) { > + ret = -ENOMEM; > + goto err_rel; > + } > + > + handle->desc->tfm = tfm; > + > + ret = crypto_shash_init(handle->desc); > + if (ret != 0) > + goto err_free; > + > return 0; > +err_free: > + kfree(handle->desc); > err_rel: > release_swap_writer(handle); > err_close: > @@ -446,7 +478,7 @@ static int get_swap_writer(struct swap_map_handle *handle) > } > > static int swap_write_page(struct swap_map_handle *handle, void *buf, > - struct hib_bio_batch *hb) > + struct hib_bio_batch *hb, bool hash) > { > int error = 0; > sector_t offset; > @@ -454,6 +486,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, > if (!handle->cur) > return -EINVAL; > offset = alloc_swapdev_block(root_swap); > + crypto_shash_update(handle->desc, buf, PAGE_SIZE); Was this supposed to be conditionalized behind the new parameter, ie: if (hash) crypto_shash_update()? If so, the same comment would apply to the read as well.