[PATCH v2] spl: Add callback for preprocessing loaded FIT header before parsing
Farhan Ali
farhan.ali at broadcom.com
Wed Mar 10 21:49:07 CET 2021
On Wed, Mar 10, 2021 at 11:38 AM Alex G. <mr.nuke.me at gmail.com> wrote:
> On 3/9/21 5:55 PM, Farhan Ali wrote:
> > This change adds a callback for preprocessing the FIT header before
> > it is parsed. There are 3 main reasons for this callback:
> >
> > (1) If a vulnerability is discovered in the FIT parsing/loading code,
> > or libfdt, this callback allows users to scan the FIT header for
> > specific exploit signatures and prevent flashing/booting of the image
> >
> > (2) If users want to implement a single signature which covers the
> > entire FIT header, which is then appended to the end of the header,
> > then this callback can be used to authenticate that signature.
> >
> > (3) If users want to check the FIT header contents against specific
> > metadata stored outside the FIT header, then this callback allows
> > them to do that.
>
> Hi Fahran,
>
> This patch describes "how" you're trying to achieve it, but "what" you
> want to achieve. I'll get later into why I think the "how" is
> fundamentally flawed.
>
> Hi Alex,
The 'what' is basically this: I want to be able to parse the fit header for
correctness before
any image loading takes place. This 'correctness' will be user defined
The 'how' is this: A weak function which is invoked right after the fit
HEADER ONLY is read.
There should be at least a use case implemented in this series. When
> someone notices an empty function that isn't used, the first instinct
> would be to submit a patch to remove it. But more importantly, seeing an
> actual example of "what" you are trying to achieve will help others
> suggest a better way on "how" to achieve it.
>
> The main use case for us is two folds:
(1) Customers are worried about our reliance on libfdt for FIT parsing and
want to prescan the FIT header to
check for any future exploits
(2) We implement a signature on the entire FIT header ( instead of
individual nodes ). This speeds
up the signing process for production/development builds. We want to be
able validate this signature
before the FIT parsing starts. Signature is stored elsewhere, outside the
FIT header.
Second issue is that spl_simple_fit_read() is intended to bring a FIT
> image to memory. If you need to make decisions on the content of that
> image, then spl_simple_fit_read() is the wrong place to do it. A better
> place might be spl_simple_fit_parse().
>
spl_simple_fit_parse() parses the 'contents' of the fit using standard
APIs. We need to check
the FIT header for correctness BEFORE its contents are parsed, using a user
defined 'safe'
parsing function. The standard FIT loading flow checks for only a few
things ( hashes/configuration etc),
there can be a lot of other USER defined checks which may need to be
checked. This callback will achieve this
The third issue is that whatever the end goal is, you're trying to
> achieve it with weak functions. Weak functions aren't always bad. There
> are a limited number of cases where they work very well for the purpose
> -- I've even used them before. But to introduce a weak function, a
> really strong argument is needed. Maybe you have it, but that argument
> needs to be made clear.
>
> The reason I used a weak function was to mirror the already
upstreamed board_spl_fit_post_load(), I
thought that the justifications for that function would also apply to this
new board_spl_fit_pre_load().
If board_spl_fit_pre_load() is fundamentally different in some aspect, then
I am happy to look for an
alternative implementation.
Regards,
Farhan
> Let's assume board 'c' implements this. Then later someone with board
> 'd' implements this at the SOC level. Does board 'c' get the old
> implementation, or the new? Things become ambiguous in everything but
> the simplest of cases.
>
> A more elegant way would be to have a proper interface to hook into the
> FIT processing. That could be done by a function pointer, ops structure,
> or perhaps new UCLASS (Simon?).
>
> Alex
>
>
>
>
> > Signed-off-by: Farhan Ali <farhan.ali at broadcom.com>
> > Cc: Simon Glass <sjg at chromium.org>
> > Cc: Alexandru Gagniuc <mr.nuke.me at gmail.com>
> > Cc: Marek Vasut <marex at denx.de>
> > Cc: Michal Simek <michal.simek at xilinx.com>
> > Cc: Philippe Reynes <philippe.reynes at softathome.com>
> > Cc: Samuel Holland <samuel at sholland.org>
> >
> > ---
> > Changes for v2:
> > - Callback now returns a value
> > - Added a log message on failure
> > ---
> > common/spl/spl_fit.c | 22 +++++++++++++++++++++-
> > 1 file changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> > index 75c8ff0..01aee1c 100644
> > --- a/common/spl/spl_fit.c
> > +++ b/common/spl/spl_fit.c
> > @@ -43,6 +43,14 @@ __weak ulong board_spl_fit_size_align(ulong size)
> > return size;
> > }
> >
> > +__weak int board_spl_fit_pre_load(struct spl_load_info *load_info,
> > + const void *fit,
> > + ulong start_sector,
> > + ulong loaded_sector_count)
> > +{
> > + return 0;
> > +}
> > +
> > static int find_node_from_desc(const void *fit, int node, const char
> *str)
> > {
> > int child;
> > @@ -527,6 +535,7 @@ static int spl_simple_fit_read(struct spl_fit_info
> *ctx,
> > unsigned long count, size;
> > int sectors;
> > void *buf;
> > + int rc = 0;
> >
> > /*
> > * For FIT with external data, figure out where the external images
> > @@ -552,7 +561,18 @@ static int spl_simple_fit_read(struct spl_fit_info
> *ctx,
> > debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu,
> size=0x%lx\n",
> > sector, sectors, buf, count, size);
> >
> > - return (count == 0) ? -EIO : 0;
> > + if (count) {
> > + /* preprocess loaded fit header before parsing and loading
> binaries */
> > + rc = board_spl_fit_pre_load(info, fit_header, sector,
> sectors);
> > + if (rc) {
> > + debug("%s: fit header pre processing failed.
> rc=%d\n",
> > + __func__, rc);
> > + }
> > + } else {
> > + rc = -EIO;
> > + }
> > +
> > + return rc;
> > }
> >
> > static int spl_simple_fit_parse(struct spl_fit_info *ctx)
> >
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4203 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210310/ec52263e/attachment.bin>
More information about the U-Boot
mailing list