lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Fri, 27 Feb 2015 11:35:47 +0000
From:	"Kweh, Hock Leong" <hock.leong.kweh@...el.com>
To:	Roy Franz <roy.franz@...aro.org>
CC:	"Fleming, Matt" <matt.fleming@...el.com>,
	Ming Lei <ming.lei@...onical.com>,
	Sam Protsenko <semen.protsenko@...aro.org>,
	"Greg Kroah-Hartman" <gregkh@...uxfoundation.org>,
	LKML <linux-kernel@...r.kernel.org>,
	"linux-efi@...r.kernel.org" <linux-efi@...r.kernel.org>,
	"Ong, Boon Leong" <boon.leong.ong@...el.com>
Subject: RE: [PATCH v2 3/3] efi: Capsule update with user helper interface

> -----Original Message-----
> From: Roy Franz [mailto:roy.franz@...aro.org]
> Sent: Friday, February 27, 2015 1:07 PM
> 
> On Sun, Nov 2, 2014 at 7:07 PM, Kweh Hock Leong
> > +/*
> > + * This function will store the capsule binary and pass it to
> > + * efi_capsule_update() API in capsule.c  */ static int
> > +efi_capsule_store(const struct firmware *fw) {
> > +       int i;
> > +       int ret;
> > +       int count = fw->size;
> > +       int copy_size = (fw->size > PAGE_SIZE) ? PAGE_SIZE : fw->size;
> > +       int pages_needed = ALIGN(fw->size, PAGE_SIZE) >> PAGE_SHIFT;
> > +       struct page **pages;
> > +       void *page_data;
> > +       efi_capsule_header_t *capsule = NULL;
> > +
> > +       pages = kmalloc_array(pages_needed, sizeof(void *), GFP_KERNEL);
> > +       if (!pages) {
> > +               pr_err("%s: kmalloc_array() failed\n", __func__);
> > +               return -ENOMEM;
> > +       }
> > +
> > +       for (i = 0; i < pages_needed; i++) {
> > +               pages[i] = alloc_page(GFP_KERNEL);
> > +               if (!pages[i]) {
> > +                       pr_err("%s: alloc_page() failed\n", __func__);
> > +                       --i;
> > +                       ret = -ENOMEM;
> > +                       goto failed;
> > +               }
> > +       }
> > +
> > +       for (i = 0; i < pages_needed; i++) {
> > +               page_data = kmap(pages[i]);
> > +               memcpy(page_data, fw->data + (i * PAGE_SIZE),
> > + copy_size);
> > +
> > +               if (i == 0)
> > +                       capsule = (efi_capsule_header_t *)page_data;
> > +               else
> > +                       kunmap(pages[i]);
> > +
> > +               count -= copy_size;
> > +               if (count < PAGE_SIZE)
> > +                       copy_size = count;
> > +       }
> > +
> > +       ret = efi_capsule_update(capsule, pages);
> > +       if (ret) {
> > +               pr_err("%s: efi_capsule_update() failed\n", __func__);
> > +               --i;
> 
> Hi Hock,
> 
> What does the decrement of i do here?  I looked at
> efi_capsule_update() and didn't see anything that would account for this.  It
> looks like in this failure case one page won't get freed.
> 
> As an aside, when I was looking at efi_update_capsule, I see that Matt is
> doing very similar operations (array of struct page pointers), but does it like
> this (snipped from his patch):
> 
> + struct page **block_pgs;
> ...
> +       block_pgs = kzalloc(nr_block_pgs * sizeof(*block_pgs), GFP_KERNEL);
> +       if (!block_pgs)
> +               return -ENOMEM;
> +
> +       for (i = 0; i < nr_block_pgs; i++) {
> +               block_pgs[i] = alloc_page(GFP_KERNEL);
> +               if (!block_pgs[i])
> +                       goto fail;
> +       }
> 
> and then can simply free the pages that are not NULL:
> +fail:
> +       for (i = 0; i < nr_block_pgs; i++) {
> +               if (block_pgs[i])
> +                       __free_page(block_pgs[i]);
> +       }
> 
> I think this way is preferable since it doesn't rely on 'i' being unchanged at the
> end of the function.  I also think it would be nice if the capsule code stuck
> with one idiom for dealing with arrays of page pointers.
> 
> Roy
> 

Hi Roy,

The reason "i" there have to perform a decrement is because a full for loop
will end with one extra incremented value if it does not break out in the middle.

And the efi_capsule_store()'s alloc page is to store the binary content and the
efi_capsule_update() from Matt is to store the efi capsule block descriptor
which will point to the binary blocks content. So, they are different.


Regards,
Wilson

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ