Changeset c4267b1 in rtems for cpukit/dtc


Ignore:
Timestamp:
Apr 10, 2018, 7:06:18 AM (19 months ago)
Author:
David Gibson <david@…>
Branches:
master
Children:
8073f95e
Parents:
85d1769
git-author:
David Gibson <david@…> (04/10/18 07:06:18)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/19/18 05:01:11)
Message:

libfdt: Improve sequential write state checking

When creating a tree with the sequential write functions, certain things
have to be done in a certain order. You must create the memory reserve map
and only then can you create the actual tree structure.

The -FDT_ERR_BADSTATE return code is for if you try to do things out of
order. However, we weren't checking that very thoroughly, so it was
possible to generate a corrupted blob if, for example, you started calling
fdt_begin_node() etc. before calling fdt_finish_reservemap().

This makes the state checking more thorough disallow that.

Signed-off-by: David Gibson <david@…>
Tested-by: Alexey Kardashevskiy <aik@…>
Reviewed-by: Alexey Kardashevskiy <aik@…>
Reviewed-by: Simon Glass <sjg@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/dtc/libfdt/fdt_sw.c

    r85d1769 rc4267b1  
    5858static int fdt_sw_probe_(void *fdt)
    5959{
    60         if (fdt_magic(fdt) != FDT_SW_MAGIC)
     60        if (fdt_magic(fdt) == FDT_MAGIC)
     61                return -FDT_ERR_BADSTATE;
     62        else if (fdt_magic(fdt) != FDT_SW_MAGIC)
    6163                return -FDT_ERR_BADMAGIC;
    62         /* FIXME: should check more details about the header state */
    6364        return 0;
    6465}
     
    7172        }
    7273
     74/* 'memrsv' state:      Initial state after fdt_create()
     75 *
     76 * Allowed functions:
     77 *      fdt_add_reservmap_entry()
     78 *      fdt_finish_reservemap()         [moves to 'struct' state]
     79 */
     80static int fdt_sw_probe_memrsv_(void *fdt)
     81{
     82        int err = fdt_sw_probe_(fdt);
     83        if (err)
     84                return err;
     85
     86        if (fdt_off_dt_strings(fdt) != 0)
     87                return -FDT_ERR_BADSTATE;
     88        return 0;
     89}
     90
     91#define FDT_SW_PROBE_MEMRSV(fdt) \
     92        { \
     93                int err; \
     94                if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \
     95                        return err; \
     96        }
     97
     98/* 'struct' state:      Enter this state after fdt_finish_reservemap()
     99 *
     100 * Allowed functions:
     101 *      fdt_begin_node()
     102 *      fdt_end_node()
     103 *      fdt_property*()
     104 *      fdt_finish()                    [moves to 'complete' state]
     105 */
     106static int fdt_sw_probe_struct_(void *fdt)
     107{
     108        int err = fdt_sw_probe_(fdt);
     109        if (err)
     110                return err;
     111
     112        if (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))
     113                return -FDT_ERR_BADSTATE;
     114        return 0;
     115}
     116
     117#define FDT_SW_PROBE_STRUCT(fdt) \
     118        { \
     119                int err; \
     120                if ((err = fdt_sw_probe_struct_(fdt)) != 0) \
     121                        return err; \
     122        }
     123
     124/* 'complete' state:    Enter this state after fdt_finish()
     125 *
     126 * Allowed functions: none
     127 */
     128
    73129static void *fdt_grab_space_(void *fdt, size_t len)
    74130{
     
    103159                                              sizeof(struct fdt_reserve_entry)));
    104160        fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
    105         fdt_set_off_dt_strings(fdt, bufsize);
     161        fdt_set_off_dt_strings(fdt, 0);
    106162
    107163        return 0;
     
    134190        }
    135191
    136         fdt_set_off_dt_strings(buf, bufsize);
    137192        fdt_set_totalsize(buf, bufsize);
     193        if (fdt_off_dt_strings(buf))
     194                fdt_set_off_dt_strings(buf, bufsize);
    138195
    139196        return 0;
     
    145202        int offset;
    146203
    147         FDT_SW_PROBE(fdt);
    148 
    149         if (fdt_size_dt_struct(fdt))
    150                 return -FDT_ERR_BADSTATE;
     204        FDT_SW_PROBE_MEMRSV(fdt);
    151205
    152206        offset = fdt_off_dt_struct(fdt);
     
    165219int fdt_finish_reservemap(void *fdt)
    166220{
    167         return fdt_add_reservemap_entry(fdt, 0, 0);
     221        int err = fdt_add_reservemap_entry(fdt, 0, 0);
     222
     223        if (err)
     224                return err;
     225
     226        fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt));
     227        return 0;
    168228}
    169229
     
    171231{
    172232        struct fdt_node_header *nh;
    173         int namelen = strlen(name) + 1;
    174 
    175         FDT_SW_PROBE(fdt);
    176 
     233        int namelen;
     234
     235        FDT_SW_PROBE_STRUCT(fdt);
     236
     237        namelen = strlen(name) + 1;
    177238        nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
    178239        if (! nh)
     
    188249        fdt32_t *en;
    189250
    190         FDT_SW_PROBE(fdt);
     251        FDT_SW_PROBE_STRUCT(fdt);
    191252
    192253        en = fdt_grab_space_(fdt, FDT_TAGSIZE);
     
    226287        int nameoff;
    227288
    228         FDT_SW_PROBE(fdt);
     289        FDT_SW_PROBE_STRUCT(fdt);
    229290
    230291        nameoff = fdt_find_add_string_(fdt, name);
     
    263324        int offset, nextoffset;
    264325
    265         FDT_SW_PROBE(fdt);
     326        FDT_SW_PROBE_STRUCT(fdt);
    266327
    267328        /* Add terminator */
Note: See TracChangeset for help on using the changeset viewer.