Skip to content

Commit

Permalink
libfdt: sync to upstream dtc.git commit 45f3d1a095dd
Browse files Browse the repository at this point in the history
sync to upstream dtc.git commit 45f3d1a095dd ("libfdt: overlay: make
overlay_get_target() public") from previous upstream sync commit 243176c
("Fix bogus error on rebuild"). This mainly updates license headers,
fixes one or two small bugs, sign mismatches, integer overflow, and
cases of undefined behaviour, compile warnings for newer compilers, and
introduces some checking options (which might be useful to speed up fdt
operations on awan).

The recipe for this patch is:

  $ cp ../dtc/libfdt/* libfdt/
  $ git add libfdt/fdt_check.c
  $ rm libfdt/meson.build

  Then add the INT32_MAX define to libc/include/limits.h, and update
  libfdt/Makefile.inc and libfdt/README.skiboot.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Cédric Le Goater <[email protected]>
  • Loading branch information
npiggin authored and legoater committed Dec 9, 2021
1 parent 10d5000 commit 301b3f7
Show file tree
Hide file tree
Showing 19 changed files with 665 additions and 889 deletions.
1 change: 1 addition & 0 deletions libc/include/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
#define CHAR_BIT 8

#define UINT32_MAX UINT_MAX
#define INT32_MAX INT_MAX

#endif
3 changes: 2 additions & 1 deletion libfdt/Makefile.inc
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
# Makefile.inc
#
# LIBFDT_ variables are taken from Makefile.libfdt

LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
fdt_addresses.c fdt_overlay.c
fdt_addresses.c fdt_overlay.c fdt_check.c
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)

CFLAGS_SKIP_libfdt/ = -Wsuggest-attribute=const -Wsuggest-attribute=noreturn
Expand Down
3 changes: 2 additions & 1 deletion libfdt/Makefile.libfdt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
# Makefile.libfdt
#
# This is not a complete Makefile of itself. Instead, it is designed to
Expand All @@ -7,7 +8,7 @@ LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
LIBFDT_VERSION = version.lds
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
fdt_addresses.c fdt_overlay.c
fdt_addresses.c fdt_overlay.c fdt_check.c
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
LIBFDT_LIB = libfdt-$(DTC_VERSION).$(SHAREDLIB_EXT)

Expand Down
8 changes: 5 additions & 3 deletions libfdt/README.skiboot
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
skiboot/libfdt/ is a minimally modified version of upstream libfdt that is
distributed with the dtc project hosted at github.com/dgibson/dtc.git.

This version is taken from dtc commit 243176c ("Fix bogus error on rebuild")
This version is taken from dtc.git commit 45f3d1a095dd ("libfdt: overlay: make
overlay_get_target() public") by copying all files from the libfdt/ directory.

The modifications from upstream are the additions of this file, and
Makefile.inc which has been derived from Makefile.libfdt.
The only modifications from the upstream source are the additions of this
file, and Makefile.inc which has been derived from Makefile.libfdt, and
the removal of meson.build.

Local libfdt changes should be kept to a minimum, and submitted upstream if
possible.
186 changes: 95 additions & 91 deletions libfdt/fdt.c
Original file line number Diff line number Diff line change
@@ -1,52 +1,7 @@
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
*
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
* a) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "libfdt_env.h"

Expand All @@ -60,23 +15,38 @@
* that the given buffer contains what appears to be a flattened
* device tree with sane information in its header.
*/
int fdt_ro_probe_(const void *fdt)
int32_t fdt_ro_probe_(const void *fdt)
{
uint32_t totalsize = fdt_totalsize(fdt);

if (can_assume(VALID_DTB))
return totalsize;

/* The device tree must be at an 8-byte aligned address */
if ((uintptr_t)fdt & 7)
return -FDT_ERR_ALIGNMENT;

if (fdt_magic(fdt) == FDT_MAGIC) {
/* Complete tree */
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
if (!can_assume(LATEST)) {
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
if (fdt_last_comp_version(fdt) >
FDT_LAST_SUPPORTED_VERSION)
return -FDT_ERR_BADVERSION;
}
} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
/* Unfinished sequential-write blob */
if (fdt_size_dt_struct(fdt) == 0)
if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0)
return -FDT_ERR_BADSTATE;
} else {
return -FDT_ERR_BADMAGIC;
}

return 0;
if (totalsize < INT32_MAX)
return totalsize;
else
return -FDT_ERR_TRUNCATED;
}

static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)
Expand Down Expand Up @@ -110,58 +80,82 @@ size_t fdt_header_size_(uint32_t version)
return FDT_V17_SIZE;
}

size_t fdt_header_size(const void *fdt)
{
return can_assume(LATEST) ? FDT_V17_SIZE :
fdt_header_size_(fdt_version(fdt));
}

int fdt_check_header(const void *fdt)
{
size_t hdrsize;

/* The device tree must be at an 8-byte aligned address */
if ((uintptr_t)fdt & 7)
return -FDT_ERR_ALIGNMENT;

if (fdt_magic(fdt) != FDT_MAGIC)
return -FDT_ERR_BADMAGIC;
if (!can_assume(LATEST)) {
if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
|| (fdt_last_comp_version(fdt) >
FDT_LAST_SUPPORTED_VERSION))
return -FDT_ERR_BADVERSION;
if (fdt_version(fdt) < fdt_last_comp_version(fdt))
return -FDT_ERR_BADVERSION;
}
hdrsize = fdt_header_size(fdt);
if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
|| (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
return -FDT_ERR_BADVERSION;
if (fdt_version(fdt) < fdt_last_comp_version(fdt))
return -FDT_ERR_BADVERSION;

if ((fdt_totalsize(fdt) < hdrsize)
|| (fdt_totalsize(fdt) > INT_MAX))
return -FDT_ERR_TRUNCATED;
if (!can_assume(VALID_DTB)) {

/* Bounds check memrsv block */
if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
return -FDT_ERR_TRUNCATED;
if ((fdt_totalsize(fdt) < hdrsize)
|| (fdt_totalsize(fdt) > INT_MAX))
return -FDT_ERR_TRUNCATED;

/* Bounds check structure block */
if (fdt_version(fdt) < 17) {
/* Bounds check memrsv block */
if (!check_off_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt)))
fdt_off_mem_rsvmap(fdt)))
return -FDT_ERR_TRUNCATED;
} else {
}

if (!can_assume(VALID_DTB)) {
/* Bounds check structure block */
if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
if (!check_off_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt)))
return -FDT_ERR_TRUNCATED;
} else {
if (!check_block_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt),
fdt_size_dt_struct(fdt)))
return -FDT_ERR_TRUNCATED;
}

/* Bounds check strings block */
if (!check_block_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt),
fdt_size_dt_struct(fdt)))
fdt_off_dt_strings(fdt),
fdt_size_dt_strings(fdt)))
return -FDT_ERR_TRUNCATED;
}

/* Bounds check strings block */
if (!check_block_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
return -FDT_ERR_TRUNCATED;

return 0;
}

const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
{
unsigned absoffset = offset + fdt_off_dt_struct(fdt);
unsigned int uoffset = offset;
unsigned int absoffset = offset + fdt_off_dt_struct(fdt);

if ((absoffset < offset)
|| ((absoffset + len) < absoffset)
|| (absoffset + len) > fdt_totalsize(fdt))
if (offset < 0)
return NULL;

if (fdt_version(fdt) >= 0x11)
if (((offset + len) < offset)
if (!can_assume(VALID_INPUT))
if ((absoffset < uoffset)
|| ((absoffset + len) < absoffset)
|| (absoffset + len) > fdt_totalsize(fdt))
return NULL;

if (can_assume(LATEST) || fdt_version(fdt) >= 0x11)
if (((uoffset + len) < uoffset)
|| ((offset + len) > fdt_size_dt_struct(fdt)))
return NULL;

Expand All @@ -177,7 +171,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)

*nextoffset = -FDT_ERR_TRUNCATED;
tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
if (!tagp)
if (!can_assume(VALID_DTB) && !tagp)
return FDT_END; /* premature end */
tag = fdt32_to_cpu(*tagp);
offset += FDT_TAGSIZE;
Expand All @@ -189,18 +183,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
do {
p = fdt_offset_ptr(fdt, offset++, 1);
} while (p && (*p != '\0'));
if (!p)
if (!can_assume(VALID_DTB) && !p)
return FDT_END; /* premature end */
break;

case FDT_PROP:
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
if (!lenp)
if (!can_assume(VALID_DTB) && !lenp)
return FDT_END; /* premature end */
/* skip-name offset, length and value */
offset += sizeof(struct fdt_property) - FDT_TAGSIZE
+ fdt32_to_cpu(*lenp);
if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
if (!can_assume(LATEST) &&
fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
offset += 4;
break;
Expand All @@ -223,17 +218,23 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)

int fdt_check_node_offset_(const void *fdt, int offset)
{
if ((offset < 0) || (offset % FDT_TAGSIZE)
|| (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
if (!can_assume(VALID_INPUT)
&& ((offset < 0) || (offset % FDT_TAGSIZE)))
return -FDT_ERR_BADOFFSET;

if (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)
return -FDT_ERR_BADOFFSET;

return offset;
}

int fdt_check_prop_offset_(const void *fdt, int offset)
{
if ((offset < 0) || (offset % FDT_TAGSIZE)
|| (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
if (!can_assume(VALID_INPUT)
&& ((offset < 0) || (offset % FDT_TAGSIZE)))
return -FDT_ERR_BADOFFSET;

if (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)
return -FDT_ERR_BADOFFSET;

return offset;
Expand Down Expand Up @@ -321,9 +322,12 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)

int fdt_move(const void *fdt, void *buf, int bufsize)
{
if (!can_assume(VALID_INPUT) && bufsize < 0)
return -FDT_ERR_NOSPACE;

FDT_RO_PROBE(fdt);

if (fdt_totalsize(fdt) > bufsize)
if (fdt_totalsize(fdt) > (unsigned int)bufsize)
return -FDT_ERR_NOSPACE;

memmove(buf, fdt, fdt_totalsize(fdt));
Expand Down
47 changes: 1 addition & 46 deletions libfdt/fdt.h
Original file line number Diff line number Diff line change
@@ -1,55 +1,10 @@
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
#ifndef FDT_H
#define FDT_H
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
* a) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef __ASSEMBLY__
Expand Down
Loading

0 comments on commit 301b3f7

Please sign in to comment.