586 Commits

Author SHA1 Message Date
George Sapkin
66127cd76c formal: fix workflow permissions
Fix formality check permissions that are needed to post optional
summaries back to the PR.

Link: openwrt/actions-shared-workflows#64
Signed-off-by: George Sapkin <george@sapk.in>
Link: https://github.com/openwrt/uci/pull/16
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-12-02 14:35:30 +01:00
Álvaro Fernández Rojas
5bea135723 github: ci: add MIPS64, PowerPC64 and RISCV64
MIPS64, PowerPC64 and RISCV64 are popular OpenWrt archs.
Refactor the sizes build step to generate the table programatically.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-18 10:03:45 +01:00
Álvaro Fernández Rojas
ebb3a01a0b build: install uci
Install uci and properly use it by adding it to PATH and LD_LIBRARY_PATH.
This is needed in order to use a proper environment for testing.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Link: https://github.com/openwrt/uci/pull/14
2025-11-17 19:32:53 +01:00
Álvaro Fernández Rojas
238963f48c github: ci: add powerpc arch
PowerPC is another popular OpenWrt arch.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-14 14:06:41 +01:00
Álvaro Fernández Rojas
dec51f48a1 github: ci: add cmake build and source directories
Add cmake build and source directories to suppress the following warning:
CMake Warning:
  No source or binary directory provided. Both will be assumed to be the
  same as the current working directory, but note that this warning will
  become a fatal error in future CMake releases.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-14 14:04:10 +01:00
Álvaro Fernández Rojas
8022b2e4d0 uci: add a simple build script
Should make it a little bit easier for people who want to contribute to
uci.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-14 12:15:13 +01:00
Álvaro Fernández Rojas
e1ab90c510 github: ci: add tests
Build ubus with UNIT_TESTING and execute tests.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-14 10:00:06 +01:00
Álvaro Fernández Rojas
b65c091a09 github: ci: disable json-c tests
Disable BUILD_TESTING to save time when building json-c.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-14 08:44:00 +01:00
Álvaro Fernández Rojas
c1e2eee6c5 github: fix CI apt dependencies
We need to run 'apt update' before installing the APT packages.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-11-03 08:09:17 +01:00
Álvaro Fernández Rojas
2e46a7405f github: improve CI
- Remove unneeded CMAKE_SYSTEM_PROCESSOR.
- Add summary table with sizes (in bytes) for each arch/variant.
- Upload generated binaries as artifacts.
- Add OpenWrt formalities.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-10-19 21:51:06 +02:00
Álvaro Fernández Rojas
57c1e8cd2c github: add CI build
Add Github CI supporting different architectures and uci build options.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-10-12 22:07:10 +02:00
David Härdeman
5e69edac2e CMakeLists: fix CMake warning for INCLUDE macro
Fix CMake warning for INCLUDE macro by moving the INCLUDE after the
PROJECT declaration.

CMake Warning (dev) at /usr/share/cmake-3.31/Modules/GNUInstallDirs.cmake:253 (message):
  Unable to determine default CMAKE_INSTALL_LIBDIR directory because no
  target architecture is known.  Please enable at least one language before
  including GNUInstallDirs.

Signed-off-by: David Härdeman <david@hardeman.nu>
[ improve commit description ]
Link: https://github.com/openwrt/uci/pull/7
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2025-10-05 14:33:55 +02:00
David Härdeman
272fc1348e lua: CMakeLists: drop redundant cmake_minimum_required
The Lua module depends on the parent uci project and can't be build
independently.

Drop redundant cmake_minimum_required from lua/CMakeLists.txt and
inherit the version from the parent CMake project to keep version
consistency.

Signed-off-by: David Härdeman <david@hardeman.nu>
[ improve commit description ]
Link: https://github.com/openwrt/uci/pull/7
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2025-10-05 14:33:54 +02:00
Christian Marangi
a072095389 lua: CMakeLists: update cmake minimum required version to 3.10
New cmake version 4.0 requires at least 3.5 version as the minimum
required version with it increased to 3.10 in to-be-released cmake
versions.

Set the minimum required version to 3.10 to future-proof for future
cmake version.

Suggested-by: Hannu Nyman <hannu.nyman@iki.fi>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2025-10-04 00:03:31 +02:00
Felix Fietkau
9033e8c272 blob: use blobmsg_parse_attr in __uci_blob_check_equal
Ensures that this function can be used with blobmsg containers

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2025-08-14 19:07:41 +02:00
Felix Fietkau
f3fc0b7604 libuci: fix false positive warning on older gcc versions
Fixes the following warning:

  libuci.c: In function 'uci_set_conf2dir':
  libuci.c:97:59: error: argument 'dir' might be clobbered by 'longjmp' or 'vfork' [-Werror=clobbered]
     97 | int uci_set_conf2dir(struct uci_context *ctx, const char *dir)
        |                                               ~~~~~~~~~~~~^~~
  cc1: all warnings being treated as errors

Reported-by: Matthias Franck <matthias.franck@softathome.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2025-01-28 19:56:34 +01:00
Felix Fietkau
16ff0badbd CMakeLists: add support for including ABIVERSION in the library version number
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2025-01-20 22:05:19 +01:00
Felix Fietkau
047b2efc13 CMakeLists.txt: bump minimum cmake version
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2025-01-17 13:09:50 +01:00
Felix Fietkau
fb3c2343b1 add support for an override config directory
This can be used to override specific config files at runtime without
touching them on primary storage. It is used by default for both reading
and updating.
The primary use case for this is adding a config management system which
generates and manages uci files at run time without overwriting existing
config files on flash.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2025-01-17 11:25:08 +01:00
Christian Marangi
10f7996ec2 file: Ignore config file with '.' in name
Uci doesn't support files with '.' in the config name and also have
parsing problems confusing option section with the actual filename.

Example:

hello.apk-new is parsed as hello filename and apk-new section

To correctly handle and prevent any kind of error, skip parsing these
file entirely. This is now needed for APK support as it does generate
config with a .apk-new suffix if a config already exist and the package
is updated.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2024-11-26 22:05:50 +01:00
Jan Venekamp
5781664d50 remove internal usage of redundant uci_ptr.last
In uci_lookup_ptr and uci_set the pointer uci_ptr ptr.last is set to
the element corresponding to the first of: ptr.o, ptr.s, ptr.p.

Thus, ptr.last is redundant and in case of uci_set is (and was) not
always consistently set.

In order to simplify the code this commit removes internal usage
of ptr.last, and remove setting it from uci_set (and from uci_add_list
that was never used anyway).

As it is part of the public C api ptr.last cannot be completely
removed though. A search on lxr.openwrt.org shows that it is used as
the output of uci_lookup_ptr in several packages.

So we leave setting ptr.last in uci_lookup_ptr intact.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-08-10 19:43:45 +02:00
Jan Venekamp
3cda25127b file: Fix uci -m import command
Without this change we see the following error:
  # uci -m import optic < /etc/optic-db/default
  uci: Parse error (option/list command found before the first section) at line 4, byte 1

ptr.last is still a null pointer in case the uci_lookup_list() call
found a matching section and set ptr.s to it. The code expects that
uci_set() updates the ptr.last pointer, but this is not done any more.
If case uci_lookup_list() did not found a section ptr->s is a null
pointer and then uci_set() will allocate a new section.

Fixes: ae61e1cad4 ("uci: optimize update section in uci_set")
Co-authored-by: Hauke Mehrtens <hmehrtens@maxlinear.com>
Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-08-10 19:42:57 +02:00
Jan Venekamp
04d0c46cfe uci: macro uci_alloc_element not in uci.h
The macro uci_alloc_element is in the public header file uci.h. However,
the macros output refers to uci_alloc_generic wich is in uci_internal.h
and not public. Thus, uci_alloc_element should be private as well and
moved to uci_internal.h.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
ae61e1cad4 uci: optimize update section in uci_set
Optimize for the case when there is no need to update the section and
the case there is no need to reallocate memory when updating a section
in uci_set.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
16e8a3b133 uci: fix memory leak uci_set on update section
If uci_realloc fails when updating a section in uci_set the reference
to the memory allocated by s = uci_strdup() is lost.

Also, if uci_strdup and uci_realloc both succeed it could happen that
ptr->s->type == uci_dataptr(ptr->s) by accident. Then later on in
uci_free_section the allocated ptr->s->type is not freed.

In order to fix this, instead of splitting the allocation of the the
section and the type string, we create a new section with in-section
storage to replace the old one. This also brings the code for updating
a section more in line with the simular code for updating an option.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
b2f341769d uci: maintain option position in uci_add_list
Maintain the position of an option in the list when a string option
is converted to a list option in uci_add_list.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
74f2797fca uci: fix atomicity of uci_add_list
The function uci_add_list is not atomic, when an alloc inside
uci_add_element_list fails the option can be left in an indeterminate
state.

Refactor uci_add_list to fix this and make the code flow easier to
read.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
47697e6579 uci: fix use-after-free uci_add_list
When uci_add_list is called with ptr->o set and ptr->option = NULL,
then in uci_expand_ptr ptr->option is set to ptr->o->e.name.
If ptr->o->type is UCI_TYPE_STRING then prev is set to ptr->o.
This will result in use-after-free because ptr->option is used in
the call to uci_add_delta in uci_add_element_list after
uci_free_option(prev).

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
7e01d66d7b uci: optimize update option in uci_set
Optimize for the case when there is no need to reallocate memory when
updating an option in uci_set.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
b7ceda9a2f uci: maintain option position in uci_set
Maintain the position of an option in the list when updating an option
in uci_set.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Jan Venekamp
9b6605ec4c uci: fix use-after-free uci_set on update option
When uci_set is called with ptr->o set and ptr->option = NULL,
then in uci_expand_ptr ptr->option is set to ptr->o->e.name.
This will result in use-after-free because ptr->option is used in
the call to uci_add_delta after uci_free_option(ptr->o).

Signed-off-by: Jan Venekamp <jan@venekamp.net>
2023-03-04 19:39:32 +01:00
Rafał Miłecki
f49a2fdc4f delta: simplify uci_load_delta() by using a helper
In the commit 3c7f3556b0 ("Fix delta path handling.")
uci_load_delta() was modified by open coding uci_load_delta_file(). It
seems that reason behind it was to avoid uci_parse_delta(). The same can
be achieved by passing NULL as "struct uci_package *p" argument.

Cc: Yousong Zhou <yszhou4tech@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2022-08-28 13:05:20 +02:00
Rafał Miłecki
5de3871898 cli: drop redundant uci_add_delta_path() call for -P
savedir is always present in the list of delta paths. It's guaranteed by
1. uci_alloc_context() which sets defaults
2. uci_set_savedir() which allows changing savedir

Calling uci_add_delta_path() with ctx->savedir argument seems to always
return UCI_ERR_DUPLICATE.

Fixes: 2b4872345a ("make use of the history path feature in the cli")
Cc: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2022-08-28 13:05:10 +02:00
Hauke Mehrtens
f84f49f00f cmake: Allow override of install directories
Use the GNUInstallDirs include to allow callers to override the install
directories. This is helpful when building uci in build systems like
Yocto which prefer to use /usr/lib64 for the 64 bit libraries.

Signed-off-by: Hauke Mehrtens <hmehrtens@maxlinear.com>
2021-10-22 22:58:18 +02:00
Rafał Miłecki
4b3db11797 cli: add option for changing save path
Save path is a directory where config change (delta) files are stored.
Having a custom individual save dir can be used to prevent two (or more)
"uci" cli callers (e.g. bash scripts) from commiting each other changes.

In the following example:

App0					App1
----					----
uci set system.@system[0].timezone=UTC
					uci set system.@system[0].hostname=OpenWrt
					uci commit system

App1 would unintentionally commit changes made by App0. This can be
avoided by at least 1 "uci" cli user specifying a custom -t option.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2021-04-14 08:15:46 +02:00
Hauke Mehrtens
52bbc99f69 Replace malloc() + memset() with calloc()
Instead of manually clearing the memory with memset() use calloc().

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2020-10-06 08:35:23 +02:00
Hauke Mehrtens
3fbd6c9234 ucimap: Check return of malloc()
Check the return value of malloc() before accessing it.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2020-10-06 08:35:21 +02:00
Hauke Mehrtens
eae126f666 file: Check buffer size after strtok()
This fixes a heap overflow in the parsing of the uci line.

The line which is parsed and put into pctx->buf is null terminated and
stored on the heap. In the uci_parse_line() function we use strtok() to
split this string in multiple parts after divided by a space or tab.
strtok() replaces these characters with a NULL byte. If the next byte is
NULL we assume that this NULL byte was added by strtok() and try to
parse the string after this NULL byte. If this NULL byte was not added
by strtok(), but by fgets() to mark the end of the string we would read
over this end of the string in uninitialized memory and later over the
allocated buffer.

Fix this problem by storing how long the line we read was and check if
we would read over the end of the string here.

This also adds the input which detected this crash to the corpus of the
fuzzer.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
[fixed merge conflict in tests]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-06 08:33:57 +02:00
Hauke Mehrtens
7f57427318 file: use size_t for position and pointer
The bufsz variable is used to store the size of the buf memory region
and pos is used to index a position in this memory. Use size_t for these
variables in the internal handling instaed of int to not break with big
files.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2020-10-06 08:31:44 +02:00
Jo-Philipp Wich
19770b6949 file: use dynamic memory allocation for tempfile name
Allocating a 4KB stack space buffer just for formatting a tempfile name
does not seem ideal.

Fixes: aa46546794 ("file: uci_file_commit: fix memory leak")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-06 08:08:10 +02:00
Petr Štetiar
aa46546794 file: uci_file_commit: fix memory leak
Fixes following memory leak:

 26 bytes in 1 blocks are definitely lost in loss record 1 of 1
   at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x52DA68F: vasprintf (vasprintf.c:73)
   by 0x52B71D3: asprintf (asprintf.c:35)
   by 0x4E40F67: uci_file_commit (file.c:738)
   by 0x4E3FD94: uci_commit (libuci.c:193)
   by 0x401ED9: uci_do_import (cli.c:408)
   by 0x401ED9: uci_cmd (cli.c:685)
   by 0x4016FA: main (cli.c:776)

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-03 09:46:18 +02:00
Petr Štetiar
671c7554bf uci: silence UBSAN error by using offsetof macro from compiler
Fixes following ubdefined-behavior as reported by clang version 10.0.0-4ubuntu1~18.04.2:

 delta.c:139:52: runtime error: member access within null pointer of type 'struct uci_element'
 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior delta.c:139:52

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-03 09:46:18 +02:00
Petr Štetiar
ea5bbd57d0 tests: cram: add uci import testing on fuzzer corpus
Use valgrind and uci cli compiled with undefined, address and leak
sanitizers.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-03 09:46:18 +02:00
Petr Štetiar
31f78bfbf7 cmake: add uci-san cli built with clang sanitizers
Will be used for testing.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-03 09:20:48 +02:00
Petr Štetiar
a3e650911f file: uci_parse_package: fix heap use after free
Fixes following issue which is caused by usage of pointer which pointed
to a reallocated address:

 ERROR: AddressSanitizer: heap-use-after-free on address 0x619000000087 at pc 0x000000509aa7 bp 0x7ffd6b9c3c40 sp 0x7ffd6b9c3400
 READ of size 2 at 0x619000000087 thread T0
     #0 0x509aa6 in strdup (test-fuzz+0x509aa6)
     #1 0x7fc36d2a1636 in uci_strdup util.c:60:8
     #2 0x7fc36d29e1ac in uci_alloc_generic list.c:55:13
     #3 0x7fc36d29e241 in uci_alloc_package list.c:253:6
     #4 0x7fc36d2a0ba3 in uci_switch_config file.c:375:18
     #5 0x7fc36d2a09b8 in uci_parse_package file.c:397:2
     #6 0x7fc36d2a09b8 in uci_parse_line file.c:513:6
     #7 0x7fc36d2a09b8 in uci_import file.c:681:4

 0x619000000087 is located 7 bytes inside of 1024-byte region [0x619000000080,0x619000000480)
 freed by thread T0 here:
     #0 0x51daa9 in realloc (test-fuzz+0x51daa9)
     #1 0x7fc36d2a1612 in uci_realloc util.c:49:8

 previously allocated by thread T0 here:
     #0 0x51daa9 in realloc (test-fuzz+0x51daa9)
     #1 0x7fc36d2a1612 in uci_realloc util.c:49:8

Reported-by: Jeremy Galindo <jgalindo@datto.com>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-03 09:20:48 +02:00
Petr Štetiar
9bd361ca32 tests: add libFuzzer based fuzzing
LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.

LibFuzzer is linked with the library under test, and feeds fuzzed inputs
to the library via a specific fuzzing entrypoint (aka "target
function"); the fuzzer then tracks which areas of the code are reached,
and generates mutations on the corpus of input data in order to maximize
the code coverage.

So lets use libFuzzer to fuzz uci_import for the start.

Ref: https://llvm.org/docs/LibFuzzer.html
Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-10-03 09:20:48 +02:00
Alin Nastac
ec8d323394 file: preserve original file mode after commit
Because mkstemp() create a file with mode 0600, only user doing
the commit (typically root) will be allowed to inspect the content
of the file after uci commit.

Signed-off-by: Alin Nastac <alin.nastac@gmail.com>
2020-04-27 21:16:27 +02:00
Luka Koznjak
e8d83732f9 file: fix segfault in uci_parse_option
Fixed a segmentation fault caused by using a pointer to a reallocated
address. The name pointer in the uci_parse_option function
becomes invalid if assert_eol calls uci_realloc down the line,
resulting in a segmentation fault when attempting to dereference
name in a strcmp check in uci_lookup_list. A simple fix is
to call assert_eol before retrieving the actual address for
the name and type pointers.

The segmentation fault has been found while fuzzing the
uci configuration system for various types of different crashes
and undefined behavious, which resulted in multiple different
import files causing instability and sementation faults.

Signed-off-by: Luka Kožnjak <luka.koznjak@sartura.hr>
Signed-off-by: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
CC: Luka Perkov <luka.perkov@sartura.hr>
2020-01-27 23:24:48 +01:00
Luka Koznjak
aa5e77a13d file: fix segfault in uci_parse_config
Fixed a segmentation fault caused by using a pointer to a reallocated
address. The name pointer in the uci_parse_config function
becomes invalid if assert_eol calls uci_realloc down the line,
resulting in a segmentation fault when attempting to dereference
name. A simple fix is to call assert_eol before retrieving the
actual address for the name and type pointers.

The segmentation fault has been found while fuzzing the
uci configuration system for various types of different crashes
and undefined behavious, which resulted in multiple different
import files causing instability and sementation faults.

Signed-off-by: Luka Kožnjak <luka.koznjak@sartura.hr>
Signed-off-by: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
CC: Luka Perkov <luka.perkov@sartura.hr>
2020-01-27 23:24:48 +01:00
Rosen Penev
165b444131 uci: Fix extra semicolons warnings
Found with clang's -Wextra-semi-stmt

Fixes:

error: empty expression statement has no effect; remove unnecessary ';' to
silence this warning [-Werror,-Wextra-semi-stmt]
                UCI_TRAP_SAVE(ctx, error);
                                         ^
error: empty expression statement has no effect; remove unnecessary ';' to
silence this warning [-Werror,-Wextra-semi-stmt]
        UCI_TRAP_SAVE(ctx, ignore);

error: empty expression statement has no effect; remove unnecessary ';' to
silence this warning [-Werror,-Wextra-semi-stmt]
        };

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-12-11 21:51:35 +01:00