All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org,
	masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl,
	u-boot@lists.denx.de, sjg@chromium.org, agraf@csgraf.de
Subject: Re: [PATCH v7 01/12] tools: mkeficapsule: rework the code a little bit
Date: Wed, 17 Nov 2021 10:20:26 +0900	[thread overview]
Message-ID: <20211117012026.GB36373@laputa> (raw)
In-Reply-To: <0b2d704e-c9cd-7db1-de84-87b256f93f05@gmx.de>

On Tue, Nov 16, 2021 at 01:19:10PM +0100, Heinrich Schuchardt wrote:
> On 11/16/21 05:32, AKASHI Takahiro wrote:
> > Abstract common routines to make the code easily understandable.
> > No functional change.
> > 
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> > ---
> >   tools/mkeficapsule.c | 223 ++++++++++++++++++++++++++++++-------------
> >   1 file changed, 159 insertions(+), 64 deletions(-)
> > 
> > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > index 4995ba4e0c2a..afdcaf7e7933 100644
> > --- a/tools/mkeficapsule.c
> > +++ b/tools/mkeficapsule.c
> > @@ -61,17 +61,122 @@ static void print_usage(void)
> >   	       tool_name);
> >   }
> > 
> > +/**
> > + * read_bin_file - read a firmware binary file
> > + * @bin:	Path to a firmware binary file
> > + * @data:	Pointer to pointer of allocated buffer
> > + * @bin_size:	Size of allocated buffer
> > + *
> > + * Read out a content of binary, @bin, into @data.
> > + * A caller should free @data.
> > + *
> > + * Return:
> > + * * 0  - on success
> > + * * -1 - on failure
> > + */
> > +static int read_bin_file(char *bin, void **data, off_t *bin_size)
> > +{
> > +	FILE *g;
> > +	struct stat bin_stat;
> > +	void *buf;
> > +	size_t size;
> > +	int ret = 0;
> > +
> > +	g = fopen(bin, "r");
> > +	if (!g) {
> > +		printf("cannot open %s\n", bin);
> 
> Error messages should be written to stderr. Use perror(bin) to get a
> message like:
> 
>     <filename>: No such file or directory
> 
> Or use fprintf(stderr, ...).

OK.
But remember that I have used printf() throughout mkeficapsule.c
even before this patch.
So I will add similar changes in patch#1 for consistency. 

> > +		return -1;
> > +	}
> > +	if (stat(bin, &bin_stat) < 0) {
> > +		printf("cannot determine the size of %s\n", bin);
> > +		ret = -1;
> > +		goto err;
> > +	}
> > +	if (bin_stat.st_size > (u32)~0U) {
> > +		printf("file size is too large: %s\n", bin);
> > +		ret = -1;
> > +		goto err;
> > +	}
> > +	buf = malloc(bin_stat.st_size);
> 
> For a symbolic link st_size is the length of the pathname it contains.
> So this function is of no help here.

Not true.
According to stat() manpage,

"lstat() is identical to stat(), except that if pathname is  a  symbolic
 link,  then  it returns information about the link itself, not the file
 that it refers to."

So stat() is a right system call.


> > +	if (!buf) {
> > +		printf("cannot allocate memory: %zx\n",
> > +		       (size_t)bin_stat.st_size);
> > +		ret = -1;
> > +		goto err;
> > +	}
> > +
> > +	size = fread(buf, 1, bin_stat.st_size, g);
> > +	if (size < bin_stat.st_size) {
> 
> fread() reads from a stream which is not necessarily a file but can be a
> named pipe. stat() does not indicate when the stream will end.
> 
> You have to run fread() in a loop until feof() or ferror() indicate that
> there is nothing more to be read from the stream.

No.
"a stream which is not necessarily a file but can be a named pipe"
may be true, but we don't handle such a use case with this tool.

-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
> > +		printf("read failed (%zx)\n", size);
> > +		ret = -1;
> > +		goto err;
> > +	}
> > +
> > +	*data = buf;
> > +	*bin_size = bin_stat.st_size;
> > +err:
> > +	fclose(g);
> > +
> > +	return ret;
> > +}
> > +
> > +/**
> > + * write_capsule_file - write a capsule file
> > + * @bin:	FILE stream
> > + * @data:	Pointer to data
> > + * @bin_size:	Size of data
> > + *
> > + * Write out data, @data, with the size @bin_size.
> > + *
> > + * Return:
> > + * * 0  - on success
> > + * * -1 - on failure
> > + */
> > +static int write_capsule_file(FILE *f, void *data, size_t size, const char *msg)
> > +{
> > +	size_t size_written;
> > +
> > +	size_written = fwrite(data, 1, size, f);
> > +	if (size_written < size) {
> > +		printf("%s: write failed (%zx != %zx)\n", msg,
> > +		       size_written, size);
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * create_fwbin - create an uefi capsule file
> > + * @path:	Path to a created capsule file
> > + * @bin:	Path to a firmware binary to encapsulate
> > + * @guid:	GUID of related FMP driver
> > + * @index:	Index number in capsule
> > + * @instance:	Instance number in capsule
> > + * @mcount:	Monotonic count in authentication information
> > + * @private_file:	Path to a private key file
> > + * @cert_file:	Path to a certificate file
> > + *
> > + * This function actually does the job of creating an uefi capsule file.
> > + * All the arguments must be supplied.
> > + * If either @private_file ror @cert_file is NULL, the capsule file
> > + * won't be signed.
> > + *
> > + * Return:
> > + * * 0  - on success
> > + * * -1 - on failure
> > + */
> >   static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> >   			unsigned long index, unsigned long instance)
> >   {
> >   	struct efi_capsule_header header;
> >   	struct efi_firmware_management_capsule_header capsule;
> >   	struct efi_firmware_management_capsule_image_header image;
> > -	FILE *f, *g;
> > -	struct stat bin_stat;
> > -	u8 *data;
> > -	size_t size;
> > +	FILE *f;
> > +	void *data;
> > +	off_t bin_size;
> >   	u64 offset;
> > +	int ret;
> > 
> >   #ifdef DEBUG
> >   	printf("For output: %s\n", path);
> > @@ -79,25 +184,28 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> >   	printf("\tindex: %ld\n\tinstance: %ld\n", index, instance);
> >   #endif
> > 
> > -	g = fopen(bin, "r");
> > -	if (!g) {
> > -		printf("cannot open %s\n", bin);
> > -		return -1;
> > -	}
> > -	if (stat(bin, &bin_stat) < 0) {
> > -		printf("cannot determine the size of %s\n", bin);
> > -		goto err_1;
> > -	}
> > -	data = malloc(bin_stat.st_size);
> > -	if (!data) {
> > -		printf("cannot allocate memory: %zx\n", (size_t)bin_stat.st_size);
> > -		goto err_1;
> > -	}
> > +	f = NULL;
> > +	data = NULL;
> > +	ret = -1;
> > +
> > +	/*
> > +	 * read a firmware binary
> > +	 */
> > +	if (read_bin_file(bin, &data, &bin_size))
> > +		goto err;
> > +
> > +	/*
> > +	 * write a capsule file
> > +	 */
> >   	f = fopen(path, "w");
> >   	if (!f) {
> >   		printf("cannot open %s\n", path);
> > -		goto err_2;
> > +		goto err;
> >   	}
> > +
> > +	/*
> > +	 * capsule file header
> > +	 */
> >   	header.capsule_guid = efi_guid_fm_capsule;
> >   	header.header_size = sizeof(header);
> >   	/* TODO: The current implementation ignores flags */
> > @@ -105,70 +213,57 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> >   	header.capsule_image_size = sizeof(header)
> >   					+ sizeof(capsule) + sizeof(u64)
> >   					+ sizeof(image)
> > -					+ bin_stat.st_size;
> > -
> > -	size = fwrite(&header, 1, sizeof(header), f);
> > -	if (size < sizeof(header)) {
> > -		printf("write failed (%zx)\n", size);
> > -		goto err_3;
> > -	}
> > +					+ bin_size;
> > +	if (write_capsule_file(f, &header, sizeof(header),
> > +			       "Capsule header"))
> > +		goto err;
> > 
> > +	/*
> > +	 * firmware capsule header
> > +	 * This capsule has only one firmware capsule image.
> > +	 */
> >   	capsule.version = 0x00000001;
> >   	capsule.embedded_driver_count = 0;
> >   	capsule.payload_item_count = 1;
> > -	size = fwrite(&capsule, 1, sizeof(capsule), f);
> > -	if (size < (sizeof(capsule))) {
> > -		printf("write failed (%zx)\n", size);
> > -		goto err_3;
> > -	}
> > +	if (write_capsule_file(f, &capsule, sizeof(capsule),
> > +			       "Firmware capsule header"))
> > +		goto err;
> > +
> >   	offset = sizeof(capsule) + sizeof(u64);
> > -	size = fwrite(&offset, 1, sizeof(offset), f);
> > -	if (size < sizeof(offset)) {
> > -		printf("write failed (%zx)\n", size);
> > -		goto err_3;
> > -	}
> > +	if (write_capsule_file(f, &offset, sizeof(offset),
> > +			       "Offset to capsule image"))
> > +		goto err;
> > 
> > +	/*
> > +	 * firmware capsule image header
> > +	 */
> >   	image.version = 0x00000003;
> >   	memcpy(&image.update_image_type_id, guid, sizeof(*guid));
> >   	image.update_image_index = index;
> >   	image.reserved[0] = 0;
> >   	image.reserved[1] = 0;
> >   	image.reserved[2] = 0;
> > -	image.update_image_size = bin_stat.st_size;
> > +	image.update_image_size = bin_size;
> >   	image.update_vendor_code_size = 0; /* none */
> >   	image.update_hardware_instance = instance;
> >   	image.image_capsule_support = 0;
> > +	if (write_capsule_file(f, &image, sizeof(image),
> > +			       "Firmware capsule image header"))
> > +		goto err;
> > 
> > -	size = fwrite(&image, 1, sizeof(image), f);
> > -	if (size < sizeof(image)) {
> > -		printf("write failed (%zx)\n", size);
> > -		goto err_3;
> > -	}
> > -	size = fread(data, 1, bin_stat.st_size, g);
> > -	if (size < bin_stat.st_size) {
> > -		printf("read failed (%zx)\n", size);
> > -		goto err_3;
> > -	}
> > -	size = fwrite(data, 1, bin_stat.st_size, f);
> > -	if (size < bin_stat.st_size) {
> > -		printf("write failed (%zx)\n", size);
> > -		goto err_3;
> > -	}
> > -
> > -	fclose(f);
> > -	fclose(g);
> > -	free(data);
> > -
> > -	return 0;
> > +	/*
> > +	 * firmware binary
> > +	 */
> > +	if (write_capsule_file(f, data, bin_size, "Firmware binary"))
> > +		goto err;
> > 
> > -err_3:
> > -	fclose(f);
> > -err_2:
> > +	ret = 0;
> > +err:
> > +	if (f)
> > +		fclose(f);
> >   	free(data);
> > -err_1:
> > -	fclose(g);
> > 
> > -	return -1;
> > +	return ret;
> >   }
> > 
> >   /*
> > 
> 

  reply	other threads:[~2021-11-17  1:20 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-16  4:32 [PATCH v7 00/12] efi_loader: capsule: improve capsule authentication support AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 01/12] tools: mkeficapsule: rework the code a little bit AKASHI Takahiro
2021-11-16 12:19   ` Heinrich Schuchardt
2021-11-17  1:20     ` AKASHI Takahiro [this message]
2021-11-16  4:32 ` [PATCH v7 02/12] tools: build mkeficapsule with tools-only_defconfig AKASHI Takahiro
2021-11-16 12:20   ` Heinrich Schuchardt
2021-11-16 13:58     ` Heinrich Schuchardt
2021-11-17  1:06       ` AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 03/12] tools: mkeficapsule: add firmwware image signing AKASHI Takahiro
2021-11-25 11:13   ` Ilias Apalodimas
2021-11-16  4:32 ` [PATCH v7 04/12] tools: mkeficapsule: add man page AKASHI Takahiro
2021-11-25 11:13   ` Ilias Apalodimas
2021-11-16  4:32 ` [PATCH v7 05/12] doc: update UEFI document for usage of mkeficapsule AKASHI Takahiro
2021-11-25 11:15   ` Ilias Apalodimas
2021-11-16  4:32 ` [PATCH v7 06/12] test/py: efi_capsule: add image authentication test AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 07/12] tools: mkeficapsule: allow for specifying GUID explicitly AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 08/12] test/py: efi_capsule: align with the syntax change of mkeficapsule AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 09/12] test/py: efi_capsule: add a test for "--guid" option AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 10/12] test/py: efi_capsule: check the results in case of CAPSULE_AUTHENTICATE AKASHI Takahiro
2021-11-16  4:32 ` [PATCH v7 11/12] (RFC) tools: add fdtsig.sh AKASHI Takahiro
2021-11-25  0:11   ` Simon Glass
2021-11-16  4:32 ` [PATCH v7 12/12] (RFC) efi_loader, dts: add public keys for capsules to device tree AKASHI Takahiro
2021-11-25  0:11   ` Simon Glass
2021-11-25  2:21     ` AKASHI Takahiro
2021-12-07 15:07       ` Simon Glass
2021-11-25  6:02 ` [PATCH v7 00/12] efi_loader: capsule: improve capsule authentication support AKASHI Takahiro
2021-12-03  7:09   ` AKASHI Takahiro
2021-12-17  2:24     ` AKASHI Takahiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211117012026.GB36373@laputa \
    --to=takahiro.akashi@linaro.org \
    --cc=agraf@csgraf.de \
    --cc=ilias.apalodimas@linaro.org \
    --cc=mark.kettenis@xs4all.nl \
    --cc=masami.hiramatsu@linaro.org \
    --cc=sjg@chromium.org \
    --cc=sughosh.ganu@linaro.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.