From patchwork Mon Jan 20 12:43:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: 'Darko Komljenovic' via swupdate X-Patchwork-Id: 1225922 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4864:20::239; helo=mail-lj1-x239.google.com; envelope-from=swupdate+bncbc6ynavgsakrb7gas3yqkgqedfkhz2a@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=googlegroups.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20161025 header.b=TOa9ITBQ; dkim-atps=neutral Received: from mail-lj1-x239.google.com (mail-lj1-x239.google.com [IPv6:2a00:1450:4864:20::239]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 481WYs0hwqz9sRf for ; Mon, 20 Jan 2020 23:43:44 +1100 (AEDT) Received: by mail-lj1-x239.google.com with SMTP id y24sf7515875ljc.19 for ; Mon, 20 Jan 2020 04:43:44 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1579524221; cv=pass; d=google.com; s=arc-20160816; b=ld/EnD1Kt+Y6tVLo+wPQPWmyMLqVsFml9Dbv3zJrpkOk0lztijbF1IpKNssuLxeYdK y2a6orlBl591zNYfNGEiEfS9bNP/7muSz/JS+cy/g1/Bi7rAPbNJncNrjm+RiE3oMDwI KjQXPdP2KoKN6JNh9YsQqT4zAPfkqp/4oo0Gj6ruHEIMmFepQKbCIcxm8UugoFBjghE9 mr3lqhyi5j47Tk30JeEQ/gL9JhCFR24xI0Gz56VAi51czYCJkSfEh3iaIGzFXpHZZ+OW xEOFNP1zllOx6Y1b2n/6IwIchqtH5yyXYF5RwWoJKZk6UKGYxOfDiOosMmgemuwXJyl7 KgJQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=6q0aZoXaGOvkYORAi7krqXlBrwnBqpXsFzXWwM4SB3s=; b=jSqlo+K+QhbJPsv6BM1zKWiNZ/eYtayRaneZvzieWM77FY1auPo1gZ1hzEmljoT1bk fmXMKTgLLlOGx9W05EFmN0kTYz4u1i2+qrqSmMg0xFoPiseGQ14nLzrD1M5d5umph/If 6lKmQ84yHsXlVElDh2P3QnM5FRm//WhxpMVG4qNtM4mn5/V0+9sCywIRv7g66nM+39dB UpMn8qY1bcijlZ/kyV8JJa9zpFOeaE+frVNJ95XSH/67gO3PldB4higjDcy9Lb96RZg6 yeTz1vt++0aXL6Y6OJF0WZwap2TAT5j1Sgky4hzmFvkx06annoulOXM+b0ggBQv3Rj3K NlHA== ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b="Dq/t+S9g"; spf=pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) smtp.mailfrom=Mark.Jonas@de.bosch.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=de.bosch.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:x-original-sender:x-original-authentication-results :reply-to:precedence:mailing-list:list-id:list-post:list-help :list-archive:list-subscribe:list-unsubscribe; bh=6q0aZoXaGOvkYORAi7krqXlBrwnBqpXsFzXWwM4SB3s=; b=TOa9ITBQvOC8VB1ECxJ9WnRO65OXzjaJPkqpBcVbAYAPrwCFEZiVhXDKph+gTqF/En Nko4jF8rLd71Rd7bR9OSf7od0DNaM76+2Zzc/aq27fcGyeuPgA79B21tZqsPFN6TvgYY PvEf9qpDlOE7QHl4JLoRAhYEJm848wy23V0LOXcjrx5y1qQCVH5ICyMTGuNaRAL4ddRX 5rY8wkpgy7qxR7/Hz2jkL6t7l5xdUpyepi2M8Fn6A7M0UnQjawiZOW++6w7rPuW934oh WQ59gRCXi1K4WlxoiiKu0H4EuNEGuIqgDKRdkM7EHY/E9loqLqy6yav0gSSjgOw5OF/m Kk3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:x-original-sender :x-original-authentication-results:reply-to:precedence:mailing-list :list-id:x-spam-checked-in-group:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=6q0aZoXaGOvkYORAi7krqXlBrwnBqpXsFzXWwM4SB3s=; b=j6iVmiLY2A37+sfmjMnyXhGFPvUwri+CTbp80ktCX5V14Np35CdANQaBeOM7cHwVMP pi96ynA6aJK7/UGm4aV5WwwbbCCxqWWl22rJgUIvIvzlzkZp31cOm+9LttVy58iLY6LO EovP89+cctm5l0jD2swBC7rf8jDoPhaIcy8EjEiyU3CqfGl4kbf0+yGVqxU9pTcgE6xW 8RQQxr8p8IW+QOSakJHmBkJFN43zfy2zsK/ODTV4r9f10K5/qAah+S2WqLjjYQItXYIq ptUR5waxHd1cgAlqA9JjqUGuXayPJ4zpbxOMaIMbDTj5N9Sy7axGbT6D0Q6hNEEj2vIn 4gRA== X-Gm-Message-State: APjAAAXgjp4Eq/SgsBvDmMYTpsvCylpbfutOI+gpw3sMH5UC1cachjxo uKSsidZy6tlWjfM5E1ajec4= X-Google-Smtp-Source: APXvYqzHnF3yl2aTD2+VduvlTuAZQ+5w8Fy680Y3xowP6WLFWo2PoKXkmVIqXh+pM8qeZw+8swqYDQ== X-Received: by 2002:ac2:54b4:: with SMTP id w20mr12984519lfk.67.1579524221273; Mon, 20 Jan 2020 04:43:41 -0800 (PST) X-BeenThere: swupdate@googlegroups.com Received: by 2002:ac2:5086:: with SMTP id f6ls313715lfm.9.gmail; Mon, 20 Jan 2020 04:43:40 -0800 (PST) X-Received: by 2002:a19:cb97:: with SMTP id b145mr7252024lfg.161.1579524220383; Mon, 20 Jan 2020 04:43:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579524220; cv=none; d=google.com; s=arc-20160816; b=tm92KgLfc7ksxPRYHYYnrhgIY+Bo6r7pfOv8WE335Y1qVkxUJtld92oIFZJk7FBXAf DnuAWRa21s5YomHIET60HJfEFYpnFv1Q0Xn1nXR4X9tGZM4b4U+RzHpIEZrRQWc0CDVY t/2nDffQHvzwhmhy10Fgq3Cvm8SaRIZX6FLCMsqADuqG/QAunY3vkzpspugRHrKQ0y6r urGM+aDGEh2pZskpqwC1+9eVjxUJ44fh40dms+5+ZnmBJkskSnmi+yHuH1hwAhHT5iWw QA5+iv7vPCRZBKJT9rY7OFwJbd40iJALju2EXyW7GLTGIL3t9Hk7Uri2a9E2ZLCAI1dz a9lA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=d+dYq8WlTykZvJmjFD//vRGGjL0BZz+hi4QFfknlPTc=; b=B7I7JjLVY6NpySSl7yOCGvFJSLAukVBi71CP8fNccu+/Dnqlsi1WXEt1ILzNjVIoZF grZLeUMkDgrETL8Gvt/GWzIj+m8ZCv0ox7hXK4+wVBHYgo5GIgHZtx5Sch/XQ3Pipv/l TLTSIVMvweK7/vTZ2khsjpRqdZfdVGutD22a6CwLdcYg093A8/TerYDzhzZ4f3vLdIDb zrfIOI2DDBcHApcgf/xR6OT4HaR4HoFocdWVNzK+usEQzeiuxphu6wEB7Mul9HIiZ3LH OLWMlW04fxV0jMAh2KBKT8irVhdrGWt8q1HJEy5l/GPU5OYqKnG8xtbJNW6z7jlPrtqS 6zZQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b="Dq/t+S9g"; spf=pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) smtp.mailfrom=Mark.Jonas@de.bosch.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=de.bosch.com Received: from de-out1.bosch-org.com (de-out1.bosch-org.com. [139.15.230.186]) by gmr-mx.google.com with ESMTPS id p20si1699851lji.1.2020.01.20.04.43.40 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Jan 2020 04:43:40 -0800 (PST) Received-SPF: pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) client-ip=139.15.230.186; Received: from fe0vm1650.rbesz01.com (unknown [139.15.230.188]) by si0vms0217.rbdmz01.com (Postfix) with ESMTPS id 481WYl5K55z4f3lwb; Mon, 20 Jan 2020 13:43:39 +0100 (CET) Received: from si0vm4642.rbesz01.com (unknown [10.58.172.176]) by fe0vm1650.rbesz01.com (Postfix) with ESMTPS id 481WYl4zWWz2gc; Mon, 20 Jan 2020 13:43:39 +0100 (CET) X-AuditID: 0a3aad12-e6bff700000045d7-cf-5e25a07bfe25 Received: from fe0vm1652.rbesz01.com ( [10.58.173.29]) (using TLS with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by si0vm4642.rbesz01.com (SMG Outbound) with SMTP id 66.91.17879.B70A52E5; Mon, 20 Jan 2020 13:43:39 +0100 (CET) Received: from SI-HUB2000.de.bosch.com (si-hub2000.de.bosch.com [10.4.103.108]) by fe0vm1652.rbesz01.com (Postfix) with ESMTPS id 481WYl2ntVzB0v; Mon, 20 Jan 2020 13:43:39 +0100 (CET) Received: from ninja.grb-fir.grb.de.bosch.com (10.19.187.97) by SI-HUB2000.de.bosch.com (10.4.103.108) with Microsoft SMTP Server id 15.1.1847.3; Mon, 20 Jan 2020 13:43:39 +0100 X-Patchwork-Original-From: "'Mark Jonas' via swupdate" From: 'Darko Komljenovic' via swupdate To: , CC: , , , Mark Jonas Subject: [swupdate] [PATCH v2 1/3] handlers: add readback handler Date: Mon, 20 Jan 2020 13:43:10 +0100 Message-ID: <20200120124312.15129-2-mark.jonas@de.bosch.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200120124312.15129-1-mark.jonas@de.bosch.com> References: <20200120124312.15129-1-mark.jonas@de.bosch.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA22SX0wTWRjFuTNDe6kMHQaQz2p1HUM0KFgQFV00xgejcY0kvhijrFMZaJUW MlMIqAm4EVhRUFECVi3Vdf2zsqkSlwAikequ1P8YV1gTjRo0FUUTqpFGojtDwfbBt3O/c3/3 3HtyMcnuVuuw2WoTRCufx6k0lGbxn/qkHc6ELMPbp/r0yps/pde3DYcvI1Y67N3Uyo6DHlUm sUGTkS3kmYsEce7SzRrTrgPDZEHbnOKR6hVlqHNGFcIYmDRw1W+rQhrMMvUEfHXsVwUWlxFc PvyYCCz+QtB06Fl4FYrAKiYR/utuJRUdy6RA7zs/oWiS2QlO+65RHcMsgK7Xn1WKppgEeF97 l1I0zWRA/62+URaYaXD+wtVRHcEsgYeV5eHKjVh5T+O1ZYHt0eA50k8Fjgfo8nrJA0hrD7Hs IZYTEX+gOMlsKLKkLUhLTRaNgrTdkJK8Jd/SjAKNsa3o4qMcNyIwcqP5mODiaPVWLouNMuZn l5h4yfSzWJgnSJyOLn27ZxMb820sFRotZkky51vdCDDJxdLOXxKyWDqbL9kuiPkBzI0mY4qL p3Px2o0sk8vbhG2CUCCI4+6PGHNAVzTKYLQo5ArFOeY827jN6WkUFhbGTgx1QmMJHOFG83Ck nH3UoWRLBbxFMueO4ZMCODs+DaI30UJdPJ2+WGYYxTUVWr+l6qbQibVyAXEhRpAcQH0IIy6G FpXASPn7BfOALlMqih4bBqHUUzLDtAJ8PT8TfO2DCBytHxF4hz8hOOXzI/AP1hHg6xkioKN/ hABX5wAFH47XhYO3uVwFl8orVdDd266CB+12NTw6c0wNr4+8wdDnPDwBLp5xTQDvhRORcP1k LQ1/N32iwfOhLgra9pzUgv9KjxYcX3q1UHNsWAv7fv8nGnyPh1jY7zkUA031B2OhvPp+LHRW VMcNyF0Scpf/LuSULm287Ttdjk2Dj9OVobSue5oZrsyc6aYbXmNbf8fZpCSqaVHG81clkUvU NctN5x6qH/za7FlttJb+cCO+cc3umqGo2WTx3tJzq5JOv0kufjJPP7VhFrV+YPoKi++3ohd7 76xuIN8/bbkymLOh4uWtV3zN2p6pW1o8Uuq15+0Gw0jhpRbN8kl6f4XLn9lzu3EdR0kmPiWR FCX+f5GP+pUXBAAA X-Original-Sender: mark.jonas@de.bosch.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@de.bosch.com header.s=key2-intmail header.b="Dq/t+S9g"; spf=pass (google.com: domain of mark.jonas@de.bosch.com designates 139.15.230.186 as permitted sender) smtp.mailfrom=Mark.Jonas@de.bosch.com; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=de.bosch.com X-Original-From: Mark Jonas Reply-To: Mark Jonas Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , From: Kevin Zhang To verify that an image was written properly, this readback handler calculates the sha256 hash of a partition (or part of it) and compares it against a given hash value. Signed-off-by: Kevin Zhang Signed-off-by: Mark Jonas --- handlers/Config.in | 14 +++- handlers/Makefile | 1 + handlers/readback_handler.c | 124 ++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 handlers/readback_handler.c diff --git a/handlers/Config.in b/handlers/Config.in index 41eac1c..be1c7a0 100644 --- a/handlers/Config.in +++ b/handlers/Config.in @@ -48,7 +48,7 @@ config UBIWHITELIST help Define a list of MTD devices that are planned to have always UBI. If first attach fails, the device is erased - and tried again. + and tried again. The list can be set as a string with the mtd numbers. Examples: "0 1 2" This sets mtd0-mtd1-mtd2 to be used as UBI volumes. @@ -106,6 +106,18 @@ config RDIFFHANDLER Add support for applying librsync's rdiff patches, see http://librsync.sourcefrog.net/ +config READBACKHANDLER + bool "readback" + depends on HASH_VERIFY + default n + help + To verify that an image was written properly, this readback handler + calculates the sha256 hash of a partition (or part of it) and compares + it against a given hash value. + + This is a post-install handler running at the same time as + post-install scripts. + config LUASCRIPTHANDLER bool "Lua Script" depends on LUA diff --git a/handlers/Makefile b/handlers/Makefile index 61e4f76..b756f31 100644 --- a/handlers/Makefile +++ b/handlers/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CFIHAMMING1)+= flash_hamming1_handler.o obj-$(CONFIG_LUASCRIPTHANDLER) += lua_scripthandler.o obj-$(CONFIG_RAW) += raw_handler.o obj-$(CONFIG_RDIFFHANDLER) += rdiff_handler.o +obj-$(CONFIG_READBACKHANDLER) += readback_handler.o obj-$(CONFIG_REMOTE_HANDLER) += remote_handler.o obj-$(CONFIG_SHELLSCRIPTHANDLER) += shell_scripthandler.o obj-$(CONFIG_SSBLSWITCH) += ssbl_handler.o diff --git a/handlers/readback_handler.c b/handlers/readback_handler.c new file mode 100644 index 0000000..d99a574 --- /dev/null +++ b/handlers/readback_handler.c @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: 2020 Bosch Sicherheitssysteme GmbH + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "swupdate.h" +#include "handler.h" +#include "sslapi.h" +#include "util.h" + +void readback_handler(void); +static int readback_postinst(struct img_type *img); + +static int readback(struct img_type *img, void *data) +{ + if (!data) + return -1; + + script_fn scriptfn = *(script_fn *)data; + switch (scriptfn) { + case POSTINSTALL: + return readback_postinst(img); + case PREINSTALL: + default: + return 0; + } +} + +static int readback_postinst(struct img_type *img) +{ + /* Get property: partition hash */ + unsigned char hash[SHA256_HASH_LENGTH]; + char *ascii_hash = dict_get_value(&img->properties, "sha256"); + if (!ascii_hash || ascii_to_hash(hash, ascii_hash) < 0 || !IsValidHash(hash)) { + ERROR("Invalid hash"); + return -EINVAL; + } + + /* Get property: partition size */ + unsigned int size = 0; + char *value = dict_get_value(&img->properties, "size"); + if (value) { + size = strtoul(value, NULL, 10); + } else { + TRACE("Property size not found, use partition size"); + } + + /* Get property: offset */ + unsigned long offset = 0; + value = dict_get_value(&img->properties, "offset"); + if (value) { + offset = strtoul(value, NULL, 10); + } else { + TRACE("Property offset not found, use default 0"); + } + + /* Open the device (partition) */ + int fdin = open(img->device, O_RDONLY); + if (fdin < 0) { + ERROR("Failed to open %s: %s", img->device, strerror(errno)); + } + + /* Get the real size of the partition, if size is not set. */ + if (size == 0) { + if (ioctl(fdin, BLKGETSIZE64, &size) < 0) { + ERROR("Cannot get size of %s", img->device); + close(fdin); + return -EFAULT; + } + TRACE("Partition size: %u", size); + } + + /* + * Seek the file descriptor before passing it to copyfile(). + * This is necessary because copyfile() only accepts streams, + * so the file descriptor shall be already at the right position. + */ + if (lseek(fdin, offset, SEEK_SET) < 0) { + ERROR("Seek %lu bytes failed: %s", offset, strerror(errno)); + close(fdin); + return -EFAULT; + } + + /* + * Perform hash verification. We do not need to pass an output device to + * the copyfile() function, because we only want it to verify the hash of + * the input device. + */ + unsigned long offset_out = 0; + int status = copyfile(fdin, + NULL, /* no output */ + size, + &offset_out, + 0, /* no output seek */ + 1, /* skip file, do not write to the output */ + 0, /* no compressed */ + NULL, /* no checksum */ + hash, + 0, /* no encrypted */ + NULL); /* no callback */ + if (status == 0) { + INFO("Readback verification success"); + } else { + ERROR("Readback verification failed, status=%d", status); + } + + close(fdin); + return status; +} + +__attribute__((constructor)) +void readback_handler(void) +{ + register_handler("readback", readback, SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); +}