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>
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
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>