[OSS-Tools] [PATCH 4/5] libdt: add CONFIG_TEST_LOOPBACK

2023-05-31 Thread Ahmad Fatoum
We have quite a bit of tricky udev and device tree parsing code that is
only tested manually. Best case we would have tests for this in QEMU,
but until we do, let's test it with loop devices:

The downside is that we can only test block devices and that we need
a tiny bit of code that's not used normally, but on the upside, we
have tests. :-)

Signed-off-by: Ahmad Fatoum 
---
 configure.ac |  2 ++
 meson.build  |  1 +
 src/dt/dt.h  |  1 -
 src/libdt.c  | 50 +++---
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 117a1e169ba9..5b5c74c2b582 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,6 +40,8 @@ AC_DEFINE(CONFIG_MTD, [1], [Statically define to be enabled 
to harmonize barebox
 
 AC_DEFINE(CONFIG_STATE, [1], [Statically define to be enabled to harmonize 
barebox' & dt-utils' code base.])
 
+AC_DEFINE(CONFIG_TEST_LOOPBACK, [0], [Only enabled in meson for testing.])
+
 AC_CHECK_FUNCS([__secure_getenv secure_getenv])
 
 my_CFLAGS="-Wall \
diff --git a/meson.build b/meson.build
index 1bc32274af07..be92446f137a 100644
--- a/meson.build
+++ b/meson.build
@@ -21,6 +21,7 @@ conf.set10('CONFIG_MTD', true)
 conf.set10('CONFIG_STATE', true)
 conf.set10('CONFIG_STATE_BACKWARD_COMPATIBLE', 
get_option('state-backward-compatibility'))
 conf.set10('CONFIG_LOCK_DEVICE_NODE', get_option('lock-device'))
+conf.set10('CONFIG_TEST_LOOPBACK', get_option('tests'))
 
 meson.add_dist_script(
   find_program('check-news.sh').path(),
diff --git a/src/dt/dt.h b/src/dt/dt.h
index a4213d49606a..153b56e09a21 100644
--- a/src/dt/dt.h
+++ b/src/dt/dt.h
@@ -220,7 +220,6 @@ extern int of_set_root_node(struct device_node *node);
 extern int of_platform_populate(struct device_node *root,
const struct of_device_id *matches,
struct device_d *parent);
-extern struct device_d *of_find_device_by_node(struct device_node *np);
 
 int of_device_is_stdout_path(struct device_d *dev);
 const char *of_get_model(void);
diff --git a/src/libdt.c b/src/libdt.c
index af28de6f17c6..7c24c9197c7f 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2091,6 +2091,22 @@ struct udev_of_path {
 
 static LIST_HEAD(udev_of_devices);
 
+static const char *udev_device_get_of_path(struct udev_device *dev)
+{
+   const char *of_path;
+
+   of_path = udev_device_get_property_value(dev, "OF_FULLNAME");
+   if (of_path)
+   return of_path;
+
+   if (IS_ENABLED(CONFIG_TEST_LOOPBACK) &&
+   !strcmp(udev_device_get_subsystem(dev), "block") &&
+   !strncmp(udev_device_get_sysname(dev), "loop", 4))
+   return udev_device_get_sysname(dev);
+
+   return NULL;
+}
+
 static void of_scan_udev_devices(void)
 {
struct udev *udev;
@@ -2111,6 +2127,8 @@ static void of_scan_udev_devices(void)
udev_enumerate_add_match_subsystem(enumerate, "spi");
udev_enumerate_add_match_subsystem(enumerate, "mtd");
udev_enumerate_add_match_subsystem(enumerate, "amba");
+   if (IS_ENABLED(CONFIG_TEST_LOOPBACK))
+   udev_enumerate_add_match_subsystem(enumerate, "block");
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
 
@@ -2124,7 +2142,7 @@ static void of_scan_udev_devices(void)
path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(udev, path);
 
-   of_path = udev_device_get_property_value(dev, "OF_FULLNAME");
+   of_path = udev_device_get_of_path(dev);
if (!of_path)
continue;
 
@@ -2148,11 +2166,37 @@ struct udev_device *of_find_device_by_node_path(const 
char *of_full_path)
ret = udev_of_path->udev;
break;
}
+   if (!strcmp(udev_of_path->of_path, of_full_path)) {
+   ret = udev_of_path->udev;
+   break;
+   }
}
 
return ret;
 }
 
+static struct udev_device *of_find_device_by_node(struct device_node *np)
+{
+   struct udev_of_path *udev_of_path;
+   struct udev_device *dev;
+   const char *filename;
+
+   dev = of_find_device_by_node_path(np->full_name);
+   if (dev)
+   return dev;
+
+   if (IS_ENABLED(CONFIG_TEST_LOOPBACK) &&
+   !of_property_read_string(np, "barebox,filename", ) &&
+   !strncmp(filename, "/dev/", 5)) {
+   list_for_each_entry(udev_of_path, _of_devices, list) {
+   if (!strcmp(udev_of_path->of_path, filename + 5))
+   return udev_of_path->udev;
+   }
+   }
+
+   return NULL;
+}
+
 static struct udev_device *device_find_mtd_partition(struct udev_device *dev,
const char *name)
 {
@@ -2546,7 +2590,7 @@ static int __of_cdev_find(struct device_node 

[OSS-Tools] [PATCH 2/5] state: add option to lock device node

2023-05-31 Thread Ahmad Fatoum
Even if /run exists, it may not be world-writable. This is the case on
NixOS. Add an alternative option to lock the device node instead.

This should eventually be made the default when it has enjoyed more
testing.

Signed-off-by: Ahmad Fatoum 
---
 configure.ac  |  9 +
 meson.build   |  1 +
 src/barebox-state.c   | 30 ++
 src/barebox-state/state.c |  4 
 src/barebox-state/state.h | 21 +
 5 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index be8967eb0809..117a1e169ba9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,6 +27,15 @@ AS_IF([test "x${enable_state_backward_compatibility}" = 
"xyes"], [
 AC_DEFINE(CONFIG_STATE_BACKWARD_COMPATIBLE, [0])
 ])
 
+AC_ARG_ENABLE([lock-device],
+AS_HELP_STRING([--enable-lock-device], [barebox-state: lock device 
node instead of global lock in /run @<:@default=disabled@:>@]),
+[], [enable_lock_device=no])
+AS_IF([test "x${enable_lock_device}" = "xyes"], [
+AC_DEFINE(CONFIG_LOCK_DEVICE_NODE, [1], [lock device node backing 
state.])
+], [
+AC_DEFINE(CONFIG_LOCK_DEVICE_NODE, [0], [use global lock in /run.])
+])
+
 AC_DEFINE(CONFIG_MTD, [1], [Statically define to be enabled to harmonize 
barebox' & dt-utils' code base.])
 
 AC_DEFINE(CONFIG_STATE, [1], [Statically define to be enabled to harmonize 
barebox' & dt-utils' code base.])
diff --git a/meson.build b/meson.build
index 22b522ea4d0e..2fc13f55ed62 100644
--- a/meson.build
+++ b/meson.build
@@ -20,6 +20,7 @@ conf = configuration_data()
 conf.set10('CONFIG_MTD', true)
 conf.set10('CONFIG_STATE', true)
 conf.set10('CONFIG_STATE_BACKWARD_COMPATIBLE', 
get_option('state-backward-compatibility'))
+conf.set10('CONFIG_LOCK_DEVICE_NODE', get_option('lock-device'))
 
 meson.add_dist_script(
   find_program('check-news.sh').path(),
diff --git a/src/barebox-state.c b/src/barebox-state.c
index c5acd1f7780a..7cf2fbf070a9 100644
--- a/src/barebox-state.c
+++ b/src/barebox-state.c
@@ -499,6 +499,8 @@ int main(int argc, char *argv[])
printf(PACKAGE_STRING "\n");
printf("Configured with build-time option 
'--%s-state-backward-compatibility'.\n",
   (CONFIG_STATE_BACKWARD_COMPATIBLE) ? "enable" : 
"disable");
+   printf("  
'--%s-lock-device-node'.\n",
+  (CONFIG_LOCK_DEVICE_NODE) ? "enable" : 
"disable");
exit(0);
case 'g':
sg = xzalloc(sizeof(*sg));
@@ -568,17 +570,19 @@ int main(int argc, char *argv[])
++nr_states;
}
 
-   lock_fd = open(BAREBOX_STATE_LOCKFILE, O_CREAT | O_RDWR, 0600);
-   if (lock_fd < 0) {
-   pr_err("Failed to open lock-file " BAREBOX_STATE_LOCKFILE "\n");
-   exit(1);
-   }
+   if (!IS_ENABLED(CONFIG_LOCK_DEVICE_NODE)) {
+   lock_fd = open(BAREBOX_STATE_LOCKFILE, O_CREAT | O_RDWR, 0600);
+   if (lock_fd < 0) {
+   pr_err("Failed to open lock-file " 
BAREBOX_STATE_LOCKFILE "\n");
+   exit(1);
+   }
 
-   ret = flock(lock_fd, LOCK_EX);
-   if (ret < 0) {
-   pr_err("Failed to lock " BAREBOX_STATE_LOCKFILE ": %m\n");
-   close(lock_fd);
-   exit(1);
+   ret = flock(lock_fd, LOCK_EX);
+   if (ret < 0) {
+   pr_err("Failed to lock " BAREBOX_STATE_LOCKFILE ": 
%m\n");
+   close(lock_fd);
+   exit(1);
+   }
}
 
list_for_each_entry(state, _list.list, list) {
@@ -700,8 +704,10 @@ int main(int argc, char *argv[])
 
ret = 0;
 out_unlock:
-   flock(lock_fd, LOCK_UN);
-   close(lock_fd);
+   if (!IS_ENABLED(CONFIG_LOCK_DEVICE_NODE)) {
+   flock(lock_fd, LOCK_UN);
+   close(lock_fd);
+   }
 
return ret;
 }
diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c
index 42ce88d3f161..371ae3959d6c 100644
--- a/src/barebox-state/state.c
+++ b/src/barebox-state/state.c
@@ -664,6 +664,10 @@ struct state *state_new_from_node(struct device_node 
*node, bool readonly)
pr_debug("%s: backend resolved to %s %lld %zu\n", node->full_name,
 state->backend_path, (long long)offset, size);
 
+   /* will be released on program exit */
+   if (IS_ENABLED(CONFIG_LOCK_DEVICE_NODE))
+   (void)open_exclusive(state->backend_path, readonly ? O_RDONLY : 
O_RDWR);
+
state->backend_reproducible_name = 
of_get_reproducible_name(partition_node);
 
ret = of_property_read_string(node, "backend-type", _type);
diff --git a/src/barebox-state/state.h b/src/barebox-state/state.h
index 4abfa84285c3..bbbc1892f846 100644
--- a/src/barebox-state/state.h
+++ 

[OSS-Tools] [PATCH 1/5] Add meson as build system

2023-05-31 Thread Ahmad Fatoum
This adds experimental support for building dt-utils with meson. The
hope is that the alternative meson.build will be easier to maintain.

Signed-off-by: Ahmad Fatoum 
---
 .gitignore|   1 +
 README|  20 ++
 check-news.sh |  82 
 meson.build   | 159 ++
 meson_options.txt |  25 
 version-gen   |   3 +
 version.h.in  |   3 +
 7 files changed, 293 insertions(+)
 create mode 100755 check-news.sh
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100755 version-gen
 create mode 100644 version.h.in

diff --git a/.gitignore b/.gitignore
index 5ee5535f544f..34df220d8723 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ Makefile.in
 /stamp-h1
 /tags
 /TAGS
+/build/
 
 /fdtdump
 /src/libdt-utils.pc
diff --git a/README b/README
index 46b4ea9c1508..0b4e96d6002e 100644
--- a/README
+++ b/README
@@ -13,6 +13,26 @@ For questions, feedback, patches, please send a mail to
 Note: you must be subscribed to post to this mailing list. You can do so by
 sending an empty mail to .
 
+Building from Sources
+-
+
+Check out the latest git state:
+
+git clone https://github.com/barebox/dt-utils
+cd dt-utils
+
+And then build using autotools:
+
+./autogen.sh
+./configure
+make
+
+There's also experimental support for building with meson.
+The intention is to deprecate autotools eventually in its favor. To build:
+
+meson setup build
+meson compile -C build
+
 Contributing
 
 
diff --git a/check-news.sh b/check-news.sh
new file mode 100755
index ..e7e8fa6bb95d
--- /dev/null
+++ b/check-news.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# Copyright (C) 2019 Red Hat, Inc.
+# Author: Bastien Nocera 
+#
+# This program 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  
USA.
+
+
+# Add to your top-level meson.build to check for an updated NEWS file
+# when doing a "dist" release, similarly to automake's check-news:
+# 
https://www.gnu.org/software/automake/manual/html_node/List-of-Automake-options.html
+#
+# Checks NEWS for the version number:
+# meson.add_dist_script(
+#   find_program('check-news.sh').path(),
+#   '@0@'.format(meson.project_version())
+# )
+#
+# Checks NEWS and data/foo.appdata.xml for the version number:
+# meson.add_dist_script(
+#   find_program('check-news.sh').path(),
+#   '@0@'.format(meson.project_version()),
+#   'NEWS',
+#   'data/foo.appdata.xml'
+# )
+
+usage()
+{
+   echo "$0 VERSION [FILES...]"
+   exit 1
+}
+
+check_version()
+{
+   VERSION=$1
+   # Look in the first 15 lines for NEWS files, but look
+   # everywhere for other types of files
+   if [ "$2" = "NEWS" ]; then
+   DATA=`sed 15q $SRC_ROOT/"$2"`
+   else
+   DATA=`cat $SRC_ROOT/"$2"`
+   fi
+   case "$DATA" in
+   *"$VERSION"*)
+   :
+   ;;
+   *)
+   echo "$2 not updated; not releasing" 1>&2;
+   exit 1
+   ;;
+   esac
+}
+
+SRC_ROOT=${MESON_DIST_ROOT:-"./"}
+
+if [ $# -lt 1 ] ; then usage ; fi
+
+VERSION=$1
+shift
+
+if [ $# -eq 0 ] ; then
+   check_version $VERSION 'NEWS'
+   exit 0
+fi
+
+for i in $@ ; do
+   check_version $VERSION "$i"
+done
+
+exit 0
diff --git a/meson.build b/meson.build
new file mode 100644
index ..22b522ea4d0e
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,159 @@
+# Copyright 2013-2023 The DT-Utils Authors 
+# Homepage: https://git.pengutronix.de/cgit/tools/dt-utils
+
+project(
+  'dt-utils',
+  'c',
+  version : '2021.03.0',
+  meson_version : '>=0.51',
+  default_options: [
+'c_std=gnu11',
+'warning_level=2',
+  ],
+  license : 'GPL-2.0-only',
+)
+
+cc = meson.get_compiler('c')
+
+conf = configuration_data()
+# Statically define to be enabled to harmonize barebox' & dt-utils' code base.
+conf.set10('CONFIG_MTD', true)
+conf.set10('CONFIG_STATE', true)
+conf.set10('CONFIG_STATE_BACKWARD_COMPATIBLE', 
get_option('state-backward-compatibility'))
+
+meson.add_dist_script(
+  find_program('check-news.sh').path(),
+  '@0@'.format(meson.project_version())
+)
+
+prefixdir = get_option('prefix')
+if not prefixdir.startswith('/')
+error('Prefix is not absolute: "@0@"'.format(prefixdir))
+endif
+sysconfdir = 

[OSS-Tools] [PATCH 3/5] meson: add simple integration test

2023-05-31 Thread Ahmad Fatoum
It's straight forward to use meson as test runner, so let's compile a
very simple test application that links against libdt-utils and verifies
crc32 behaves as one would expect.

Signed-off-by: Ahmad Fatoum 
---
 README   |  1 +
 meson.build  |  2 ++
 test/crc32.c | 18 ++
 test/meson.build | 26 ++
 4 files changed, 47 insertions(+)
 create mode 100644 test/crc32.c
 create mode 100644 test/meson.build

diff --git a/README b/README
index 0b4e96d6002e..528751d2cb65 100644
--- a/README
+++ b/README
@@ -32,6 +32,7 @@ The intention is to deprecate autotools eventually in its 
favor. To build:
 
 meson setup build
 meson compile -C build
+meson test -C build  # optional
 
 Contributing
 
diff --git a/meson.build b/meson.build
index 2fc13f55ed62..1bc32274af07 100644
--- a/meson.build
+++ b/meson.build
@@ -158,3 +158,5 @@ executable('dtblint',
   dependencies : [versiondep],
   link_with : libdt,
   install : true)
+
+subdir('test')
diff --git a/test/crc32.c b/test/crc32.c
new file mode 100644
index ..9a99254c8f22
--- /dev/null
+++ b/test/crc32.c
@@ -0,0 +1,18 @@
+#include 
+#include 
+
+#include 
+
+int main(void)
+{
+   const char *str = "Hello, World!";
+   uint32_t checksum;
+
+   checksum = crc32(0, str, strlen(str));
+   assert(checksum == 0xec4ac3d0);
+
+   checksum = crc32_no_comp(0, str, strlen(str));
+   assert(checksum == 0xe33e8552);
+
+   return 0;
+}
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index ..5e073547d79b
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,26 @@
+if not get_option('tests')
+  subdir_done()
+endif
+
+tests = [
+  'crc32',
+]
+
+extra_test_sources = files([
+])
+
+foreach test_name : tests
+  exe = executable(
+test_name + '-test',
+test_name + '.c',
+extra_test_sources,
+link_with : [libdt],
+include_directories : incdir)
+
+  test(
+test_name,
+exe,
+is_parallel : false,
+timeout : 240,
+workdir : meson.source_root())
+endforeach
-- 
2.39.2




[OSS-Tools] [PATCH 5/5] test: add barebox-state loop block device tests

2023-05-31 Thread Ahmad Fatoum
There's certainly more unit tests to be had, but the biggest ROI is
probably feeding barebox-state device trees and verifying that they
work. This same use case exists with RAUC too, where sharness (shell
test harness) is used to test the rauc executable. Let's import it from
there and follow the structure of the RAUC tests to do some basic
testing of barebox-state's block device handling.

The basic testing flow is:

  - mount loop devices
  - compile and supply device tree snippet describing state on
loop device to the barebox-state utility
  - barebox-state is called with verbose output to report which
device it uses
  - tests check correct device was used and basic state reading
and writing works.

Signed-off-by: Ahmad Fatoum 
---
 .gitignore|   1 +
 test/01-fixed-partition-no-gpt.dts|  34 +
 ...2-fixed-partition-before-gpt-partition.dts |  34 +
 test/03-fixed-partition-is-gpt-partition.dts  |  34 +
 test/04-gpt-partition-by-partuuid.dts |  31 +
 test/05-gpt-partition-by-typeuuid.dts |  23 +
 test/06-fixed-partition-by-diskuuid.dts   |  33 +
 test/07-raw-disk-fail.dts |  18 +
 test/08-gpt-disk-no-typeuuid-fail.dts |  18 +
 ...-partition-overlaps-two-gpt-partitions.dts |  34 +
 ...-overlaps-two-gpt-partitions-partially.dts |  34 +
 ...-fixed-partition-part-of-gpt-partition.dts |  34 +
 test/barebox-state.dtsi   |  53 ++
 test/barebox-state.t  | 229 +
 test/gpt-no-typeuuid.config   |  33 +
 test/gpt.config   |  35 +
 test/meson.build  |  10 +
 test/raw.config   |  24 +
 test/sharness.sh  | 857 ++
 19 files changed, 1569 insertions(+)
 create mode 100644 test/01-fixed-partition-no-gpt.dts
 create mode 100644 test/02-fixed-partition-before-gpt-partition.dts
 create mode 100644 test/03-fixed-partition-is-gpt-partition.dts
 create mode 100644 test/04-gpt-partition-by-partuuid.dts
 create mode 100644 test/05-gpt-partition-by-typeuuid.dts
 create mode 100644 test/06-fixed-partition-by-diskuuid.dts
 create mode 100644 test/07-raw-disk-fail.dts
 create mode 100644 test/08-gpt-disk-no-typeuuid-fail.dts
 create mode 100644 test/31-fixed-partition-overlaps-two-gpt-partitions.dts
 create mode 100644 
test/32-fixed-partition-overlaps-two-gpt-partitions-partially.dts
 create mode 100644 test/33-fixed-partition-part-of-gpt-partition.dts
 create mode 100644 test/barebox-state.dtsi
 create mode 100755 test/barebox-state.t
 create mode 100644 test/gpt-no-typeuuid.config
 create mode 100644 test/gpt.config
 create mode 100644 test/raw.config
 create mode 100755 test/sharness.sh

diff --git a/.gitignore b/.gitignore
index 34df220d8723..22060feceab3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ Makefile.in
 /tags
 /TAGS
 /build/
+/test/test-results
 
 /fdtdump
 /src/libdt-utils.pc
diff --git a/test/01-fixed-partition-no-gpt.dts 
b/test/01-fixed-partition-no-gpt.dts
new file mode 100644
index ..3ed26e3da468
--- /dev/null
+++ b/test/01-fixed-partition-no-gpt.dts
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+#include "barebox-state.dtsi"
+
+/ {
+   expected-dev = __RAW_LOOPDEV__;
+   expected-partno = <0>; /* unpartitioned space */
+   expected-offset = <0x8000>;
+   expected-size = <0x8000>;
+
+   disk: loopfile {
+   compatible = "barebox,hostfile";
+   barebox,filename = __RAW_LOOPDEV__;
+   barebox,blockdev;
+
+   partitions {
+   compatible = "fixed-partitions";
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   part_state: state@8000 {
+   reg = <0x8000 0x8000>;
+   label = "state";
+   };
+   };
+   };
+};
+
+ {
+   backend = <_state>;
+   backend-type = "raw";
+   backend-stridesize = <0x40>;
+   backend-storage-type = "direct";
+};
diff --git a/test/02-fixed-partition-before-gpt-partition.dts 
b/test/02-fixed-partition-before-gpt-partition.dts
new file mode 100644
index ..b64f910a0cad
--- /dev/null
+++ b/test/02-fixed-partition-before-gpt-partition.dts
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+#include "barebox-state.dtsi"
+
+/ {
+   expected-dev = __GPT_LOOPDEV__;
+   expected-partno = <0>; /* unpartitioned space */
+   expected-offset = <0x8000>;
+   expected-size = <0x8000>;
+
+   disk: loopfile {
+   compatible = "barebox,hostfile";
+   barebox,filename = __GPT_LOOPDEV__;
+   barebox,blockdev;
+
+   partitions {
+   compatible = "fixed-partitions";
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   

[OSS-Tools] [PATCH 0/5] Add meson support and first test suite

2023-05-31 Thread Ahmad Fatoum
The barebox,state binding is quite complex and we have a lot of udev
parsing code that can only be exercised by manually running
barebox-state on the target. Make development less error prone, by
adding tests for the block device bindings. EEPROM and MTD can
follow later.

Tests are executed by meson as a runner. Patches to teach autotools
to do the same are welcome, although I think we should follow RAUC's
steps and eventually deprecate autotools once meson is on par.

The obvious wart is that we build with -fvisibility=hidden on autotools,
but with meson the same visibility option results in linker errors.

I have no idea why yet, but that should only make meson-built
libdt-utils a bit slower without functional change.

Ahmad Fatoum (5):
  Add meson as build system
  state: add option to lock device node
  meson: add simple integration test
  libdt: add CONFIG_TEST_LOOPBACK
  test: add barebox-state loop block device tests

 .gitignore|   2 +
 README|  21 +
 check-news.sh |  82 ++
 configure.ac  |  11 +
 meson.build   | 163 
 meson_options.txt |  25 +
 src/barebox-state.c   |  30 +-
 src/barebox-state/state.c |   4 +
 src/barebox-state/state.h |  21 +
 src/dt/dt.h   |   1 -
 src/libdt.c   |  50 +-
 test/01-fixed-partition-no-gpt.dts|  34 +
 ...2-fixed-partition-before-gpt-partition.dts |  34 +
 test/03-fixed-partition-is-gpt-partition.dts  |  34 +
 test/04-gpt-partition-by-partuuid.dts |  31 +
 test/05-gpt-partition-by-typeuuid.dts |  23 +
 test/06-fixed-partition-by-diskuuid.dts   |  33 +
 test/07-raw-disk-fail.dts |  18 +
 test/08-gpt-disk-no-typeuuid-fail.dts |  18 +
 ...-partition-overlaps-two-gpt-partitions.dts |  34 +
 ...-overlaps-two-gpt-partitions-partially.dts |  34 +
 ...-fixed-partition-part-of-gpt-partition.dts |  34 +
 test/barebox-state.dtsi   |  53 ++
 test/barebox-state.t  | 229 +
 test/crc32.c  |  18 +
 test/gpt-no-typeuuid.config   |  33 +
 test/gpt.config   |  35 +
 test/meson.build  |  36 +
 test/raw.config   |  24 +
 test/sharness.sh  | 857 ++
 version-gen   |   3 +
 version.h.in  |   3 +
 32 files changed, 2012 insertions(+), 16 deletions(-)
 create mode 100755 check-news.sh
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100644 test/01-fixed-partition-no-gpt.dts
 create mode 100644 test/02-fixed-partition-before-gpt-partition.dts
 create mode 100644 test/03-fixed-partition-is-gpt-partition.dts
 create mode 100644 test/04-gpt-partition-by-partuuid.dts
 create mode 100644 test/05-gpt-partition-by-typeuuid.dts
 create mode 100644 test/06-fixed-partition-by-diskuuid.dts
 create mode 100644 test/07-raw-disk-fail.dts
 create mode 100644 test/08-gpt-disk-no-typeuuid-fail.dts
 create mode 100644 test/31-fixed-partition-overlaps-two-gpt-partitions.dts
 create mode 100644 
test/32-fixed-partition-overlaps-two-gpt-partitions-partially.dts
 create mode 100644 test/33-fixed-partition-part-of-gpt-partition.dts
 create mode 100644 test/barebox-state.dtsi
 create mode 100755 test/barebox-state.t
 create mode 100644 test/crc32.c
 create mode 100644 test/gpt-no-typeuuid.config
 create mode 100644 test/gpt.config
 create mode 100644 test/meson.build
 create mode 100644 test/raw.config
 create mode 100755 test/sharness.sh
 create mode 100755 version-gen
 create mode 100644 version.h.in

-- 
2.39.2




[OSS-Tools] [PATCH 5/8] libdt: use block device partition instead of parent if found

2023-05-31 Thread Ahmad Fatoum
Linux doesn't parse MTD fixed-partitions described in the device tree
for block devices and EEPROMs. For block devices, The dt-utils work around
this by doing the lookup in userspace and then arrive at the parent block
device along with an offset that is passed along. We can do better
though: If there's a partition block device that contains the region
we are interested in, we should just be using that.

This avoids the issue of triggering a reread of the partition table
after writing barebox state because udev is notified that we had
been opening the whole block device writable.

Tested-by: Ulrich Ölmann 
Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 60 +++--
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/src/libdt.c b/src/libdt.c
index 440fcbd32fb4..e90ac5e26273 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2212,23 +2212,29 @@ static int udev_device_parse_sysattr_u64(struct 
udev_device *dev, const char *at
return 0;
 }
 
+/* True if A completely contains B */
+static bool region_contains(loff_t starta, loff_t enda,
+   loff_t startb, loff_t endb)
+{
+return starta <= startb && enda >= endb;
+}
+
 /*
- * device_find_block_device - extract device path from udev block device
+ * cdev_from_block_device - Populate cdev from udev block device
  *
  * @dev:   the udev_device to extract information from
- * @devpath:   returns the devicepath under which the block device is 
accessible
+ * @cdev:  the cdev output parameter to populate
  *
  * returns 0 for success or negative error value on failure.
  */
-int device_find_block_device(struct udev_device *dev,
-   char **devpath)
+static int cdev_from_block_device(struct udev_device *dev,
+ struct cdev *cdev)
 {
 
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
-   struct udev_device *part;
-   const char *outpath;
+   struct udev_device *part, *best_match = NULL;
int ret;
 
udev = udev_new();
@@ -2252,19 +2258,43 @@ int device_find_block_device(struct udev_device *dev,
if (!devtype)
continue;
if (!strcmp(devtype, "disk")) {
-   outpath = udev_device_get_devnode(part);
-   *devpath = strdup(outpath);
-   ret = 0;
-   goto out;
+   best_match = part;
+
+   /* Should we try to find  a matching partition first? */
+   if (!cdev->size)
+   break;
+   } else if (cdev->size && !strcmp(devtype, "partition")) {
+   u64 partstart, partsize;
+
+   ret = udev_device_parse_sysattr_u64(part, "start", 
);
+   if (ret)
+   continue;
+
+   ret = udev_device_parse_sysattr_u64(part, "size", 
);
+   if (ret)
+   continue;
+
+   /* start/size sys attributes are always in 512-byte 
units */
+   partstart *= 512;
+   partsize *= 512;
+
+   if (!region_contains(partstart, partstart + partsize,
+cdev->offset, cdev->offset + 
cdev->size))
+   continue;
+
+   best_match = part;
+   cdev->offset -= partstart;
+   break;
}
}
-   ret = -ENODEV;
 
-out:
+   if (best_match)
+   cdev->devpath = strdup(udev_device_get_devnode(best_match));
+
udev_enumerate_unref(enumerate);
udev_unref(udev);
 
-   return ret;
+   return best_match ? 0 : -ENODEV;
 }
 
 /*
@@ -2604,10 +2634,10 @@ static int __of_cdev_find(struct device_node 
*partition_node, struct cdev *cdev)
 
return of_parse_partition(partition_node, >offset, 
>size);
} else {
-   ret = device_find_block_device(dev, >devpath);
+   ret = of_parse_partition(partition_node, >offset, 
>size);
if (ret)
return ret;
-   return of_parse_partition(partition_node, >offset, 
>size);
+   return cdev_from_block_device(dev, cdev);
}
 
return -EINVAL;
-- 
2.39.2




[OSS-Tools] [PATCH 6/8] state: align with barebox use of of_cdev_find

2023-05-31 Thread Ahmad Fatoum
As part of barebox-state by GPT partition type GUID lookup support,
state code in barebox needs direct interaction with the cdev, so it can
enumerate the child partitions. We have recently added __of_cdev_find
with internal linkage, so lets export of_cdev_find with external linkage
for outside use. Unlike __of_cdev_find, the new external function will
return dynamically allocated memory to avoid consumer code having to
know the struct cdev layout.

Signed-off-by: Ahmad Fatoum 
---
 src/barebox-state/state.c | 26 +++---
 src/dt/common.h   |  8 
 src/dt/dt.h   |  3 +++
 src/libdt-utils.sym   |  2 ++
 src/libdt.c   | 37 +
 5 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c
index 3174c84b8ded..29e04c3d7ea8 100644
--- a/src/barebox-state/state.c
+++ b/src/barebox-state/state.c
@@ -578,6 +578,20 @@ void state_release(struct state *state)
free(state);
 }
 
+#ifdef __BAREBOX__
+static char *cdev_to_devpath(struct cdev *cdev, off_t *offset, size_t *size)
+{
+   /*
+* We only accept partitions exactly mapping the barebox-state,
+* but dt-utils may need to set non-zero values here
+*/
+   *offset = 0;
+   *size = 0;
+
+   return basprintf("/dev/%s", cdev->name);
+}
+#endif
+
 /*
  * state_new_from_node - create a new state instance from a device_node
  *
@@ -594,8 +608,9 @@ struct state *state_new_from_node(struct device_node *node, 
bool readonly)
const char *alias;
uint32_t stridesize;
struct device_node *partition_node;
-   off_t offset = 0;
-   size_t size = 0;
+   struct cdev *cdev;
+   off_t offset;
+   size_t size;
 
alias = of_alias_get(node);
if (!alias) {
@@ -614,11 +629,8 @@ struct state *state_new_from_node(struct device_node 
*node, bool readonly)
goto out_release_state;
}
 
-#ifdef __BAREBOX__
-   ret = of_find_path_by_node(partition_node, >backend_path, 0);
-#else
-   ret = of_get_devicepath(partition_node, >backend_path, , 
);
-#endif
+   cdev = of_cdev_find(partition_node);
+   ret = PTR_ERR_OR_ZERO(cdev);
if (ret) {
if (ret != -EPROBE_DEFER)
dev_err(>dev, "state failed to parse path to 
backend: %s\n",
diff --git a/src/dt/common.h b/src/dt/common.h
index d16f1193fbe3..38dc61cd65fe 100644
--- a/src/dt/common.h
+++ b/src/dt/common.h
@@ -166,6 +166,14 @@ static inline void *ERR_CAST(const void *ptr)
return (void *) ptr;
 }
 
+static inline int PTR_ERR_OR_ZERO(const void *ptr)
+{
+   if (IS_ERR(ptr))
+   return PTR_ERR(ptr);
+   else
+   return 0;
+}
+
 static inline char *barebox_asprintf(const char *fmt, ...) __attribute__ 
((format(__printf__, 1, 2)));
 static inline char *barebox_asprintf(const char *fmt, ...)
 {
diff --git a/src/dt/dt.h b/src/dt/dt.h
index d5e49eb32df9..f8bd3e56efed 100644
--- a/src/dt/dt.h
+++ b/src/dt/dt.h
@@ -231,6 +231,9 @@ void of_add_memory_bank(struct device_node *node, bool 
dump, int r,
 int of_get_devicepath(struct device_node *partition_node, char **devnode, 
off_t *offset,
size_t *size);
 
+struct cdev *of_cdev_find(struct device_node *partition_node);
+char *cdev_to_devpath(struct cdev *cdev, off_t *offset, size_t *size);
+
 #define for_each_node_by_name(dn, name) \
for (dn = of_find_node_by_name(NULL, name); dn; \
 dn = of_find_node_by_name(dn, name))
diff --git a/src/libdt-utils.sym b/src/libdt-utils.sym
index a749317fa024..f95c74305fb0 100644
--- a/src/libdt-utils.sym
+++ b/src/libdt-utils.sym
@@ -34,6 +34,8 @@ global:
of_get_child_by_name;
of_get_child_count;
of_get_devicepath;
+   of_cdev_find;
+   cdev_to_devpath;
of_get_next_available_child;
of_get_parent;
of_get_property;
diff --git a/src/libdt.c b/src/libdt.c
index e90ac5e26273..1cfca40f9f79 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2677,3 +2677,40 @@ int of_get_devicepath(struct device_node 
*partition_node, char **devpath, off_t
 
return 0;
 }
+
+/*
+ * of_cdev_find - get information how to access device corresponding to a 
device_node
+ * @partition_node:The device_node which shall be accessed
+ * @devpath:   Returns the devicepath under which the device is 
accessible
+ * @offset:Returns the offset in the device
+ * @size:  Returns the size of the device
+ *
+ * This function takes a device_node which represents a partition.
+ * For this partition the function returns the device path and the offset
+ * and size in the device. For mtd devices the path will be /dev/mtdx, for
+ * EEPROMs it will be /sys/.../eeprom and for block devices it will be /dev/...
+ * For mtd devices the device path returned will be the partition itself.
+ * Since EEPROMs do not have partitions under 

[OSS-Tools] [PATCH 2/8] libdt: factor out u64 sysattr parsing into helper

2023-05-31 Thread Ahmad Fatoum
We will need to parse two more sysattrs in a follow-up patch, so factor
this out for reuse. While at it switch to 64-bit strtoull: This may
be more useful for future users and unlike atol doesn't invoke undefined
behavior when parsing fails.

Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 42 +++---
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/libdt.c b/src/libdt.c
index 2c994c647ac9..580b0b0ba769 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2179,6 +2179,33 @@ static struct udev_device 
*device_find_mtd_partition(struct udev_device *dev,
return NULL;
 }
 
+/*
+ * udev_device_parse_sysattr_u64 - parse sysattr value as unsigned 64-bit 
integer
+ * @dev:   the udev_device to extract the attribute from
+ * @attr:  name of the attribute to lookup
+ * @outvalue:  returns the value parsed out of the attribute
+ *
+ * returns 0 for success or negative error value on failure.
+ */
+static int udev_device_parse_sysattr_u64(struct udev_device *dev, const char 
*attr,
+   u64 *outvalue)
+{
+   char *endptr;
+   u64 value;
+   const char *str;
+
+   str = udev_device_get_sysattr_value(dev, attr);
+   if (!str)
+   return -EINVAL;
+
+   value = strtoull(str, , 0);
+   if (!*str || *endptr)
+   return -EINVAL;
+
+   *outvalue = value;
+   return 0;
+}
+
 /*
  * device_find_block_device - extract device path from udev block device
  *
@@ -2305,24 +2332,25 @@ static int udev_device_is_eeprom(struct udev_device 
*dev)
  * udev_parse_mtd - get information from a mtd udev_device
  * @dev:   the udev_device to extract information from
  * @devpath:   returns the devicepath under which the mtd device is accessible
- * @size:  returns the size of the mtd device
+ * @outsize:   returns the size of the mtd device
  *
  * returns 0 for success or negative error value on failure. *devpath
  * will be valid on success and must be freed after usage.
  */
-static int udev_parse_mtd(struct udev_device *dev, char **devpath, size_t 
*size)
+static int udev_parse_mtd(struct udev_device *dev, char **devpath, size_t 
*outsize)
 {
-   const char *sizestr;
const char *outpath;
+   u64 size;
+   int ret;
 
if (!udev_device_is_mtd(dev))
return -EINVAL;
 
-   sizestr = udev_device_get_sysattr_value(dev, "size");
-   if (!sizestr)
-   return -EINVAL;
+   ret = udev_device_parse_sysattr_u64(dev, "size", );
+   if (ret)
+   return ret;
 
-   *size = atol(sizestr);
+   *outsize = size;
 
outpath = udev_device_get_devnode(dev);
if (!outpath)
-- 
2.39.2




[OSS-Tools] [PATCH 0/8] state: allow lookup of barebox state partition by Type GUID

2023-05-31 Thread Ahmad Fatoum
This implements the binding extension introduced to barebox here:
https://lore.barebox.org/barebox/20230531145927.1399282-1-a.fat...@pengutronix.de/T/#t

With this, barebox,state backend can optionally point at a device
instead of a partition. If this device is GPT-partitioned and has
a partition with a specific partition type GUID of

  4778ed65-bf42-45fa-9c5b-287a1dc4aab1

It will be taken.

This series also fixes an annoying issue of barebox-state triggering
udev on every access, because the root block device corresponding
to the device tree node was opened r/w.

barebox-state will now open the disk read-only if possible and if
a partition exists that fits the barebox state location, it will
be opened instead.

Ahmad Fatoum (8):
  state: backend: direct: open block device in read-only mode if
possible
  libdt: factor out u64 sysattr parsing into helper
  libdt: drop broken if-branch
  libdt: factor out __of_cdev_find helper
  libdt: use block device partition instead of parent if found
  state: align with barebox use of of_cdev_find
  libdt: use of_find_device_by_uuid for partuuid lookup
  state: allow lookup of barebox state partition by Type GUID

 src/barebox-state/backend_bucket_direct.c |   5 +-
 src/barebox-state/backend_storage.c   |   2 +-
 src/barebox-state/state.c |  58 +++-
 src/barebox-state/state.h |   3 +-
 src/dt/common.h   |   8 +
 src/dt/dt.h   |   8 +
 src/libdt-utils.sym   |   5 +
 src/libdt.c   | 341 ++
 src/linux/uuid.h  |  24 ++
 src/state.h   |   4 +
 10 files changed, 380 insertions(+), 78 deletions(-)
 create mode 100644 src/linux/uuid.h

-- 
2.39.2




[OSS-Tools] [PATCH 8/8] state: allow lookup of barebox state partition by Type GUID

2023-05-31 Thread Ahmad Fatoum
The backend device tree property so far always pointed at a partition.
Let's allow pointing it at GPT storage devices directly and lookup
the correct barebox state partition by the well-known type GUID:

  4778ed65-bf42-45fa-9c5b-287a1dc4aab1

The implementation is not as neat as hoped for, because lifetime for
barebox cdev and libudev udev_device are quite different and libdt
doesn't yet get the latter right. Once we make sure not to leak
libudev objects and add cdev_unref stubs to barebox, this can be
further simplified by sticking the struct udev_device into struct
cdev and determining extra information on demand.

Signed-off-by: Ahmad Fatoum 
---
 src/barebox-state/state.c |  26 ++
 src/dt/dt.h   |   5 ++
 src/libdt-utils.sym   |   3 ++
 src/libdt.c   | 101 --
 src/linux/uuid.h  |  24 +
 src/state.h   |   4 ++
 6 files changed, 160 insertions(+), 3 deletions(-)
 create mode 100644 src/linux/uuid.h

diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c
index 29e04c3d7ea8..42ce88d3f161 100644
--- a/src/barebox-state/state.c
+++ b/src/barebox-state/state.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -592,6 +593,8 @@ static char *cdev_to_devpath(struct cdev *cdev, off_t 
*offset, size_t *size)
 }
 #endif
 
+static guid_t barebox_state_partition_guid = BAREBOX_STATE_PARTITION_GUID;
+
 /*
  * state_new_from_node - create a new state instance from a device_node
  *
@@ -638,6 +641,29 @@ struct state *state_new_from_node(struct device_node 
*node, bool readonly)
goto out_release_state;
}
 
+   /* Is the backend referencing an on-disk partitonable block device? */
+   if (cdev_is_block_disk(cdev)) {
+   struct cdev *partcdev = NULL;
+
+   if (cdev_is_gpt_partitioned(cdev))
+   partcdev = cdev_find_child_by_typeuuid(cdev, 
_state_partition_guid);
+
+   if (!partcdev) {
+   ret = -EINVAL;
+   goto out_release_state;
+   }
+
+   pr_debug("%s: backend GPT partition looked up via 
PartitionTypeGUID\n",
+node->full_name);
+
+   cdev = partcdev;
+   }
+
+   state->backend_path = cdev_to_devpath(cdev, , );
+
+   pr_debug("%s: backend resolved to %s %lld %zu\n", node->full_name,
+state->backend_path, (long long)offset, size);
+
state->backend_reproducible_name = 
of_get_reproducible_name(partition_node);
 
ret = of_property_read_string(node, "backend-type", _type);
diff --git a/src/dt/dt.h b/src/dt/dt.h
index f8bd3e56efed..a4213d49606a 100644
--- a/src/dt/dt.h
+++ b/src/dt/dt.h
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Default string compare functions */
 #define of_compat_cmp(s1, s2, l)   strcasecmp((s1), (s2))
@@ -234,6 +235,10 @@ int of_get_devicepath(struct device_node *partition_node, 
char **devnode, off_t
 struct cdev *of_cdev_find(struct device_node *partition_node);
 char *cdev_to_devpath(struct cdev *cdev, off_t *offset, size_t *size);
 
+bool cdev_is_block_disk(struct cdev *cdev);
+bool cdev_is_gpt_partitioned(struct cdev *cdev);
+struct cdev *cdev_find_child_by_typeuuid(struct cdev *cdev, guid_t *typeuuid);
+
 #define for_each_node_by_name(dn, name) \
for (dn = of_find_node_by_name(NULL, name); dn; \
 dn = of_find_node_by_name(dn, name))
diff --git a/src/libdt-utils.sym b/src/libdt-utils.sym
index f95c74305fb0..63536224e518 100644
--- a/src/libdt-utils.sym
+++ b/src/libdt-utils.sym
@@ -36,6 +36,9 @@ global:
of_get_devicepath;
of_cdev_find;
cdev_to_devpath;
+   cdev_is_block_disk;
+   cdev_is_gpt_partitioned;
+   cdev_find_child_by_typeuuid;
of_get_next_available_child;
of_get_parent;
of_get_property;
diff --git a/src/libdt.c b/src/libdt.c
index 4c000919d305..af28de6f17c6 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -30,12 +30,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct cdev {
char *devpath;
off_t offset;
size_t size;
+   bool is_gpt_partitioned;
+   bool is_block_disk;
 };
 
 static int pr_level = 5;
@@ -2230,7 +2233,7 @@ static bool region_contains(loff_t starta, loff_t enda,
 static int cdev_from_block_device(struct udev_device *dev,
  struct cdev *cdev)
 {
-
+   const char *devtype;
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
@@ -2250,7 +2253,7 @@ static int cdev_from_block_device(struct udev_device *dev,
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(dev_list_entry, devices) {
-   const char *path, *devtype;
+   const char 

[OSS-Tools] [PATCH 4/8] libdt: factor out __of_cdev_find helper

2023-05-31 Thread Ahmad Fatoum
of_get_devicepath is an exported symbol by libdt, so we shouldn't change
its signature or its semantics. Yet, we will want to export more
information out of the udev'ification code in future.  already
declares an opaque struct cdev, so let's add a __of_cdev_find helper
that can populate it with the same information that of_get_devicepath
would return. In later commits we will define helpers that return
and process a struct cdev placed in dynamic memory.

Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 82 +
 1 file changed, 52 insertions(+), 30 deletions(-)

diff --git a/src/libdt.c b/src/libdt.c
index 12d692d2b2cf..440fcbd32fb4 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -32,6 +32,12 @@
 #include 
 #include 
 
+struct cdev {
+   char *devpath;
+   off_t offset;
+   size_t size;
+};
+
 static int pr_level = 5;
 
 void pr_level_set(int level)
@@ -2482,33 +2488,14 @@ static struct udev_device 
*of_find_device_by_uuid(struct udev_device *parent,
return NULL;
 }
 
-/*
- * of_get_devicepath - get information how to access device corresponding to a 
device_node
- * @partition_node:The device_node which shall be accessed
- * @devpath:   Returns the devicepath under which the device is 
accessible
- * @offset:Returns the offset in the device
- * @size:  Returns the size of the device
- *
- * This function takes a device_node which represents a partition.
- * For this partition the function returns the device path and the offset
- * and size in the device. For mtd devices the path will be /dev/mtdx, for
- * EEPROMs it will be /sys/.../eeprom and for block devices it will be /dev/...
- * For mtd devices the device path returned will be the partition itself.
- * Since EEPROMs do not have partitions under Linux @offset and @size will
- * describe the offset and size inside the full device. The same applies to
- * block devices.
- *
- * returns 0 for success or negative error value on failure.
- */
-int of_get_devicepath(struct device_node *partition_node, char **devpath, 
off_t *offset,
-   size_t *size)
+static int __of_cdev_find(struct device_node *partition_node, struct cdev 
*cdev)
 {
struct device_node *node;
struct udev_device *dev, *partdev, *mtd;
int ret;
 
-   *offset = 0;
-   *size = 0;
+   cdev->offset = 0;
+   cdev->size = 0;
 
/*
 * simplest case: This nodepath can directly be translated into
@@ -2520,8 +2507,8 @@ int of_get_devicepath(struct device_node *partition_node, 
char **devpath, off_t
dev = of_find_device_by_node_path(partition_node->full_name);
if (dev) {
if (udev_device_is_eeprom(dev))
-   return udev_parse_eeprom(dev, devpath);
-   if (!udev_parse_mtd(dev, devpath, size))
+   return udev_parse_eeprom(dev, >devpath);
+   if (!udev_parse_mtd(dev, >devpath, >size))
return 0;
 
/*
@@ -2551,7 +2538,7 @@ int of_get_devicepath(struct device_node *partition_node, 
char **devpath, off_t
while (*uuid)
*s++ = tolower(*uuid++);
 
-   *devpath = lc_uuid;
+   cdev->devpath = lc_uuid;
 
return 0;
}
@@ -2607,21 +2594,56 @@ int of_get_devicepath(struct device_node 
*partition_node, char **devpath, off_t
return -ENODEV;
 
/* ...find the desired information by mtd udev_device */
-   return udev_parse_mtd(partdev, devpath, size);
+   return udev_parse_mtd(partdev, >devpath, >size);
}
 
if (udev_device_is_eeprom(dev)) {
-   ret = udev_parse_eeprom(dev, devpath);
+   ret = udev_parse_eeprom(dev, >devpath);
if (ret)
return ret;
 
-   return of_parse_partition(partition_node, offset, size);
+   return of_parse_partition(partition_node, >offset, 
>size);
} else {
-   ret = device_find_block_device(dev, devpath);
+   ret = device_find_block_device(dev, >devpath);
if (ret)
return ret;
-   return of_parse_partition(partition_node, offset, size);
+   return of_parse_partition(partition_node, >offset, 
>size);
}
 
return -EINVAL;
 }
+
+/*
+ * of_get_devicepath - get information how to access device corresponding to a 
device_node
+ * @partition_node:The device_node which shall be accessed
+ * @devpath:   Returns the devicepath under which the device is 
accessible
+ * @offset:Returns the offset in the device
+ * @size:  Returns the size of the device
+ *
+ * This function takes a device_node which represents a partition.
+ * For this partition the function returns the 

[OSS-Tools] [PATCH 1/8] state: backend: direct: open block device in read-only mode if possible

2023-05-31 Thread Ahmad Fatoum
We unconditionally open the device backing a direct bucket in read-write
mode. The barebox_state utility already populates struct
state_backend_storage::readonly though, which we could consult at device
open time. Do so. This could possibly be done for MTD as well, but until
that's tested, for now, we do it only for the direct backend meant for
use with block devices.

Tested-by: Ulrich Ölmann 
Signed-off-by: Ahmad Fatoum 
---
 src/barebox-state/backend_bucket_direct.c | 5 +++--
 src/barebox-state/backend_storage.c   | 2 +-
 src/barebox-state/state.c | 6 +++---
 src/barebox-state/state.h | 3 ++-
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/barebox-state/backend_bucket_direct.c 
b/src/barebox-state/backend_bucket_direct.c
index 4522f0170f3d..48c1596c9add 100644
--- a/src/barebox-state/backend_bucket_direct.c
+++ b/src/barebox-state/backend_bucket_direct.c
@@ -164,12 +164,13 @@ static void state_backend_bucket_direct_free(struct
 
 int state_backend_bucket_direct_create(struct device_d *dev, const char *path,
   struct state_backend_storage_bucket 
**bucket,
-  off_t offset, ssize_t max_size)
+  off_t offset, ssize_t max_size,
+  bool readonly)
 {
int fd;
struct state_backend_storage_bucket_direct *direct;
 
-   fd = open(path, O_RDWR);
+   fd = open(path, readonly ? O_RDONLY : O_RDWR);
if (fd < 0) {
dev_err(dev, "Failed to open file '%s', %d\n", path, -errno);
return -errno;
diff --git a/src/barebox-state/backend_storage.c 
b/src/barebox-state/backend_storage.c
index 458f2a91552b..4c5e1783c199 100644
--- a/src/barebox-state/backend_storage.c
+++ b/src/barebox-state/backend_storage.c
@@ -326,7 +326,7 @@ static int state_storage_file_buckets_init(struct 
state_backend_storage *storage
offset = storage->offset + n * stridesize;
ret = state_backend_bucket_direct_create(storage->dev, 
storage->path,
 , offset,
-stridesize);
+stridesize, 
storage->readonly);
if (ret) {
dev_warn(storage->dev, "Failed to create direct bucket 
at '%s' offset %lld\n",
 storage->path, (long long) offset);
diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c
index 4779574d2ee9..3174c84b8ded 100644
--- a/src/barebox-state/state.c
+++ b/src/barebox-state/state.c
@@ -649,14 +649,14 @@ struct state *state_new_from_node(struct device_node 
*node, bool readonly)
if (ret)
goto out_release_state;
 
+   if (readonly)
+   state_backend_set_readonly(state);
+
ret = state_storage_init(state, state->backend_path, offset,
 size, stridesize, storage_type);
if (ret)
goto out_release_state;
 
-   if (readonly)
-   state_backend_set_readonly(state);
-
ret = state_from_node(state, node, 1);
if (ret) {
goto out_release_state;
diff --git a/src/barebox-state/state.h b/src/barebox-state/state.h
index 719f7e43c94c..4abfa84285c3 100644
--- a/src/barebox-state/state.h
+++ b/src/barebox-state/state.h
@@ -225,7 +225,8 @@ void state_backend_set_readonly(struct state *state);
 void state_storage_free(struct state_backend_storage *storage);
 int state_backend_bucket_direct_create(struct device_d *dev, const char *path,
   struct state_backend_storage_bucket 
**bucket,
-  off_t offset, ssize_t max_size);
+  off_t offset, ssize_t max_size,
+  bool readonly);
 int state_storage_write(struct state_backend_storage *storage,
const void * buf, ssize_t len);
 int state_storage_read(struct state_backend_storage *storage,
-- 
2.39.2




[OSS-Tools] [PATCH 7/8] libdt: use of_find_device_by_uuid for partuuid lookup

2023-05-31 Thread Ahmad Fatoum
With the addition of of_find_device_by_uuid as part of the support for
barebox,storage-by-uuid, we don't need to rely on the device symlinks
created by 60-persistent-storage.rules and instead can just use libudev
directly, which we do elsewhere anyway. This has the added benefit
that we unify with the other code paths, where we determine the device
path through the struct udev_device.

Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/src/libdt.c b/src/libdt.c
index 1cfca40f9f79..4c000919d305 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2558,18 +2558,22 @@ static int __of_cdev_find(struct device_node 
*partition_node, struct cdev *cdev)
/* when partuuid is specified short-circuit the search for the 
cdev */
ret = of_property_read_string(partition_node, "partuuid", 
);
if (!ret) {
-   const char prefix[] = "/dev/disk/by-partuuid/";
-   size_t prefix_len = sizeof(prefix) - 1;
-   char *lc_uuid, *s;
+   u64 partsize;
+   int ret;
 
-   lc_uuid = xzalloc(prefix_len + strlen(uuid) + 1);
-   s = memcpy(lc_uuid, prefix, prefix_len) + prefix_len;
+   dev = of_find_device_by_uuid(NULL, uuid, false);
+   if (!dev) {
+   fprintf(stderr, "%s: cannot find device for 
uuid %s\n", __func__,
+   uuid);
+   return -ENODEV;
+   }
 
-   while (*uuid)
-   *s++ = tolower(*uuid++);
-
-   cdev->devpath = lc_uuid;
+   ret = udev_device_parse_sysattr_u64(dev, "size", 
);
+   if (ret)
+   return -EINVAL;
 
+   cdev->size = partsize * 512;
+   cdev->devpath = strdup(udev_device_get_devnode(dev));
return 0;
}
}
-- 
2.39.2




[OSS-Tools] [PATCH 3/8] libdt: drop broken if-branch

2023-05-31 Thread Ahmad Fatoum
device_find_block_device returns 0 on success, so the way the else if
clause is now, only if there is a block device, the code falls through.
If there is none, a 0 is returned, but devpath is not populated breaking
the contract of the function. Just drop the branch for now and add back
it later in a way that works.

Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/libdt.c b/src/libdt.c
index 580b0b0ba769..12d692d2b2cf 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2519,13 +2519,10 @@ int of_get_devicepath(struct device_node 
*partition_node, char **devpath, off_t
 */
dev = of_find_device_by_node_path(partition_node->full_name);
if (dev) {
-   if (udev_device_is_eeprom(dev)) {
+   if (udev_device_is_eeprom(dev))
return udev_parse_eeprom(dev, devpath);
-   } else if (!udev_parse_mtd(dev, devpath, size)) {
+   if (!udev_parse_mtd(dev, devpath, size))
return 0;
-   } else if (device_find_block_device(dev, devpath)) {
-   return of_parse_partition(partition_node, offset, size);
-   }
 
/*
 * If we found a device but couldn't classify it above, we fall
-- 
2.39.2




Re: [OSS-Tools] [PATCH v4 2/3] libdt: add support for barebox, storage-by-uuid

2023-05-31 Thread Ahmad Fatoum
Hello Michael,

On 11.05.22 10:21, Michael Olbrich wrote:
> Signed-off-by: Michael Olbrich 

Tested-by: Ahmad Fatoum 

I'd squash the two fixups I just sent when I apply this.

Thanks,
Ahmad

> ---
> 
> changes in v3:
> uuid comparison fixed:
>  - compare the correct uuids
>  - don't crash when no uuid is present
> 
> changes in v4:
> use strcasecmp() to make the uuid check case insensitive.
> 
>  src/libdt.c | 74 +
>  1 file changed, 69 insertions(+), 5 deletions(-)
> 
> diff --git a/src/libdt.c b/src/libdt.c
> index 48c31931e8a1..4076d9a2f4a3 100644
> --- a/src/libdt.c
> +++ b/src/libdt.c
> @@ -2358,6 +2358,52 @@ out:
>   return dev;
>  }
>  
> +static struct udev_device *of_find_device_by_uuid(const char *uuid)
> +{
> + struct udev *udev;
> + struct udev_enumerate *enumerate;
> + struct udev_list_entry *devices, *dev_list_entry;
> + int ret = 0;
> +
> + udev = udev_new();
> + if (!udev) {
> +   fprintf(stderr, "Can't create udev\n");
> +   return NULL;
> + }
> +
> + enumerate = udev_enumerate_new(udev);
> + udev_enumerate_add_match_subsystem(enumerate, "block");
> + udev_enumerate_scan_devices(enumerate);
> + devices = udev_enumerate_get_list_entry(enumerate);
> + udev_list_entry_foreach(dev_list_entry, devices) {
> + const char *path, *devtype, *outpath, *dev_uuid;
> + struct udev_device *device;
> +
> + path = udev_list_entry_get_name(dev_list_entry);
> + device = udev_device_new_from_syspath(udev, path);
> +
> + /* distinguish device (disk) from partitions */
> + devtype = udev_device_get_devtype(device);
> + if (!devtype)
> + continue;
> + if (!strcmp(devtype, "disk")) {
> + dev_uuid = udev_device_get_property_value(device, 
> "ID_PART_TABLE_UUID");
> + if (dev_uuid && !strcasecmp(dev_uuid, uuid)) {
> + outpath = udev_device_get_devnode(device);
> + return device;
> + }
> + } else if (!strcmp(devtype, "partition")) {
> + dev_uuid = udev_device_get_property_value(device, 
> "ID_PART_ENTRY_UUID");
> + if (dev_uuid && !strcasecmp(dev_uuid, uuid)) {
> + outpath = udev_device_get_devnode(device);
> + return device;
> + }
> + }
> +
> + }
> + return NULL;
> +}
> +
>  /*
>   * of_get_devicepath - get information how to access device corresponding to 
> a device_node
>   * @partition_node:  The device_node which shall be accessed
> @@ -2443,11 +2489,29 @@ int of_get_devicepath(struct device_node 
> *partition_node, char **devpath, off_t
>   if (!strcmp(node->name, "partitions"))
>   node = node->parent;
>  
> - dev = of_find_device_by_node_path(node->full_name);
> - if (!dev) {
> - fprintf(stderr, "%s: cannot find device from node %s\n", 
> __func__,
> - node->full_name);
> - return -ENODEV;
> + if (of_device_is_compatible(node, "barebox,storage-by-uuid")) {
> + const char *uuid;
> +
> + ret = of_property_read_string(node, "uuid", );
> + if (ret) {
> + fprintf(stderr, "%s: missing uuid property for %s\n", 
> __func__,
> + node->full_name);
> + return -ENODEV;
> + }
> + dev = of_find_device_by_uuid(uuid);
> + if (!dev) {
> + fprintf(stderr, "%s: cannot find device for uuid %s\n", 
> __func__,
> + uuid);
> + return -ENODEV;
> + }
> + }
> + else {
> + dev = of_find_device_by_node_path(node->full_name);
> + if (!dev) {
> + fprintf(stderr, "%s: cannot find device from node 
> %s\n", __func__,
> + node->full_name);
> + return -ENODEV;
> + }
>   }
>  
>   mtd = of_find_mtd_device(dev);

-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |




[OSS-Tools] [PATCH fixup 2/2] libdt: fix possible use of uninitialized variable

2023-05-31 Thread Ahmad Fatoum
property may not be always defined. So let's skip trying to do something
with it in that case.

Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/libdt.c b/src/libdt.c
index 302ca7a76375..ca0502ac9483 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2397,6 +2397,8 @@ static struct udev_device *of_find_device_by_uuid(struct 
udev_device *parent,
property = "ID_PART_TABLE_UUID";
else if (!strcmp(devtype, "partition"))
property = "ID_PART_ENTRY_UUID";
+   else
+   continue;
 
dev_uuid = udev_device_get_property_value(device, property);
if (dev_uuid && !strcasecmp(dev_uuid, uuid))
-- 
2.39.2




[OSS-Tools] [PATCH fixup 1/2] libdt: remove ultimately unused variables

2023-05-31 Thread Ahmad Fatoum
These variables were recently added, but are unused. Drop them.

Signed-off-by: Ahmad Fatoum 
---
 src/libdt.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/libdt.c b/src/libdt.c
index 44491a5e739b..302ca7a76375 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -2365,7 +2365,6 @@ static struct udev_device *of_find_device_by_uuid(struct 
udev_device *parent,
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
-   int ret = 0;
 
udev = udev_new();
if (!udev) {
@@ -2380,7 +2379,7 @@ static struct udev_device *of_find_device_by_uuid(struct 
udev_device *parent,
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(dev_list_entry, devices) {
-   const char *path, *devtype, *outpath, *dev_uuid;
+   const char *path, *devtype, *dev_uuid;
struct udev_device *device;
const char *property;
 
@@ -2400,10 +2399,8 @@ static struct udev_device *of_find_device_by_uuid(struct 
udev_device *parent,
property = "ID_PART_ENTRY_UUID";
 
dev_uuid = udev_device_get_property_value(device, property);
-   if (dev_uuid && !strcasecmp(dev_uuid, uuid)) {
-   outpath = udev_device_get_devnode(device);
+   if (dev_uuid && !strcasecmp(dev_uuid, uuid))
return device;
-   }
}
return NULL;
 }
-- 
2.39.2




[OSS-Tools] [PATCH 3/5] libdt: use memcpy instead of strncpy

2023-05-31 Thread Ahmad Fatoum
Despite the name, GCC objects at the strncpy use in safe_strncpy on
safety grounds.  While that seems to be a false positive, we could
just be using memcpy instead and side step this altogether.

Signed-off-by: Ahmad Fatoum 
---
 src/dt/common.h | 34 ++
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/src/dt/common.h b/src/dt/common.h
index c3c4f53fc216..69a264cfc1a9 100644
--- a/src/dt/common.h
+++ b/src/dt/common.h
@@ -36,6 +36,12 @@ typedef uint64_t u64;
 #undef offsetof
 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 
+#define min(x, y) ({   \
+   typeof(x) _min1 = (x);  \
+   typeof(y) _min2 = (y);  \
+   (void) (&_min1 == &_min2);  \
+   _min1 < _min2 ? _min1 : _min2; })
+
 struct device_d;
 
 void pr_level_set(int level);
@@ -199,14 +205,6 @@ static inline size_t DT_strlcpy(char *dest, const char 
*src, size_t size)
return ret;
 }
 
-/* Like strncpy but make sure the resulting string is always 0 terminated. */
-static inline char * safe_strncpy(char *dst, const char *src, size_t size)
-{
-   if (!size) return dst;
-   dst[--size] = '\0';
-   return strncpy(dst, src, size);
-}
-
 static inline char *xstrdup(const char *s)
 {
char *p = strdup(s);
@@ -415,21 +413,23 @@ static inline int dev_set_name(struct device_d *dev, 
const char *fmt, ...)
 {
char newname[MAX_DRIVER_NAME];
va_list vargs;
-   int err;
+   int ret;
 
va_start(vargs, fmt);
-   err = vsnprintf(newname, MAX_DRIVER_NAME, fmt, vargs);
+   ret = vsnprintf(newname, MAX_DRIVER_NAME, fmt, vargs);
va_end(vargs);
 
+   if (WARN_ON(ret < 0))
+   return ret;
+
/*
 * Copy new name into dev structure, we do this after vsnprintf call in
 * case old device name was in one of vargs
 */
-   safe_strncpy(dev->name, newname, MAX_DRIVER_NAME);
+   memcpy(dev->name, newname, min(MAX_DRIVER_NAME - 1, ret));
+   dev->name[MAX_DRIVER_NAME - 1] = '\0';
 
-   WARN_ON(err < 0);
-
-   return err;
+   return 0;
 }
 
 struct driver_d;
@@ -577,12 +577,6 @@ static inline __u32 ror32(__u32 word, unsigned int shift)
return (word >> shift) | (word << (32 - shift));
 }
 
-#define min(x, y) ({   \
-   typeof(x) _min1 = (x);  \
-   typeof(y) _min2 = (y);  \
-   (void) (&_min1 == &_min2);  \
-   _min1 < _min2 ? _min1 : _min2; })
-
 /*
  * Helper macros to use CONFIG_ options in C expressions. Note that
  * these only work with boolean and tristate options.
-- 
2.39.2




[OSS-Tools] [PATCH 4/5] libdt: don't use old-style function definition

2023-05-31 Thread Ahmad Fatoum
Increasing the warning level has GCC warn us, so let's heed the warning.

Signed-off-by: Ahmad Fatoum 
---
 src/dt/common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/dt/common.h b/src/dt/common.h
index 69a264cfc1a9..62776c0bb027 100644
--- a/src/dt/common.h
+++ b/src/dt/common.h
@@ -460,7 +460,7 @@ static inline int of_unregister_fixup(int (*fixup)(struct 
device_node *, void *)
 }
 
 #define __define_initcall(level,fn,id) \
-static void __attribute__ ((constructor)) __initcall_##id##_##fn() { \
+static void __attribute__ ((constructor)) __initcall_##id##_##fn(void) { \
fn(); \
 }
 
-- 
2.39.2




[OSS-Tools] [PATCH 1/5] configure: pass -fno-strict-aliasing to GCC

2023-05-31 Thread Ahmad Fatoum
Like the Linux kernel, barebox is built with -fno-strict-aliasing, and
code is written to take advantage of that. As dt-utils imports code from
barebox, we may import code that assumes aliasing to be non-strict, so
we better compile it with the same rules.

Signed-off-by: Ahmad Fatoum 
---
 configure.ac | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 00c80105e467..be8967eb0809 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,8 @@ my_CFLAGS="-Wall \
 -Wmissing-declarations -Wmissing-prototypes \
 -Wnested-externs -Wsign-compare -Wchar-subscripts \
 -Wstrict-prototypes -Wshadow \
--Wformat-security -Wtype-limits"
+-Wformat-security -Wtype-limits \
+-fno-strict-aliasing"
 AC_SUBST([my_CFLAGS])
 
 PKG_CHECK_MODULES(UDEV, [libudev])
-- 
2.39.2




[OSS-Tools] [PATCH 2/5] libdt: fix issues of external function without prototype

2023-05-31 Thread Ahmad Fatoum
When increasing warning level, we see that of_find_device_by_node_path
lacks a prototype despite having external linkage and being exported
in the symbols file. On the other hand, scan_proc_dir has external
linkage, but is only ever needed internally, so let's give it internal
linkage.

Signed-off-by: Ahmad Fatoum 
---
 src/crc32.c | 1 +
 src/dt/dt.h | 1 +
 src/libdt.c | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/crc32.c b/src/crc32.c
index 8d4dddcf6129..8273d3465f6f 100644
--- a/src/crc32.c
+++ b/src/crc32.c
@@ -8,6 +8,7 @@
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
+#include 
 #include 
 
 /* 
diff --git a/src/dt/dt.h b/src/dt/dt.h
index 4ae24ba8bf7a..6ce95d91da87 100644
--- a/src/dt/dt.h
+++ b/src/dt/dt.h
@@ -121,6 +121,7 @@ extern struct device_node *of_find_node_by_type(struct 
device_node *from,
const char *type);
 extern struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);
+extern struct udev_device *of_find_device_by_node_path(const char 
*of_full_path);
 extern const struct of_device_id *of_match_node(
const struct of_device_id *matches, const struct device_node *node);
 extern struct device_node *of_find_matching_node_and_match(
diff --git a/src/libdt.c b/src/libdt.c
index 59e76d336d8d..a833c582dfbf 100644
--- a/src/libdt.c
+++ b/src/libdt.c
@@ -1938,7 +1938,7 @@ int of_device_disable_path(const char *path)
return of_device_disable(node);
 }
 
-int scan_proc_dir(struct device_node *node, const char *path)
+static int scan_proc_dir(struct device_node *node, const char *path)
 {
DIR *dir;
struct dirent *dirent;
-- 
2.39.2




[OSS-Tools] [PATCH 5/5] barebox-state: fix use after free in error path

2023-05-31 Thread Ahmad Fatoum
blob_bin is freed a few lines above unconditionally, so freeing it
again in the error path will cause a double free.

Signed-off-by: Ahmad Fatoum 
---
 src/keystore-blob.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/keystore-blob.c b/src/keystore-blob.c
index ed6ecb4eaa25..8ec07f0a3d56 100644
--- a/src/keystore-blob.c
+++ b/src/keystore-blob.c
@@ -81,10 +81,8 @@ int keystore_get_secret(const char *name, const unsigned 
char **key, int *key_le
 
/* payload */
fd = open(blob_gen_payload, O_RDONLY);
-   if (fd < 0) {
-   free(blob_bin);
+   if (fd < 0)
return -errno;
-   }
 
payload = xzalloc(len);
len = read(fd, payload, len);
-- 
2.39.2