diff mbox series

[U-Boot,3/4] fs: prevent overwriting reserved memory

Message ID 20181112212532.13126-4-simon.k.r.goldschmidt@gmail.com
State Superseded
Delegated to: Tom Rini
Headers show
Series Fix CVE-2018-18440 | expand

Commit Message

Simon Goldschmidt Nov. 12, 2018, 9:25 p.m. UTC
This fixes CVE-2018-18440 ("insufficient boundary checks in filesystem
image load") by using lmb to check the load size of a file against
reserved memory addresses.

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
---

 fs/fs.c       | 56 ++++++++++++++++++++++++++++++++++++++++++++++++---
 include/lmb.h |  2 ++
 lib/lmb.c     | 13 ++++++++++++
 3 files changed, 68 insertions(+), 3 deletions(-)

Comments

Fabio Estevam Nov. 13, 2018, 2:23 a.m. UTC | #1
Hi Simon,

On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
<simon.k.r.goldschmidt@gmail.com> wrote:

> diff --git a/fs/fs.c b/fs/fs.c
> index adae98d021..4baf6b1c39 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size)
>         return ret;
>  }
>
> -int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
> -           loff_t *actread)
> +#ifdef CONFIG_LMB

Unrelated to your series, but I was wondering if we could get rid of
the CONFIG_LMB option.

As far as I can see all the architectures define it, the only
exception being arch/sh.

If you agree I can send a patch after your series gets applied that
removes CONFIG_LMB.
Simon Goldschmidt Nov. 13, 2018, 5:47 a.m. UTC | #2
On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam <festevam@gmail.com> wrote:
>
> Hi Simon,
>
> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
> <simon.k.r.goldschmidt@gmail.com> wrote:
>
> > diff --git a/fs/fs.c b/fs/fs.c
> > index adae98d021..4baf6b1c39 100644
> > --- a/fs/fs.c
> > +++ b/fs/fs.c
> > @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size)
> >         return ret;
> >  }
> >
> > -int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
> > -           loff_t *actread)
> > +#ifdef CONFIG_LMB
>
> Unrelated to your series, but I was wondering if we could get rid of
> the CONFIG_LMB option.
>
> As far as I can see all the architectures define it, the only
> exception being arch/sh.
>
> If you agree I can send a patch after your series gets applied that
> removes CONFIG_LMB.

Sure, that would clean things up.

Simon
Heinrich Schuchardt Nov. 13, 2018, 7:42 p.m. UTC | #3
On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam <festevam@gmail.com> wrote:
>>
>> Hi Simon,
>>
>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
>> <simon.k.r.goldschmidt@gmail.com> wrote:
>>
>>> diff --git a/fs/fs.c b/fs/fs.c
>>> index adae98d021..4baf6b1c39 100644
>>> --- a/fs/fs.c
>>> +++ b/fs/fs.c
>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size)
>>>         return ret;
>>>  }
>>>
>>> -int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
>>> -           loff_t *actread)
>>> +#ifdef CONFIG_LMB
>>
>> Unrelated to your series, but I was wondering if we could get rid of
>> the CONFIG_LMB option.
>>
>> As far as I can see all the architectures define it, the only
>> exception being arch/sh.
>>
>> If you agree I can send a patch after your series gets applied that
>> removes CONFIG_LMB.
> 
> Sure, that would clean things up.
> 
> Simon
> 

NAK

This patch-series does not provide what is needed. With
odroid-c2_defconfig I get

fdt list /reserved-memory/secmon@10000000
reserved-memory {
        secmon@10000000 {
                reg = <0x00000000 0x10000000 0x00000000 0x00200000>;
                no-map;
        };
};

=> load mmc 0:1 0x10000000 dtb
22925 bytes read in 8 ms (2.7 MiB/s)

So now I have successfully overwritten the secure monitor. Urrgh.

As you have observed load is still writing into a memory area that is
reserved by the device-tree.

Please, iterate over the device tree to ensure that nothing is loaded
into a reserved memory area. Do not expect board files to do anything
but create the reserve-memory entry in the device tree.

Best regards

Heinrich
Simon Goldschmidt Nov. 13, 2018, 8:01 p.m. UTC | #4
On 13.11.2018 20:42, Heinrich Schuchardt wrote:
> On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
>> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam <festevam@gmail.com> wrote:
>>> Hi Simon,
>>>
>>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
>>> <simon.k.r.goldschmidt@gmail.com> wrote:
>>>
>>>> diff --git a/fs/fs.c b/fs/fs.c
>>>> index adae98d021..4baf6b1c39 100644
>>>> --- a/fs/fs.c
>>>> +++ b/fs/fs.c
>>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size)
>>>>          return ret;
>>>>   }
>>>>
>>>> -int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
>>>> -           loff_t *actread)
>>>> +#ifdef CONFIG_LMB
>>> Unrelated to your series, but I was wondering if we could get rid of
>>> the CONFIG_LMB option.
>>>
>>> As far as I can see all the architectures define it, the only
>>> exception being arch/sh.
>>>
>>> If you agree I can send a patch after your series gets applied that
>>> removes CONFIG_LMB.
>> Sure, that would clean things up.
>>
>> Simon
>>
> NAK
>
> This patch-series does not provide what is needed. With
> odroid-c2_defconfig I get
>
> fdt list /reserved-memory/secmon@10000000
> reserved-memory {
>          secmon@10000000 {
>                  reg = <0x00000000 0x10000000 0x00000000 0x00200000>;
>                  no-map;
>          };
> };
>
> => load mmc 0:1 0x10000000 dtb
> 22925 bytes read in 8 ms (2.7 MiB/s)
>
> So now I have successfully overwritten the secure monitor. Urrgh.
>
> As you have observed load is still writing into a memory area that is
> reserved by the device-tree.
>
> Please, iterate over the device tree to ensure that nothing is loaded
> into a reserved memory area. Do not expect board files to do anything
> but create the reserve-memory entry in the device tree.

First of all, thanks for testing. I must admit I haven't tested this 
case, I just had the impression the existing function 
'boot_fdt_add_mem_rsv_regions()' (in image-fdt.c) would do that. I'll 
have to dig into why it doesn't.

Or do you have CONFIG_OF_LIBFDT disabled?

In any case, it *was* my intention to include the dts memory 
reservation! I'll make sure I test that for a v2.

Simon
Heinrich Schuchardt Nov. 13, 2018, 9:36 p.m. UTC | #5
On 11/13/18 9:01 PM, Simon Goldschmidt wrote:
> On 13.11.2018 20:42, Heinrich Schuchardt wrote:
>> On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
>>> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam <festevam@gmail.com>
>>> wrote:
>>>> Hi Simon,
>>>>
>>>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
>>>> <simon.k.r.goldschmidt@gmail.com> wrote:
>>>>
>>>>> diff --git a/fs/fs.c b/fs/fs.c
>>>>> index adae98d021..4baf6b1c39 100644
>>>>> --- a/fs/fs.c
>>>>> +++ b/fs/fs.c
>>>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size)
>>>>>          return ret;
>>>>>   }
>>>>>
>>>>> -int fs_read(const char *filename, ulong addr, loff_t offset,
>>>>> loff_t len,
>>>>> -           loff_t *actread)
>>>>> +#ifdef CONFIG_LMB
>>>> Unrelated to your series, but I was wondering if we could get rid of
>>>> the CONFIG_LMB option.
>>>>
>>>> As far as I can see all the architectures define it, the only
>>>> exception being arch/sh.
>>>>
>>>> If you agree I can send a patch after your series gets applied that
>>>> removes CONFIG_LMB.
>>> Sure, that would clean things up.
>>>
>>> Simon
>>>
>> NAK
>>
>> This patch-series does not provide what is needed. With
>> odroid-c2_defconfig I get
>>
>> fdt list /reserved-memory/secmon@10000000
>> reserved-memory {
>>          secmon@10000000 {
>>                  reg = <0x00000000 0x10000000 0x00000000 0x00200000>;
>>                  no-map;
>>          };
>> };
>>
>> => load mmc 0:1 0x10000000 dtb
>> 22925 bytes read in 8 ms (2.7 MiB/s)
>>
>> So now I have successfully overwritten the secure monitor. Urrgh.
>>
>> As you have observed load is still writing into a memory area that is
>> reserved by the device-tree.
>>
>> Please, iterate over the device tree to ensure that nothing is loaded
>> into a reserved memory area. Do not expect board files to do anything
>> but create the reserve-memory entry in the device tree.
> 
> First of all, thanks for testing. I must admit I haven't tested this
> case, I just had the impression the existing function
> 'boot_fdt_add_mem_rsv_regions()' (in image-fdt.c) would do that. I'll
> have to dig into why it doesn't.
> 
> Or do you have CONFIG_OF_LIBFDT disabled?

`make odroid-c2_defconfig` sets
CONFIG_OF_LIBFDT=y

CONFIG_CMD_FDT depends on it. So without I would not have had the fdt
command used above.

The device-tree I was looking at was the one provided by U-Boot at
${fdtcontroladdr}.

We should also think about making this testable. I would be happy if we
had a test on a QEMU board.

Best regards

Heinrich

> 
> In any case, it *was* my intention to include the dts memory
> reservation! I'll make sure I test that for a v2.
> 
> Simon
>
Simon Goldschmidt Nov. 13, 2018, 9:47 p.m. UTC | #6
Am Di., 13. Nov. 2018, 22:37 hat Heinrich Schuchardt <xypron.glpk@gmx.de>
geschrieben:

> On 11/13/18 9:01 PM, Simon Goldschmidt wrote:
> > On 13.11.2018 20:42, Heinrich Schuchardt wrote:
> >> On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
> >>> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam <festevam@gmail.com>
> >>> wrote:
> >>>> Hi Simon,
> >>>>
> >>>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
> >>>> <simon.k.r.goldschmidt@gmail.com> wrote:
> >>>>
> >>>>> diff --git a/fs/fs.c b/fs/fs.c
> >>>>> index adae98d021..4baf6b1c39 100644
> >>>>> --- a/fs/fs.c
> >>>>> +++ b/fs/fs.c
> >>>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t *size)
> >>>>>          return ret;
> >>>>>   }
> >>>>>
> >>>>> -int fs_read(const char *filename, ulong addr, loff_t offset,
> >>>>> loff_t len,
> >>>>> -           loff_t *actread)
> >>>>> +#ifdef CONFIG_LMB
> >>>> Unrelated to your series, but I was wondering if we could get rid of
> >>>> the CONFIG_LMB option.
> >>>>
> >>>> As far as I can see all the architectures define it, the only
> >>>> exception being arch/sh.
> >>>>
> >>>> If you agree I can send a patch after your series gets applied that
> >>>> removes CONFIG_LMB.
> >>> Sure, that would clean things up.
> >>>
> >>> Simon
> >>>
> >> NAK
> >>
> >> This patch-series does not provide what is needed. With
> >> odroid-c2_defconfig I get
> >>
> >> fdt list /reserved-memory/secmon@10000000
> >> reserved-memory {
> >>          secmon@10000000 {
> >>                  reg = <0x00000000 0x10000000 0x00000000 0x00200000>;
> >>                  no-map;
> >>          };
> >> };
> >>
> >> => load mmc 0:1 0x10000000 dtb
> >> 22925 bytes read in 8 ms (2.7 MiB/s)
> >>
> >> So now I have successfully overwritten the secure monitor. Urrgh.
> >>
> >> As you have observed load is still writing into a memory area that is
> >> reserved by the device-tree.
> >>
> >> Please, iterate over the device tree to ensure that nothing is loaded
> >> into a reserved memory area. Do not expect board files to do anything
> >> but create the reserve-memory entry in the device tree.
> >
> > First of all, thanks for testing. I must admit I haven't tested this
> > case, I just had the impression the existing function
> > 'boot_fdt_add_mem_rsv_regions()' (in image-fdt.c) would do that. I'll
> > have to dig into why it doesn't.
> >
> > Or do you have CONFIG_OF_LIBFDT disabled?
>
> `make odroid-c2_defconfig` sets
> CONFIG_OF_LIBFDT=y
>
> CONFIG_CMD_FDT depends on it. So without I would not have had the fdt
> command used above.
>
> The device-tree I was looking at was the one provided by U-Boot at
> ${fdtcontroladdr}.
>

That might be an explanation. I used 'gd->fdt_blob' only in my patch. Are
there any more device tree locations to care about?

We should also think about making this testable. I would be happy if we
> had a test on a QEMU board.
>

I tried to build the tests but I only got build errors. Is there any
documentation about what I could be missing? I think my Ubuntu should be up
to date, so maybe I am missing some dependencies...?

Simon


> Best regards
>
> Heinrich
>
> >
> > In any case, it *was* my intention to include the dts memory
> > reservation! I'll make sure I test that for a v2.
> >
> > Simon
> >
>
>
Heinrich Schuchardt Nov. 13, 2018, 11:03 p.m. UTC | #7
On 11/13/18 10:47 PM, Simon Goldschmidt wrote:
> 
> 
> Am Di., 13. Nov. 2018, 22:37 hat Heinrich Schuchardt <xypron.glpk@gmx.de
> <mailto:xypron.glpk@gmx.de>> geschrieben:
> 
>     On 11/13/18 9:01 PM, Simon Goldschmidt wrote:
>     > On 13.11.2018 20:42, Heinrich Schuchardt wrote:
>     >> On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
>     >>> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam
>     <festevam@gmail.com <mailto:festevam@gmail.com>>
>     >>> wrote:
>     >>>> Hi Simon,
>     >>>>
>     >>>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
>     >>>> <simon.k.r.goldschmidt@gmail.com
>     <mailto:simon.k.r.goldschmidt@gmail.com>> wrote:
>     >>>>
>     >>>>> diff --git a/fs/fs.c b/fs/fs.c
>     >>>>> index adae98d021..4baf6b1c39 100644
>     >>>>> --- a/fs/fs.c
>     >>>>> +++ b/fs/fs.c
>     >>>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t
>     *size)
>     >>>>>          return ret;
>     >>>>>   }
>     >>>>>
>     >>>>> -int fs_read(const char *filename, ulong addr, loff_t offset,
>     >>>>> loff_t len,
>     >>>>> -           loff_t *actread)
>     >>>>> +#ifdef CONFIG_LMB
>     >>>> Unrelated to your series, but I was wondering if we could get
>     rid of
>     >>>> the CONFIG_LMB option.
>     >>>>
>     >>>> As far as I can see all the architectures define it, the only
>     >>>> exception being arch/sh.
>     >>>>
>     >>>> If you agree I can send a patch after your series gets applied that
>     >>>> removes CONFIG_LMB.
>     >>> Sure, that would clean things up.
>     >>>
>     >>> Simon
>     >>>
>     >> NAK
>     >>
>     >> This patch-series does not provide what is needed. With
>     >> odroid-c2_defconfig I get
>     >>
>     >> fdt list /reserved-memory/secmon@10000000
>     >> reserved-memory {
>     >>          secmon@10000000 {
>     >>                  reg = <0x00000000 0x10000000 0x00000000 0x00200000>;
>     >>                  no-map;
>     >>          };
>     >> };
>     >>
>     >> => load mmc 0:1 0x10000000 dtb
>     >> 22925 bytes read in 8 ms (2.7 MiB/s)
>     >>
>     >> So now I have successfully overwritten the secure monitor. Urrgh.
>     >>
>     >> As you have observed load is still writing into a memory area that is
>     >> reserved by the device-tree.
>     >>
>     >> Please, iterate over the device tree to ensure that nothing is loaded
>     >> into a reserved memory area. Do not expect board files to do anything
>     >> but create the reserve-memory entry in the device tree.
>     >
>     > First of all, thanks for testing. I must admit I haven't tested this
>     > case, I just had the impression the existing function
>     > 'boot_fdt_add_mem_rsv_regions()' (in image-fdt.c) would do that. I'll
>     > have to dig into why it doesn't.
>     >
>     > Or do you have CONFIG_OF_LIBFDT disabled?
> 
>     `make odroid-c2_defconfig` sets
>     CONFIG_OF_LIBFDT=y
> 
>     CONFIG_CMD_FDT depends on it. So without I would not have had the fdt
>     command used above.
> 
>     The device-tree I was looking at was the one provided by U-Boot at
>     ${fdtcontroladdr}.
> 
> 
> That might be an explanation. I used 'gd->fdt_blob' only in my patch.

For the Odroid C2 the relevant memory reservations are created in
arch/arm/mach-meson/board.c:61:
void meson_gx_init_reserved_memory(void *fdt)

According to /README ${fdtcontroladdr} and gd->fdt_blob should be the same:

lib/fdtdec.c:1255:
gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
(uintptr_t)gd->fdt_blob);

The boards with CONFIG_OF_PRIOR_STAGE=y set fdtcontroladdr in the board
file (board/broadcom/bcmstb/bcmstb.c).

You should use gd->fdt_blob. Just make sure it is already set.

Best regards

Heinrich

> Are there any more device tree locations to care about?
> 
>     We should also think about making this testable. I would be happy if we
>     had a test on a QEMU board.
> 
> 
> I tried to build the tests but I only got build errors. Is there any
> documentation about what I could be missing? I think my Ubuntu should be
> up to date, so maybe I am missing some dependencies...?
> 
> Simon
> 
> 
>     Best regards
> 
>     Heinrich
> 
>     >
>     > In any case, it *was* my intention to include the dts memory
>     > reservation! I'll make sure I test that for a v2.
>     >
>     > Simon
>     >
>
Simon Goldschmidt Nov. 16, 2018, 6:48 a.m. UTC | #8
On 14.11.2018 00:03, Heinrich Schuchardt wrote:
> On 11/13/18 10:47 PM, Simon Goldschmidt wrote:
>>
>> Am Di., 13. Nov. 2018, 22:37 hat Heinrich Schuchardt <xypron.glpk@gmx.de
>> <mailto:xypron.glpk@gmx.de>> geschrieben:
>>
>>      On 11/13/18 9:01 PM, Simon Goldschmidt wrote:
>>      > On 13.11.2018 20:42, Heinrich Schuchardt wrote:
>>      >> On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
>>      >>> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam
>>      <festevam@gmail.com <mailto:festevam@gmail.com>>
>>      >>> wrote:
>>      >>>> Hi Simon,
>>      >>>>
>>      >>>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
>>      >>>> <simon.k.r.goldschmidt@gmail.com
>>      <mailto:simon.k.r.goldschmidt@gmail.com>> wrote:
>>      >>>>
>>      >>>>> diff --git a/fs/fs.c b/fs/fs.c
>>      >>>>> index adae98d021..4baf6b1c39 100644
>>      >>>>> --- a/fs/fs.c
>>      >>>>> +++ b/fs/fs.c
>>      >>>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename, loff_t
>>      *size)
>>      >>>>>          return ret;
>>      >>>>>   }
>>      >>>>>
>>      >>>>> -int fs_read(const char *filename, ulong addr, loff_t offset,
>>      >>>>> loff_t len,
>>      >>>>> -           loff_t *actread)
>>      >>>>> +#ifdef CONFIG_LMB
>>      >>>> Unrelated to your series, but I was wondering if we could get
>>      rid of
>>      >>>> the CONFIG_LMB option.
>>      >>>>
>>      >>>> As far as I can see all the architectures define it, the only
>>      >>>> exception being arch/sh.
>>      >>>>
>>      >>>> If you agree I can send a patch after your series gets applied that
>>      >>>> removes CONFIG_LMB.
>>      >>> Sure, that would clean things up.
>>      >>>
>>      >>> Simon
>>      >>>
>>      >> NAK
>>      >>
>>      >> This patch-series does not provide what is needed. With
>>      >> odroid-c2_defconfig I get
>>      >>
>>      >> fdt list /reserved-memory/secmon@10000000
>>      >> reserved-memory {
>>      >>          secmon@10000000 {
>>      >>                  reg = <0x00000000 0x10000000 0x00000000 0x00200000>;
>>      >>                  no-map;
>>      >>          };
>>      >> };
>>      >>
>>      >> => load mmc 0:1 0x10000000 dtb
>>      >> 22925 bytes read in 8 ms (2.7 MiB/s)
>>      >>
>>      >> So now I have successfully overwritten the secure monitor. Urrgh.
>>      >>
>>      >> As you have observed load is still writing into a memory area that is
>>      >> reserved by the device-tree.
>>      >>
>>      >> Please, iterate over the device tree to ensure that nothing is loaded
>>      >> into a reserved memory area. Do not expect board files to do anything
>>      >> but create the reserve-memory entry in the device tree.
>>      >
>>      > First of all, thanks for testing. I must admit I haven't tested this
>>      > case, I just had the impression the existing function
>>      > 'boot_fdt_add_mem_rsv_regions()' (in image-fdt.c) would do that. I'll
>>      > have to dig into why it doesn't.
>>      >
>>      > Or do you have CONFIG_OF_LIBFDT disabled?
>>
>>      `make odroid-c2_defconfig` sets
>>      CONFIG_OF_LIBFDT=y
>>
>>      CONFIG_CMD_FDT depends on it. So without I would not have had the fdt
>>      command used above.
>>
>>      The device-tree I was looking at was the one provided by U-Boot at
>>      ${fdtcontroladdr}.
>>
>>
>> That might be an explanation. I used 'gd->fdt_blob' only in my patch.
> For the Odroid C2 the relevant memory reservations are created in
> arch/arm/mach-meson/board.c:61:
> void meson_gx_init_reserved_memory(void *fdt)
>
> According to /README ${fdtcontroladdr} and gd->fdt_blob should be the same:
>
> lib/fdtdec.c:1255:
> gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
> (uintptr_t)gd->fdt_blob);
>
> The boards with CONFIG_OF_PRIOR_STAGE=y set fdtcontroladdr in the board
> file (board/broadcom/bcmstb/bcmstb.c).
>
> You should use gd->fdt_blob. Just make sure it is already set.

OK, so it seems U-Boot just cannot handle the "reserved-memory" node 
with its subnodes but only the "memreserve" thing on top level?
I have the rest of the patches in a state I would submit, but I'll need 
some more time to dig into the dts reserved memory reservation...

Simon

>
> Best regards
>
> Heinrich
>
>> Are there any more device tree locations to care about?
>>
>>      We should also think about making this testable. I would be happy if we
>>      had a test on a QEMU board.
>>
>>
>> I tried to build the tests but I only got build errors. Is there any
>> documentation about what I could be missing? I think my Ubuntu should be
>> up to date, so maybe I am missing some dependencies...?
>>
>> Simon
>>
>>
>>      Best regards
>>
>>      Heinrich
>>
>>      >
>>      > In any case, it *was* my intention to include the dts memory
>>      > reservation! I'll make sure I test that for a v2.
>>      >
>>      > Simon
>>      >
>>
Heinrich Schuchardt Nov. 16, 2018, 6:47 p.m. UTC | #9
On 11/16/18 7:48 AM, Simon Goldschmidt wrote:
> On 14.11.2018 00:03, Heinrich Schuchardt wrote:
>> On 11/13/18 10:47 PM, Simon Goldschmidt wrote:
>>>
>>> Am Di., 13. Nov. 2018, 22:37 hat Heinrich Schuchardt <xypron.glpk@gmx.de
>>> <mailto:xypron.glpk@gmx.de>> geschrieben:
>>>
>>>      On 11/13/18 9:01 PM, Simon Goldschmidt wrote:
>>>      > On 13.11.2018 20:42, Heinrich Schuchardt wrote:
>>>      >> On 11/13/18 6:47 AM, Simon Goldschmidt wrote:
>>>      >>> On Tue, Nov 13, 2018 at 3:23 AM Fabio Estevam
>>>      <festevam@gmail.com <mailto:festevam@gmail.com>>
>>>      >>> wrote:
>>>      >>>> Hi Simon,
>>>      >>>>
>>>      >>>> On Mon, Nov 12, 2018 at 7:25 PM Simon Goldschmidt
>>>      >>>> <simon.k.r.goldschmidt@gmail.com
>>>      <mailto:simon.k.r.goldschmidt@gmail.com>> wrote:
>>>      >>>>
>>>      >>>>> diff --git a/fs/fs.c b/fs/fs.c
>>>      >>>>> index adae98d021..4baf6b1c39 100644
>>>      >>>>> --- a/fs/fs.c
>>>      >>>>> +++ b/fs/fs.c
>>>      >>>>> @@ -428,13 +428,57 @@ int fs_size(const char *filename,
>>> loff_t
>>>      *size)
>>>      >>>>>          return ret;
>>>      >>>>>   }
>>>      >>>>>
>>>      >>>>> -int fs_read(const char *filename, ulong addr, loff_t offset,
>>>      >>>>> loff_t len,
>>>      >>>>> -           loff_t *actread)
>>>      >>>>> +#ifdef CONFIG_LMB
>>>      >>>> Unrelated to your series, but I was wondering if we could get
>>>      rid of
>>>      >>>> the CONFIG_LMB option.
>>>      >>>>
>>>      >>>> As far as I can see all the architectures define it, the only
>>>      >>>> exception being arch/sh.
>>>      >>>>
>>>      >>>> If you agree I can send a patch after your series gets
>>> applied that
>>>      >>>> removes CONFIG_LMB.
>>>      >>> Sure, that would clean things up.
>>>      >>>
>>>      >>> Simon
>>>      >>>
>>>      >> NAK
>>>      >>
>>>      >> This patch-series does not provide what is needed. With
>>>      >> odroid-c2_defconfig I get
>>>      >>
>>>      >> fdt list /reserved-memory/secmon@10000000
>>>      >> reserved-memory {
>>>      >>          secmon@10000000 {
>>>      >>                  reg = <0x00000000 0x10000000 0x00000000
>>> 0x00200000>;
>>>      >>                  no-map;
>>>      >>          };
>>>      >> };
>>>      >>
>>>      >> => load mmc 0:1 0x10000000 dtb
>>>      >> 22925 bytes read in 8 ms (2.7 MiB/s)
>>>      >>
>>>      >> So now I have successfully overwritten the secure monitor.
>>> Urrgh.
>>>      >>
>>>      >> As you have observed load is still writing into a memory area
>>> that is
>>>      >> reserved by the device-tree.
>>>      >>
>>>      >> Please, iterate over the device tree to ensure that nothing
>>> is loaded
>>>      >> into a reserved memory area. Do not expect board files to do
>>> anything
>>>      >> but create the reserve-memory entry in the device tree.
>>>      >
>>>      > First of all, thanks for testing. I must admit I haven't
>>> tested this
>>>      > case, I just had the impression the existing function
>>>      > 'boot_fdt_add_mem_rsv_regions()' (in image-fdt.c) would do
>>> that. I'll
>>>      > have to dig into why it doesn't.
>>>      >
>>>      > Or do you have CONFIG_OF_LIBFDT disabled?
>>>
>>>      `make odroid-c2_defconfig` sets
>>>      CONFIG_OF_LIBFDT=y
>>>
>>>      CONFIG_CMD_FDT depends on it. So without I would not have had
>>> the fdt
>>>      command used above.
>>>
>>>      The device-tree I was looking at was the one provided by U-Boot at
>>>      ${fdtcontroladdr}.
>>>
>>>
>>> That might be an explanation. I used 'gd->fdt_blob' only in my patch.
>> For the Odroid C2 the relevant memory reservations are created in
>> arch/arm/mach-meson/board.c:61:
>> void meson_gx_init_reserved_memory(void *fdt)
>>
>> According to /README ${fdtcontroladdr} and gd->fdt_blob should be the
>> same:
>>
>> lib/fdtdec.c:1255:
>> gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
>> (uintptr_t)gd->fdt_blob);
>>
>> The boards with CONFIG_OF_PRIOR_STAGE=y set fdtcontroladdr in the board
>> file (board/broadcom/bcmstb/bcmstb.c).
>>
>> You should use gd->fdt_blob. Just make sure it is already set.
> 
> OK, so it seems U-Boot just cannot handle the "reserved-memory" node
> with its subnodes but only the "memreserve" thing on top level?
> I have the rest of the patches in a state I would submit, but I'll need
> some more time to dig into the dts reserved memory reservation...
> 
> Simon
> 

Linux
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
defines /reserved-memory.

Documentation/arm64/booting.txt defines /memreserve

The device tree specification v0.2 fails to provide the label used for
memory reservations.

https://patchwork.kernel.org/patch/5143721/ sheds some light:

"Device tree regions described by /memreserve/ entries are not available
in /proc/device-tree, and hence are not available to user space
utilities that use /proc/device-tree.  In order for these regions to be
available, convert any arm64 DTS files using /memreserve/ entries to use
reserved-memory nodes."

So /memreserve and /reserved-memory have different semantics but neither
region should be used by the load command.

Best regards

Heinrich

>>
>> Best regards
>>
>> Heinrich
>>
>>> Are there any more device tree locations to care about?
>>>
>>>      We should also think about making this testable. I would be
>>> happy if we
>>>      had a test on a QEMU board.
>>>
>>>
>>> I tried to build the tests but I only got build errors. Is there any
>>> documentation about what I could be missing? I think my Ubuntu should be
>>> up to date, so maybe I am missing some dependencies...?
>>>
>>> Simon
>>>
>>>
>>>      Best regards
>>>
>>>      Heinrich
>>>
>>>      >
>>>      > In any case, it *was* my intention to include the dts memory
>>>      > reservation! I'll make sure I test that for a v2.
>>>      >
>>>      > Simon
>>>      >
>>>
> 
>
diff mbox series

Patch

diff --git a/fs/fs.c b/fs/fs.c
index adae98d021..4baf6b1c39 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -428,13 +428,57 @@  int fs_size(const char *filename, loff_t *size)
 	return ret;
 }
 
-int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
-	    loff_t *actread)
+#ifdef CONFIG_LMB
+/* Check if a file may be read to the given address */
+static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
+			     loff_t len, struct fstype_info *info)
+{
+	struct lmb lmb;
+	int ret;
+	loff_t size;
+	loff_t read_len;
+
+	/* get the actual size of the file */
+	ret = info->size(filename, &size);
+	if (ret)
+		return ret;
+	if (offset >= size) {
+		/* offset >= EOF, no bytes will be written */
+		return 0;
+	}
+	read_len = size - offset;
+
+	/* limit to 'len' if it is smaller */
+	if (len && len < read_len)
+		read_len = len;
+
+	lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
+			     gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
+	lmb_dump_all(&lmb);
+
+	if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
+		return 0;
+
+	printf("** Reading file would overwrite reserved memory **\n");
+	return -1;
+}
+#endif
+
+static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
+		    int do_lmb_check, loff_t *actread)
 {
 	struct fstype_info *info = fs_get_info(fs_type);
 	void *buf;
 	int ret;
 
+#ifdef CONFIG_LMB
+	if (do_lmb_check) {
+		ret = fs_read_lmb_check(filename, addr, offset, len, info);
+		if (ret)
+			return ret;
+	}
+#endif
+
 	/*
 	 * We don't actually know how many bytes are being read, since len==0
 	 * means read the whole file.
@@ -451,6 +495,12 @@  int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
 	return ret;
 }
 
+int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
+	    loff_t *actread)
+{
+	return _fs_read(filename, addr, offset, len, 0, actread);
+}
+
 int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
 	     loff_t *actwrite)
 {
@@ -621,7 +671,7 @@  int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 		pos = 0;
 
 	time = get_timer(0);
-	ret = fs_read(filename, addr, pos, bytes, &len_read);
+	ret = _fs_read(filename, addr, pos, bytes, 1, &len_read);
 	time = get_timer(time);
 	if (ret < 0)
 		return 1;
diff --git a/include/lmb.h b/include/lmb.h
index bc06f175e1..810a37d5a5 100644
--- a/include/lmb.h
+++ b/include/lmb.h
@@ -31,6 +31,8 @@  struct lmb {
 extern struct lmb lmb;
 
 extern void lmb_init(struct lmb *lmb);
+extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base,
+				 phys_size_t size, void *fdt_blob);
 extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
 extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
 extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
diff --git a/lib/lmb.c b/lib/lmb.c
index c3af2fd5fc..99a4aaa09e 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -104,6 +104,19 @@  void lmb_init(struct lmb *lmb)
 	lmb->reserved.size = 0;
 }
 
+/* Initialize the struct, add memory and call arch/board reserve functions */
+void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size,
+			  void *fdt_blob)
+{
+	lmb_init(lmb);
+	lmb_add(lmb, base, size);
+	arch_lmb_reserve(lmb);
+	board_lmb_reserve(lmb);
+
+	if (IMAGE_ENABLE_OF_LIBFDT)
+		boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
+}
+
 /* This routine called with relocation disabled. */
 static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size)
 {