project/libubox.git
2 years agoblob: clear buf->head when freeing a buffer
Felix Fietkau [Thu, 10 Feb 2022 20:02:16 +0000 (21:02 +0100)]
blob: clear buf->head when freeing a buffer

Prevents accidental silent use-after-free bugs

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2 years agovlist: define vlist_for_each_element_safe
Daniel Golle [Fri, 12 Nov 2021 20:04:29 +0000 (20:04 +0000)]
vlist: define vlist_for_each_element_safe

Yet another macro wrapper around the corresponding avl_* macro.
This new macro makes it possible to iterate over vlists in ways which
may have destructive consequences without being punished by segfault.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2 years agouloop: deprecate uloop_timeout_remaining
Stijn Tintel [Thu, 4 Nov 2021 10:28:39 +0000 (12:28 +0200)]
uloop: deprecate uloop_timeout_remaining

We have uloop_timeout_remaining64 now.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Acked-by: Jo-Philipp Wich <jo@mein.io>
Acked-by: John Crispin <john@phrozen.org>
2 years agolua/uloop: use uloop_timeout_remaining64
Stijn Tintel [Thu, 4 Nov 2021 10:31:28 +0000 (12:31 +0200)]
lua/uloop: use uloop_timeout_remaining64

We will deprecate uloop_timeout_remaining soon.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Acked-by: Jo-Philipp Wich <jo@mein.io>
Acked-by: John Crispin <john@phrozen.org>
2 years agouloop: add uloop_timeout_remaining64
Stijn Tintel [Thu, 4 Nov 2021 10:26:41 +0000 (12:26 +0200)]
uloop: add uloop_timeout_remaining64

This uses the same return type as tv_diff so we don't need to check for
integer overflow.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Acked-by: Jo-Philipp Wich <jo@mein.io>
Acked-by: John Crispin <john@phrozen.org>
2 years agouloop: restore return type of uloop_timeout_remaining
Stijn Tintel [Thu, 4 Nov 2021 10:14:02 +0000 (12:14 +0200)]
uloop: restore return type of uloop_timeout_remaining

The uloop_timeout_remaining function is public and changing its return
type breaks ABI. Change the return type back to int, and return INT_MIN
or INT_MAX if the value returned by tv_diff would overflow integer.

Fixes: be3dc7223a6d ("uloop: avoid integer overflow in tv_diff")
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Acked-by: Jo-Philipp Wich <jo@mein.io>
Acked-by: John Crispin <john@phrozen.org>
2 years agouloop: avoid integer overflow in tv_diff
Stijn Tintel [Wed, 3 Nov 2021 23:17:39 +0000 (01:17 +0200)]
uloop: avoid integer overflow in tv_diff

The tv_diff function can potentially overflow as soon as t2->tv_sec is
larger than 2147483. This is very easily hit in ujail, after only
2147484 seconds of uptime, or 24.85 days.

Improve the behaviour by changing the return type to int64_t.

Fixes: FS#3943
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2 years agolist.h: add a few missing iterator macros
Felix Fietkau [Thu, 19 Aug 2021 06:47:04 +0000 (08:47 +0200)]
list.h: add a few missing iterator macros

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2 years agojson_script: fix unannotated fall-through warning
Felix Fietkau [Sun, 16 May 2021 16:07:24 +0000 (18:07 +0200)]
json_script: fix unannotated fall-through warning

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2 years agoutils.h: add fallthrough macro
Felix Fietkau [Sun, 16 May 2021 15:31:57 +0000 (17:31 +0200)]
utils.h: add fallthrough macro

This can be used to silence clang warnings about unannotated fall-through

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoblob: fix exceeding maximum buffer length
Zefir Kurtisi [Fri, 23 Apr 2021 17:48:01 +0000 (19:48 +0200)]
blob: fix exceeding maximum buffer length

Currently there is no measure in place to prevent the blob buffer
to exceed its maximum allowed length of 16MB. Continuously
calling blob_add() will expand the buffer until it exceeds
BLOB_ATTR_LEN_MASK and after that will return valid blob_attr
pointer without increasing the buflen.

A test program was added in the previous commit, this one fixes
the issue by asserting that the new bufflen after grow does not
exceed BLOB_ATTR_LEN_MASK.

Signed-off-by: Zefir Kurtisi <zefir.kurtisi@gmail.com>
3 years agotests: add blob-buffer overflow test
Zefir Kurtisi [Fri, 23 Apr 2021 17:48:00 +0000 (19:48 +0200)]
tests: add blob-buffer overflow test

The blob buffer has no limitation in place
to prevent buflen to exceed maximum size.

This commit adds a test to demonstrate how
a blob increases past the maximum allowd
size of 16MB. It continuously adds chunks
of 64KB and with the 255th one blob_add()
returns a valid attribute pointer but the
blob's buflen does not increase.

The test is used to demonstrate the
failure, which is fixed with a follow-up
commit.

Signed-off-by: Zefir Kurtisi <zefir.kurtisi@gmail.com>
[adjusted test case for cram usage]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
3 years agolibubox: tests: add more blobmsg/json test cases
Peter Seiderer [Sat, 6 Mar 2021 10:54:50 +0000 (11:54 +0100)]
libubox: tests: add more blobmsg/json test cases

* add mixed int/double tests
 * add blobmsg_cast_u64/blobmsg_cast_s64 tests

Signed-off-by: Peter Seiderer <ps.report@gmx.net>
3 years agotests: cram: test_base64: really fix failing tests
Petr Štetiar [Wed, 3 Mar 2021 14:37:52 +0000 (15:37 +0100)]
tests: cram: test_base64: really fix failing tests

Remove the checks for 'Aborted (core dumped)' message altogether as it's
not reliable and not portable.

References: https://gitlab.com/openwrt/project/libubox/-/jobs/1070226897
Signed-off-by: Petr Štetiar <ynezz@true.cz>
3 years agotests: cram: test_base64: fix failing tests
Petr Štetiar [Wed, 3 Mar 2021 12:49:27 +0000 (13:49 +0100)]
tests: cram: test_base64: fix failing tests

Seems like latest version of llvm compiler/sanitizer has changed
behaviour during crash so `Aborted (core dumped)` is now printed to
stdout.

Fixes following issue:

 --- /builds/openwrt/project/libubox/tests/cram/test_base64.t
 +++ /builds/openwrt/project/libubox/tests/cram/test_base64.t.err
 @@ -49,9 +49,7 @@
    b64_encode: Assertion `dest && targsize > 0' failed.

    $ test-b64_decode-san 2> output.log; check
 -  Aborted (core dumped)
    b64_decode: Assertion `dest && targsize > 0' failed.

    $ test-b64_encode-san 2> output.log; check
 -  Aborted (core dumped)
    b64_encode: Assertion `dest && targsize > 0' failed.

References: https://gitlab.com/openwrt/project/libubox/-/jobs/1069840314
Signed-off-by: Petr Štetiar <ynezz@true.cz>
3 years agolibubox: fix BLOBMSG_CAST_INT64 (do not override BLOBMSG_TYPE_DOUBLE)
Peter Seiderer [Fri, 26 Feb 2021 19:24:20 +0000 (20:24 +0100)]
libubox: fix BLOBMSG_CAST_INT64 (do not override BLOBMSG_TYPE_DOUBLE)

Commit 9e52171 ('blobmsg: introduce BLOBMSG_CAST_INT64') broke
blobmsg_parse() for BLOBMSG_TYPE_DOUBLE.

This is because the enum definition leads to the following double
define for BLOBMSG_CAST_INT64/BLOBMSG_TYPE_DOUBLE as value 8.

Tested with:

$ cat test-enum-001.c
  #include <stdio.h>

  enum blobmsg_type {
   BLOBMSG_TYPE_UNSPEC,
   BLOBMSG_TYPE_ARRAY,
   BLOBMSG_TYPE_TABLE,
   BLOBMSG_TYPE_STRING,
   BLOBMSG_TYPE_INT64,
   BLOBMSG_TYPE_INT32,
   BLOBMSG_TYPE_INT16,
   BLOBMSG_TYPE_INT8,
   BLOBMSG_TYPE_DOUBLE,
   __BLOBMSG_TYPE_LAST,
   BLOBMSG_TYPE_LAST = __BLOBMSG_TYPE_LAST - 1,
   BLOBMSG_TYPE_BOOL = BLOBMSG_TYPE_INT8,
   BLOBMSG_CAST_INT64,
  };

  int main(int artc, char* argv[]) {
   printf("BLOBMSG_TYPE_UNSPEC: %d\n", BLOBMSG_TYPE_UNSPEC);
   printf("BLOBMSG_TYPE_ARRAY: %d\n", BLOBMSG_TYPE_ARRAY);
   printf("BLOBMSG_TYPE_TABLE: %d\n", BLOBMSG_TYPE_TABLE);
   printf("BLOBMSG_TYPE_STRING: %d\n", BLOBMSG_TYPE_STRING);
   printf("BLOBMSG_TYPE_INT64: %d\n", BLOBMSG_TYPE_INT64);
   printf("BLOBMSG_TYPE_INT32: %d\n", BLOBMSG_TYPE_INT32);
   printf("BLOBMSG_TYPE_INT16: %d\n", BLOBMSG_TYPE_INT16);
   printf("BLOBMSG_TYPE_INT8: %d\n", BLOBMSG_TYPE_INT8);
   printf("BLOBMSG_TYPE_DOUBLE: %d\n", BLOBMSG_TYPE_DOUBLE);
   printf("__BLOBMSG_TYPE_LAST: %d\n", __BLOBMSG_TYPE_LAST);
   printf("BLOBMSG_TYPE_LAST: %d\n", BLOBMSG_TYPE_LAST);
   printf("BLOBMSG_TYPE_BOOL: %d\n", BLOBMSG_TYPE_BOOL);
   printf("BLOBMSG_CAST_INT64: %d\n", BLOBMSG_CAST_INT64);
   return 0;
  }

$ gcc test-enum-001.c

$ ./a.out
  BLOBMSG_TYPE_UNSPEC: 0
  BLOBMSG_TYPE_ARRAY: 1
  BLOBMSG_TYPE_TABLE: 2
  BLOBMSG_TYPE_STRING: 3
  BLOBMSG_TYPE_INT64: 4
  BLOBMSG_TYPE_INT32: 5
  BLOBMSG_TYPE_INT16: 6
  BLOBMSG_TYPE_INT8: 7
  BLOBMSG_TYPE_DOUBLE: 8
  __BLOBMSG_TYPE_LAST: 9
  BLOBMSG_TYPE_LAST: 8
  BLOBMSG_TYPE_BOOL: 7
  BLOBMSG_CAST_INT64: 8

Fix this by changing the enum defintion to assign BLOBMSG_CAST_INT64 to
the unique value 9.

Signed-off-by: Peter Seiderer <ps.report@gmx.net>
3 years agoutils: simplify mkdir_p boolean conditions
Rui Salvaterra [Sun, 13 Dec 2020 11:57:43 +0000 (11:57 +0000)]
utils: simplify mkdir_p boolean conditions

Just a trivial simplification.

Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
3 years agoutils: introduce mkdir_p
Daniel Golle [Sat, 12 Dec 2020 22:45:53 +0000 (22:45 +0000)]
utils: introduce mkdir_p

Add new utility function mkdir_p(char *path, mode_t mode) to replace
the partially buggy implementations found accross fstools and procd.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
3 years agoblobmsg: introduce BLOBMSG_CAST_INT64
Daniel Golle [Tue, 4 Aug 2020 00:27:09 +0000 (01:27 +0100)]
blobmsg: introduce BLOBMSG_CAST_INT64

When dealing with 64-bit integers in JSON documents, blobmsg_parse
becomes useless as blobmsg-json only uses BLOBMSG_TYPE_INT64 if the
value exceeds the range of a 32-bit integer, otherwise
BLOBMSG_TYPE_INT32 is used. This is because blobmsg-json parses the
JSON document ad-hoc without knowing the schema in advance and hence
a result of the design of blobmsg-json (and the absence of JSON
schema definitions).
In practise, this made code less readable as instead of using
blobmsg_parse() one had to to deal with *all* attributes manually just
to catch fields which can be both, BLOBMSG_TYPE_INT32 or
BLOBMSG_TYPE_INT64, but are always dealt with as uint64_t in code as
they potentially could exceed the 32-bit range.

To resolve this issue, introduce as special wildcard attribute
type BLOBMSG_CAST_INT64 which should only be used in policies used
by blobmsg_parse(). If used for an attribute in the policy,
blobmsg_parse shall accept all integer types and allow the user
to retrieve the value using the uint64_t blobmsg_cast_u64() and
int64_t blobmsg_cast_s64() functions which is also introduced by this
commit.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
3 years agoexamples/lua: attempt to highlight some traps
Karl Palsson [Tue, 30 Jun 2020 10:38:44 +0000 (10:38 +0000)]
examples/lua: attempt to highlight some traps

Ran into some issues with my fd event being garbage collected.  As I
never wanted to call :delete, I had seen no reason to keep the returned
object, as my callback and upvalues were still valid.

Signed-off-by: Karl Palsson <karlp@etactica.com>
3 years agolua/uloop: fd_add: use absolute indices for arguments
Karl Palsson [Tue, 30 Jun 2020 10:38:43 +0000 (10:38 +0000)]
lua/uloop: fd_add: use absolute indices for arguments

Instead of having to adjust the index repeatedly as the stack is
manipulated, use absolute addressing for the function arguments, so they
stay the same throughout the call.  Zero functional change, just
subjectively easier to follow variables.

Signed-off-by: Karl Palsson <karlp@etactica.com>
3 years agolua/uloop: make get_sock_fd capable of absolute addresses
Karl Palsson [Tue, 30 Jun 2020 10:38:42 +0000 (10:38 +0000)]
lua/uloop: make get_sock_fd capable of absolute addresses

The original code required the use of relative addresses into the lua
stack.  It should accept either.

Signed-off-by: Karl Palsson <karlp@etactica.com>
3 years agolua/uloop: fd_add() better args checking
Karl Palsson [Tue, 30 Jun 2020 10:38:41 +0000 (10:38 +0000)]
lua/uloop: fd_add() better args checking

Actually check for flags being valid, instead of simply ignoring the
call if flags was zero.

Use standard lua checks for the function argument, so you can get a
normal "argument #2 was invalid, expected function, got xxx" instead of
the vague, "invalid arg list"

Signed-off-by: Karl Palsson <karlp@etactica.com>
3 years agoblobmsg: drop old comment about json formatting functions
Rafał Miłecki [Tue, 26 May 2020 08:50:58 +0000 (10:50 +0200)]
blobmsg: drop old comment about json formatting functions

Those functions were moved out of blobmsg.h.

Fixes: 0918243e90e6 ("move json formatting to the blobmsg_json library")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
3 years agoblobmsg: fix missing length checks
Felix Fietkau [Mon, 25 May 2020 10:40:04 +0000 (12:40 +0200)]
blobmsg: fix missing length checks

blobmsg_check_attr_len was calling blobmsg_check_data for some, but not all
attribute types. These checks was missing for arrays and tables.

Additionally, the length check in blobmsg_check_data was a bit off, since
it was comparing the blobmsg data length against the raw blob attr length.

Fix this by checking the raw blob length against the buffer length in
blobmsg_hdr_from_blob

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoblobmsg: simplify and fix name length checks in blobmsg_check_name
Felix Fietkau [Mon, 25 May 2020 12:49:35 +0000 (14:49 +0200)]
blobmsg: simplify and fix name length checks in blobmsg_check_name

blobmsg_hdr_valid_namelen was omitted when name==false
The blob_len vs blobmsg_namelen changes were not taking into account
potential padding between name and data

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoblobmsg: fix length in blobmsg_check_array
Felix Fietkau [Mon, 25 May 2020 11:44:20 +0000 (13:44 +0200)]
blobmsg: fix length in blobmsg_check_array

blobmsg_check_array_len expects the length of the full attribute buffer,
not just the data length.
Due to other missing length checks (fixed in the next commit), this did
not show up as a test failure

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agotests: add fuzzer seed file for crash in blob_len
Petr Štetiar [Tue, 26 May 2020 07:22:13 +0000 (09:22 +0200)]
tests: add fuzzer seed file for crash in blob_len

Following regression was introduced in commit 5e75160f4878 ("blobmsg:
fix attrs iteration in the blobmsg_check_array_len()"):

 Thread 1 "test-fuzz" received signal SIGSEGV, Segmentation fault.
  in blob_len (attr=0x6020000100d4) at libubox/blob.h:102
  102             return (be32_to_cpu(attr->id_len) & BLOB_ATTR_LEN_MASK) - sizeof(struct blob_attr);

 blob_len (attr=0x6020000100d4) at /libubox/blob.h:102
 blob_raw_len (attr=0x6020000100d4) at /libubox/blob.h:111
 blob_pad_len (attr=0x6020000100d4) at /libubox/blob.h:120
 blobmsg_check_array_len (attr=0x6020000000d0, type=0, blob_len=10) at /libubox/blobmsg.c:145
 fuzz_blobmsg_parse (data=0x6020000000d0 "\001\004", size=10) at /libubox/tests/fuzz/test-fuzz.c:57

Signed-off-by: Petr Štetiar <ynezz@true.cz>
3 years agoblob: make blob_parse_untrusted more permissive
Matthias Schiffer [Sat, 16 May 2020 20:22:10 +0000 (22:22 +0200)]
blob: make blob_parse_untrusted more permissive

Some tools like ucert use concatenations of multiple blobs. Account for
this case by allowing the underlying buffer length to be greater than
the blob length.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
3 years agoblobmsg: fix attrs iteration in the blobmsg_check_array_len()
Rafał Miłecki [Sat, 23 May 2020 11:18:51 +0000 (13:18 +0200)]
blobmsg: fix attrs iteration in the blobmsg_check_array_len()

Starting with 75e300aeec25 ("blobmsg: fix wrong payload len passed from
blobmsg_check_array") blobmsg_check_array_len() gets *blob* length
passed as argument. It cannot be used with __blobmsg_for_each_attr()
which expects *data* length.

Use blobmsg_for_each_attr() which calculates *data* length on its own.

The same bug was already reported in the past and there was fix attempt
in the commit cd75136b1342 ("blobmsg: fix wrong payload len passed from
blobmsg_check_array"). That change made blobmsg_check_attr_len() calls
fail however.

This is hopefully the correct & complete fix:
1. blobmsg_check_array_len() gets *blob* length
2. It calls blobmsg_check_attr_len() which requires *blob* length
3. It uses blobmsg_for_each_attr() which gets *data* length

This fixes iterating over random memory treated as attrs. That was
resulting in check failing randomly for totally correct blobs. It's
critical e.g. for procd project with its instance_fill_array() failing
and procd not starting services.

Fixes: 75e300aeec25 ("blobmsg: fix wrong payload len passed from blobmsg_check_array")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
3 years agotests: runqueue: try to fix race on GitLab CI
Petr Štetiar [Thu, 21 May 2020 14:28:29 +0000 (16:28 +0200)]
tests: runqueue: try to fix race on GitLab CI

Seems like the CI runners are slower and produce different test output:

 -  [0/1] finish 'sleep 1' (killer)
    [1/1] start 'sleep 1' (sleeper)
 +  [1/1] finish 'sleep 1' (killer)
 +  [1/1] finish 'sleep 1' (killer)
    [1/1] cancel 'sleep 1' (sleeper)
    [0/1] finish 'sleep 1' (sleeper)
    [1/1] start 'sleep 1' (sleeper)

Lets try to fix it by lowering the killing timeout.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
3 years agolibubox: runqueue: fix use-after-free bug
Alban Bedel [Thu, 23 Apr 2020 03:35:23 +0000 (15:35 +1200)]
libubox: runqueue: fix use-after-free bug

Fixes a use-after-free bug in runqueue_task_kill():

 Invalid read of size 8
    at runqueue_task_kill (runqueue.c:200)
    by uloop_process_timeouts (uloop.c:505)
    by uloop_run_timeout (uloop.c:542)
    by uloop_run (uloop.h:111)
    by main (tests/test-runqueue.c:126)
  Address 0x5a4b058 is 24 bytes inside a block of size 208 free'd
    at free
    by runqueue_task_complete (runqueue.c:234)
    by runqueue_task_kill (runqueue.c:199)
    by uloop_process_timeouts (uloop.c:505)
    by uloop_run_timeout (uloop.c:542)
    by uloop_run (uloop.h:111)
    by main (tests/test-runqueue.c:126)
  Block was alloc'd at
    at calloc
    by add_sleeper (tests/test-runqueue.c:101)
    by main (tests/test-runqueue.c:123)

Since commit 11e8afea (runqueue should call the complete handler from
more places) the call to the complete() callback has been moved to
runqueue_task_complete().  However in runqueue_task_kill()
runqueue_task_complete() is called before the kill() callback.  This
will result in a use after free if the complete() callback frees the
task struct.

Furthermore runqueue_start_next() is already called at the end of
runqueue_task_complete(), so there is no need to call it again in
runqueue_task_kill().

The issue was that the _complete() callback frees the memory used by the
task struct, which is then read after the _complete() callback returns.

Ref: FS#3016
Signed-off-by: Alban Bedel <albeu@free.fr>
[initial test case, kill cb comment fix]
Signed-off-by: Chris Nisbet <nischris@gmail.com>
[testcase improvements and commit subject/description tweaks]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
3 years agolibubox: runqueue fix comment in header
Chris Nisbet [Thu, 23 Apr 2020 03:35:24 +0000 (15:35 +1200)]
libubox: runqueue fix comment in header

The comment relating to the runqueue task structure 'cancel' callback
indicated that the callback 'calls' runqueue_task_complete, which
isn't quite right. The callback _should_ call runqueue_task_complete.

Signed-off-by: Chris Nisbet <nischris@gmail.com>
3 years agotests: list: add test case for list_empty iterator
Petr Štetiar [Thu, 19 Dec 2019 10:49:39 +0000 (11:49 +0100)]
tests: list: add test case for list_empty iterator

Increasing unit testing code coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: blobmsg: add test case
Chris Nisbet [Wed, 12 Feb 2020 08:08:44 +0000 (21:08 +1300)]
tests: blobmsg: add test case

 * add a test for blobmsg_check_array() to test an array with a string in it

This test was added in conjunction with a change to blobmsg_check_array() to
get it to pass the length obtained from blob_len() rather than blobmsg_len().

Signed-off-by: Chris Nisbet <nischris@gmail.com>
4 years agoblobmsg: fix wrong payload len passed from blobmsg_check_array
Chris Nisbet [Wed, 12 Feb 2020 08:00:31 +0000 (21:00 +1300)]
blobmsg: fix wrong payload len passed from blobmsg_check_array

Fix incorrect use of blobmsg_len() on passed blobmsg to
blobmsg_check_array_len() introduced in commit 379cd33d1992
("fix wrong payload len passed from blobmsg_check_array") by using correct
blob_len().

By using blobmsg_len() a value too small was passed to blobmsg_check_array()
which could lead to this function returning an error when there is none.

Fixes: 379cd33d1992 ("fix wrong payload len passed from blobmsg_check_array")
Signed-off-by: Chris Nisbet <nischris@gmail.com>
[add fixes tag, rewrap commit message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
4 years agoblobmsg: blobmsg_parse and blobmsg_parse_array oob read fixes
Juraj Vijtiuk [Sun, 12 Jan 2020 11:26:18 +0000 (12:26 +0100)]
blobmsg: blobmsg_parse and blobmsg_parse_array oob read fixes

Fix out of bounds read in blobmsg_parse and blobmsg_check_name. The
out of bounds read happens because blob_attr and blobmsg_hdr have
flexible array members, whose size is 0 in the corresponding sizeofs.
For example the __blob_for_each_attr macro checks whether rem >=
sizeof(struct blob_attr). However, what LibFuzzer discovered was,
if the input data was only 4 bytes, the data would be casted to blob_attr,
and later on blob_data(attr) would be called even though attr->data was empty.
The same issue could appear with data larger than 4 bytes, where data
wasn't empty, but contained only the start of the blobmsg_hdr struct,
and blobmsg_hdr name was empty. The bugs were discovered by fuzzing
blobmsg_parse and blobmsg_array_parse with LibFuzzer.

CC: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
[refactored some checks, added fuzz inputs, adjusted unit test results]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: prefer dynamically allocated buffers
Petr Štetiar [Sat, 18 Jan 2020 17:32:55 +0000 (18:32 +0100)]
tests: prefer dynamically allocated buffers

Help detecting Valgrind OOB reads and other issues.

 Conditional jump or move depends on uninitialised value(s)
   at 0x5452886: blobmsg_parse (blobmsg.c:203)
   by 0x400A8E: test_blobmsg (tests/test-blobmsg-parse.c:66)
   by 0x400A8E: main (tests/test-blobmsg-parse.c:82)

 Conditional jump or move depends on uninitialised value(s)
   at 0x545247F: blobmsg_check_name (blobmsg.c:39)
   by 0x545247F: blobmsg_check_attr_len (blobmsg.c:79)
   by 0x5452710: blobmsg_parse_array (blobmsg.c:159)
   by 0x400AB8: test_blobmsg (tests/test-blobmsg-parse.c:69)
   by 0x400AB8: main (tests/test-blobmsg-parse.c:82)

 Conditional jump or move depends on uninitialised value(s)
   at 0x54524A0: blobmsg_check_name (blobmsg.c:42)
   by 0x54524A0: blobmsg_check_attr_len (blobmsg.c:79)
   by 0x5452710: blobmsg_parse_array (blobmsg.c:159)
   by 0x400AB8: test_blobmsg (tests/test-blobmsg-parse.c:69)
   by 0x400AB8: main (tests/test-blobmsg-parse.c:82)

Ref: http://lists.infradead.org/pipermail/openwrt-devel/2020-January/021204.html
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg_json: prefer snprintf usage
Petr Štetiar [Tue, 14 Jan 2020 08:05:02 +0000 (09:05 +0100)]
blobmsg_json: prefer snprintf usage

Better safe than sorry and while at it prefer use of PRId16 and PRId32
formatting constants as well.

Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: blobmsg_vprintf: prefer vsnprintf
Petr Štetiar [Tue, 14 Jan 2020 07:57:05 +0000 (08:57 +0100)]
blobmsg: blobmsg_vprintf: prefer vsnprintf

Better safe than sorry and while at it add handling of possible
*printf() failures.

Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agojshn: prefer snprintf usage
Petr Štetiar [Tue, 14 Jan 2020 07:55:34 +0000 (08:55 +0100)]
jshn: prefer snprintf usage

Better safe than sorry.

Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agocmake: add a possibility to set library version
Petr Štetiar [Fri, 10 Jan 2020 21:00:04 +0000 (22:00 +0100)]
cmake: add a possibility to set library version

Add a new `ABIVERSION` define which allows to control the SOVERSION used
for the built shared library. This is needed for downstream packaging to
properly track breaking ABI changes when updating to newer versions of
the library.

Suggested-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: blobmsg_add_json_element() 64-bit values
Dainis Jonitis [Fri, 10 Jan 2020 14:41:04 +0000 (16:41 +0200)]
blobmsg: blobmsg_add_json_element() 64-bit values

libjson-c json_type_int values are stored as int64_t. Use
json_object_get_int64() instead of json_object_get_int()
to avoid clamping to INT32_MAX.

Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Dainis Jonitis <dainis.jonitis@ubnt.com>
[fixed author to match SoB, added unit test results]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg_json: fix int16 serialization
Petr Štetiar [Sun, 12 Jan 2020 21:40:18 +0000 (22:40 +0100)]
blobmsg_json: fix int16 serialization

int16 blobmsg type is currently being serialized as uint16_t due to
missing cast during JSON output.

Following blobmsg content:

 bar-min: -32768 (i16)
 bar-max: 32767 (i16)

Produces following JSON:

 { "bar-min":32768,"bar-max":32767 }

Whereas one would expect:

 { "bar-min":-32768,"bar-max":32767 }

Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: blobmsg/json: add more test cases
Petr Štetiar [Sun, 12 Jan 2020 14:31:49 +0000 (15:31 +0100)]
tests: blobmsg/json: add more test cases

 * add missing test with sanitizers
 * add test case for blobmsg_add_json_from_string
 * add test cases for all numeric types
 * print types for each variable

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: include json script shunit2 based testing
Petr Štetiar [Wed, 8 Jan 2020 18:47:22 +0000 (19:47 +0100)]
tests: include json script shunit2 based testing

Include shunit2 based tests into unit testing pipeline until
(eventually) it's converted to cram based unit tests.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: fix wrong payload len passed from blobmsg_check_array
Petr Štetiar [Sat, 28 Dec 2019 18:00:39 +0000 (19:00 +0100)]
blobmsg: fix wrong payload len passed from blobmsg_check_array

Fix incorrect use of blob_raw_len() on passed blobmsg to
blobmsg_check_array_len()  introduced in commit b0e21553ae8c ("blobmsg:
add _len variants for all attribute checking methods") by using correct
blobmsg_len().

This wrong (higher) length was then for example causing issues in
procd's instance_config_parse_command() where blobmsg_check_attr_list()
was failing sanity checking of service command, thus resulting in the
startup failures of some services like collectd, nlbwmon and samba4.

Ref: http://lists.infradead.org/pipermail/openwrt-devel/2019-December/020840.html
Fixes: b0e21553ae8c ("blobmsg: add _len variants for all attribute checking methods")
Reported-by: Hannu Nyman <hannu.nyman@welho.com>
Tested-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: fix array out of bounds GCC 10 warning
Petr Štetiar [Wed, 25 Dec 2019 09:27:59 +0000 (10:27 +0100)]
blobmsg: fix array out of bounds GCC 10 warning

Fixes following warning reported by GCC 10.0.0 20191203:

 blobmsg.c:234:2: error: 'strcpy' offset 6 from the object at 'attr' is out of the bounds of referenced subobject 'name' with type 'uint8_t[0]' {aka 'unsigned char[0]'} at offset 6 [-Werror=array-bounds]
   234 |  strcpy((char *) hdr->name, (const char *)name);
       |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 In file included from blobmsg.c:16:
 blobmsg.h:42:10: note: subobject 'name' declared here
    42 |  uint8_t name[];
       |          ^~~~

Reported-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: reuse blobmsg_namelen in blobmsg_data
Petr Štetiar [Thu, 12 Dec 2019 15:42:39 +0000 (16:42 +0100)]
blobmsg: reuse blobmsg_namelen in blobmsg_data

Move blobmsg_namelen into header file so it's possible to reuse it in
blobmsg_data.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: fuzz: fuzz _len variants of checking methods
Petr Štetiar [Wed, 11 Dec 2019 05:35:17 +0000 (06:35 +0100)]
tests: fuzz: fuzz _len variants of checking methods

In order to increase test coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: add _len variants for all attribute checking methods
Tobias Schramm [Thu, 15 Nov 2018 02:42:48 +0000 (03:42 +0100)]
blobmsg: add _len variants for all attribute checking methods

Introduce _len variants of blobmsg attribute checking functions which
aims to provide safer implementation as those functions should limit all
memory accesses performed on the blob to the range [attr, attr + len]
(upper bound non inclusive) and thus should be suited for checking of
untrusted blob attributes.

While at it add some comments in order to make it clear.

Signed-off-by: Tobias Schramm <tobleminer@gmail.com>
[_safe -> _len, blobmsg_check_array_len fix, commit subject/desc facelift]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoReplace use of blobmsg_check_attr by blobmsg_check_attr_len
Tobias Schramm [Tue, 13 Nov 2018 03:16:12 +0000 (04:16 +0100)]
Replace use of blobmsg_check_attr by blobmsg_check_attr_len

blobmsg_check_attr_len adds a length limit specifying the max offset
from attr that can be read safely.

Signed-off-by: Tobias Schramm <tobleminer@gmail.com>
[rebased and reworked, line wrapped commit message, _safe -> _len]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoEnsure blob_attr length check does not perform out of bounds reads
Tobias Schramm [Wed, 28 Nov 2018 12:39:29 +0000 (13:39 +0100)]
Ensure blob_attr length check does not perform out of bounds reads

Before there might have been as little as one single byte left which
would result in 3 bytes of blob_attr->id_len being out of bounds.

Acked-by: Yousong Zhou <yszhou4tech@gmail.com>
Signed-off-by: Tobias Schramm <tobleminer@gmail.com>
[line wrapped < 72 chars]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: fix heap buffer overflow in blobmsg_parse
Petr Štetiar [Tue, 10 Dec 2019 11:02:40 +0000 (12:02 +0100)]
blobmsg: fix heap buffer overflow in blobmsg_parse

Fixes following error found by the fuzzer:

 ==29774==ERROR: AddressSanitizer: heap-buffer-overflow
 READ of size 1 at 0x6020004f1c56 thread T0
     #0 strcmp sanitizer_common_interceptors.inc:442:3
     #1 blobmsg_parse blobmsg.c:168:8

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg: make blobmsg_len and blobmsg_data_len return unsigned value
Petr Štetiar [Tue, 10 Dec 2019 10:53:23 +0000 (11:53 +0100)]
blobmsg: make blobmsg_len and blobmsg_data_len return unsigned value

One usually doesn't guard against negative length values in the code.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: add test cases for blobmsg parsing
Petr Štetiar [Tue, 10 Dec 2019 10:51:43 +0000 (11:51 +0100)]
tests: add test cases for blobmsg parsing

Increasing test coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotest: fuzz: add blobmsg_check_attr crashes
Petr Štetiar [Tue, 10 Dec 2019 13:58:40 +0000 (14:58 +0100)]
test: fuzz: add blobmsg_check_attr crashes

 ==31775==ERROR: AddressSanitizer: SEGV on unknown address 0x604000a7c715
 ==31775==The signal is caused by a READ memory access.
    #0 blobmsg_check_attr blobmsg.c:48:6
    #1 blobmsg_parse_array blobmsg.c:118:8
    #2 fuzz_blobmsg_parse test-blobmsg-parse-fuzzer.c:35:2

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblob: fix OOB access in blob_check_type
Petr Štetiar [Mon, 9 Dec 2019 14:27:16 +0000 (15:27 +0100)]
blob: fix OOB access in blob_check_type

Found by fuzzer:

 ERROR: AddressSanitizer: SEGV on unknown address 0x602100000455
 The signal is caused by a READ memory access.
     #0 in blob_check_type blob.c:214:43
     #1 in blob_parse_attr blob.c:234:9
     #2 in blob_parse_untrusted blob.c:272:12
     #3 in fuzz_blob_parse tests/fuzzer/test-blob-parse-fuzzer.c:34:2
     #4 in LLVMFuzzerTestOneInput tests/fuzzer/test-blob-parse-fuzzer.c:39:2

Caused by following line:

if (type == BLOB_ATTR_STRING && data[len - 1] != 0)

where len was pointing outside of the data buffer.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: use blob_parse_untrusted variant
Petr Štetiar [Mon, 9 Dec 2019 13:47:40 +0000 (14:47 +0100)]
tests: use blob_parse_untrusted variant

In order to be able to use invalid input for testing as well.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblob: introduce blob_parse_untrusted
Petr Štetiar [Mon, 9 Dec 2019 13:11:45 +0000 (14:11 +0100)]
blob: introduce blob_parse_untrusted

blob_parse can be only used on trusted input as it has no possibility to
check the length of the provided input buffer, which might lead to
undefined behaviour and/or crashes when supplied with malformed,
corrupted or otherwise specially crafted input.

So this introduces blob_parse_untrusted variant which expects additional
input buffer length argument and thus should be able to process also
inputs from untrusted sources.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblob: refactor attr parsing into separate function
Petr Štetiar [Mon, 9 Dec 2019 12:53:27 +0000 (13:53 +0100)]
blob: refactor attr parsing into separate function

Making blob_parse easier to review.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotest: fuzz: add blob_parse crashes
Petr Štetiar [Tue, 10 Dec 2019 16:12:07 +0000 (17:12 +0100)]
test: fuzz: add blob_parse crashes

==5872==ERROR: AddressSanitizer: SEGV on unknown address 0x6020004100b4
==5872==The signal is caused by a READ memory access.
    #0 blob_data blob.h
    #1 blob_parse blob.c:228:2

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: add test cases for blob parsing
Petr Štetiar [Mon, 9 Dec 2019 12:28:25 +0000 (13:28 +0100)]
tests: add test cases for blob parsing

Increasing test coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: add libFuzzer based tests
Petr Štetiar [Sun, 8 Dec 2019 14:11:02 +0000 (15:11 +0100)]
tests: add libFuzzer based tests

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.

Lets use libFuzzer to fuzz blob and blobmsg parsing for the start.

Ref: https://llvm.org/docs/LibFuzzer.html
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: add unit tests covered with Clang sanitizers
Petr Štetiar [Sun, 8 Dec 2019 12:12:47 +0000 (13:12 +0100)]
tests: add unit tests covered with Clang sanitizers

Currently we run all tests via Valgrind. This patch adds 2nd batch of
tests which are compiled with Clang AddressSanitizer[1],
LeakSanitizer[2] and UndefinedBehaviorSanitizer[3] in order to catch
more issues during QA on CI.

AddressSanitizer is a fast memory error detector.  The tool can detect
the following types of bugs:

 * Out-of-bounds accesses to heap, stack and globals
 * Use-after-free, use-after-return, use-after-scope
 * Double-free, invalid free

LeakSanitizer is a run-time memory leak detector. It can be combined
with AddressSanitizer to get both memory error and leak detection, or
used in a stand-alone mode.

UndefinedBehaviorSanitizer (UBSan) is a fast undefined behavior
detector. UBSan modifies the program at compile-time to catch various
kinds of undefined behavior during program execution, for example:

 * Using misaligned or null pointer
 * Signed integer overflow
 * Conversion to, from, or between floating-point types which would
   overflow the destination

1. http://clang.llvm.org/docs/AddressSanitizer.html
2. http://http://clang.llvm.org/docs/LeakSanitizer.html
3. http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agocmake: add more hardening compiler flags
Petr Štetiar [Sat, 7 Dec 2019 12:29:05 +0000 (13:29 +0100)]
cmake: add more hardening compiler flags

In order to spot possible issues with direct impact on security during
QA on CI (GCC version 6 and higher).

Ref: https://developers.redhat.com/blog/2018/03/21/compiler-and-linker-flags-gcc/
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg/ulog: fix format string compiler warnings
Petr Štetiar [Sat, 7 Dec 2019 12:34:25 +0000 (13:34 +0100)]
blobmsg/ulog: fix format string compiler warnings

Fixes following compiler warnings:

 blobmsg.c:242:39: error: format string is not a string literal [-Werror,-Wformat-nonliteral]
 blobmsg.c:248:23: error: format string is not a string literal [-Werror,-Wformat-nonliteral]
 ulog.c:100:18: error: format string is not a string literal [-Werror,-Wformat-nonliteral]
 ulog.c:112:16: error: format string is not a string literal [-Werror,-Wformat-nonliteral]
 ulog.c:117:20: error: format string is not a string literal [-Werror,-Wformat-nonliteral]

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agocmake: use extra compiler warnings only on gcc6+
Petr Štetiar [Tue, 26 Nov 2019 07:32:57 +0000 (08:32 +0100)]
cmake: use extra compiler warnings only on gcc6+

gcc version 4.8.4 (Ubuntu 14.04) and -Wextra produces following:

 json_script.c:124:3: error: missing initializer for field 'name' of 'struct blobmsg_policy' [-Werror=missing-field-initializers]

Reported-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agotests: jshn: add more test cases
Petr Štetiar [Sat, 23 Nov 2019 22:51:20 +0000 (23:51 +0100)]
tests: jshn: add more test cases

In order to cover all command line options.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agojshn: fix missing usage for -p and -o arguments
Petr Štetiar [Sat, 23 Nov 2019 22:40:48 +0000 (23:40 +0100)]
jshn: fix missing usage for -p and -o arguments

Add missing usage hints for -p and -o arguments.

Fixes: e16fa068a573 ("jshn: add support for namespaces")
Fixes: eb30a03048f8 ("libubox, jshn: add option to write output to a file")
Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agojshn: fix off by one in jshn_parse_file
Petr Štetiar [Sat, 23 Nov 2019 21:48:25 +0000 (22:48 +0100)]
jshn: fix off by one in jshn_parse_file

Fixes following error:

 Invalid read of size 1
   at 0x4C32D04: strlen
   by 0x5043367: json_tokener_parse_ex
   by 0x5045316: json_tokener_parse_verbose
   by 0x504537D: json_tokener_parse
   by 0x401AB1: jshn_parse (jshn.c:179)
   by 0x40190D: jshn_parse_file (jshn.c:370)
   by 0x40190D: main (jshn.c:434)
 Address 0x5848c4c is 0 bytes after a block of size 1,036 alloc'd
   at 0x4C2FB0F: malloc
   by 0x4018E2: jshn_parse_file (jshn.c:357)
   by 0x4018E2: main (jshn.c:434)

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agojshn: jshn_parse: fix leaks of memory pointed to by 'obj'
Petr Štetiar [Tue, 19 Nov 2019 13:09:43 +0000 (14:09 +0100)]
jshn: jshn_parse: fix leaks of memory pointed to by 'obj'

Fixes following leaks of memory:

 352 (72 direct, 280 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
   at 0x4C31B25: calloc
   by 0x5042E1F: json_object_new_array
   by 0x5044B02: json_tokener_parse_ex
   by 0x5045316: json_tokener_parse_verbose
   by 0x504537D: json_tokener_parse
   by 0x401AA9: jshn_parse (jshn.c:179)
   by 0x401977: main (jshn.c:378)

 752 (72 direct, 680 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
   at 0x4C31B25: calloc
   by 0x50424CF: json_object_new_object
   by 0x5044B38: json_tokener_parse_ex
   by 0x5045316: json_tokener_parse_verbose
   by 0x504537D: json_tokener_parse
   by 0x401AA9: jshn_parse (jshn.c:179)
   by 0x401977: main (jshn.c:380)

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agojshn: main: fix leak of memory pointed to by 'vars'
Petr Štetiar [Tue, 19 Nov 2019 11:34:14 +0000 (12:34 +0100)]
jshn: main: fix leak of memory pointed to by 'vars'

Fixes following leak of memory:

 6,016 bytes in 1 blocks are possibly lost in loss record 1 of 1
    at 0x4C31B25: calloc
    by 0x1098F8: main (jshn.c:353)

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agojshn: refactor main into smaller pieces
Petr Štetiar [Sat, 23 Nov 2019 21:27:46 +0000 (22:27 +0100)]
jshn: refactor main into smaller pieces

Turn longer switch cases into separate functions in order to make it
easier to follow. Don't return from the cases as it makes future
cleaning up harder.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoavl: guard against theoretical null pointer dereference
Petr Štetiar [Wed, 20 Nov 2019 08:31:08 +0000 (09:31 +0100)]
avl: guard against theoretical null pointer dereference

clang-10 analyzer reports following:

 avl.c:671:25: warning: Access to field 'parent' results in a dereference of a null pointer (loaded from field 'right')
     node->right->parent = parent;
           ~~~~~         ^

Which seems to be impossible to trigger via exported AVL public API, but
it could be probably trigerred by fiddling with the AVL tree node struct
members manually as they are exposed.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoblobmsg_json: fix possible uninitialized struct member
Petr Štetiar [Tue, 19 Nov 2019 16:34:25 +0000 (17:34 +0100)]
blobmsg_json: fix possible uninitialized struct member

clang-10 analyzer reports following:

 blobmsg_json.c:285:2: warning: The expression is an uninitialized value. The computed value will also be garbage
         s->indent_level++;
         ^~~~~~~~~~~~~~~~~

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agobase64: fix possible null pointer dereference
Petr Štetiar [Tue, 19 Nov 2019 16:16:40 +0000 (17:16 +0100)]
base64: fix possible null pointer dereference

clang-10 analyzer reports following:

 base64.c:325:20: warning: Array access (from variable 'target') results in a null pointer dereference
                 target[tarindex] = 0;
                 ~~~~~~           ^

and prepared test case confirms it:

 Invalid write of size 1
    at 0x4E4463F: b64_decode (base64.c:325)
    by 0x40088C: test_invalid_inputs (tests/test-base64.c:26)
    by 0x40088C: main (tests/test-base64.c:32)
  Address 0x1 is not stack'd, malloc'd or (recently) free'd

 Process terminating with default action of signal 11 (SIGSEGV)
  Access not within mapped region at address 0x1
    at 0x4E4463F: b64_decode (base64.c:325)
    by 0x40088C: test_invalid_inputs (tests/test-base64.c:26)
    by 0x40088C: main (tests/test-base64.c:32)

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoadd assert.h component
Petr Štetiar [Wed, 20 Nov 2019 17:02:39 +0000 (18:02 +0100)]
add assert.h component

In order to allow seamless assert() usage in release builds without the
need for fiddling with CMake C flags as CMake adds -DNDEBUG switch in
release builds which disable assert().

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoadd cram based unit tests
Petr Štetiar [Tue, 19 Nov 2019 13:31:44 +0000 (14:31 +0100)]
add cram based unit tests

For improved QA etc. For the start with initial test cases for avl,
base64, jshn and list components. Moved runqueue and blobmsg from
examples to tests.  Converted just a few first test cases from
json-script example into the new cram based unit test, more to come.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoadd initial GitLab CI support
Petr Štetiar [Fri, 27 Sep 2019 21:24:44 +0000 (23:24 +0200)]
add initial GitLab CI support

Uses currently proof-of-concept openwrt-ci[1] in order to:

 * improve the quality of the codebase in various areas
 * decrease code review time and help merging contributions faster
 * get automagic feedback loop on various platforms and tools
   - out of tree build with OpenWrt SDK on following targets:
     * ath79-generic
     * imx6-generic
     * malta-be
     * mvebu-cortexa53
   - out of tree native build on x86/64 with GCC (versions 7, 8, 9) and Clang 10
   - out of tree native x86/64 static code analysis with cppcheck and
     scan-build from Clang 10

1. https://gitlab.com/ynezz/openwrt-ci/

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoenable extra compiler checks
Petr Štetiar [Mon, 10 Jun 2019 06:45:56 +0000 (08:45 +0200)]
enable extra compiler checks

Let's enforce additional automatic checks enforced by the compiler in
order to catch possible errors during compilation.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agoiron out all extra compiler warnings
Petr Štetiar [Mon, 10 Jun 2019 06:47:38 +0000 (08:47 +0200)]
iron out all extra compiler warnings

gcc-9 on x86/64 has reported following issues:

 base64.c:173:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:230:18: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:238:18: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:242:22: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:252:18: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:256:22: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:266:18: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:315:27: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 base64.c:329:15: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 blob.c:207:11: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 blob.c:210:11: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 blob.c:243:31: error: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Werror=sign-compare]
 blob.c:246:31: error: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Werror=sign-compare]
 blob.h:245:37: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 blob.h:253:37: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 blobmsg.h:269:37: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 blobmsg_json.c:155:10: error: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
 examples/../blob.h:245:37: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 examples/../blobmsg.h:269:37: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Werror=sign-compare]
 json_script.c:590:7: error: this statement may fall through [-Werror=implicit-fallthrough=]

Signed-off-by: Petr Štetiar <ynezz@true.cz>
4 years agovlist: add more macros for loop iteration
Yousong Zhou [Tue, 29 Oct 2019 07:24:20 +0000 (07:24 +0000)]
vlist: add more macros for loop iteration

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
4 years agolibubox, jshn: add option to write output to a file
Roman Yeryomin [Fri, 13 Sep 2019 22:22:48 +0000 (01:22 +0300)]
libubox, jshn: add option to write output to a file

This would allow board_config_flush to run one command instead
of two and would be faster and safer than redirecting output
and moving a file between filesystems.

Originally discussed here:
http://lists.openwrt.org/pipermail/openwrt-devel/2017-December/010127.html

Signed-off-by: Roman Yeryomin <roman@advem.lv>
4 years agoustream: Add format string checks to ustream_(v)printf()
Hauke Mehrtens [Sun, 9 Jun 2019 11:00:21 +0000 (13:00 +0200)]
ustream: Add format string checks to ustream_(v)printf()

This tells the compiler that these functions are takeing a format
string, the compiler will now do additional checks and is able to emitt
a compile warning in case the format string is not valid.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
4 years agolibubox: add format string checking to ulog()
Kristupas Savickas [Thu, 6 Jun 2019 18:28:32 +0000 (21:28 +0300)]
libubox: add format string checking to ulog()

This offers an increased level of security, as the arguments will be
checked for validity against the format string at compile time. The
format attribute is supported by both GCC and Clang, so there shouldn't
be any portability issues.

Signed-off-by: Kristupas Savickas <savickas.kristupas@gmail.com>
5 years agoblobmsg_json: blobmsg_format_string: do not escape '/'
Yousong Zhou [Wed, 27 Feb 2019 02:48:47 +0000 (02:48 +0000)]
blobmsg_json: blobmsg_format_string: do not escape '/'

Resolves FS#2147

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
5 years agofix segfault when passed blobmsg attr is NULL
John Crispin [Wed, 25 Jul 2018 08:30:05 +0000 (10:30 +0200)]
fix segfault when passed blobmsg attr is NULL

Signed-off-by: John Crispin <john@phrozen.org>
5 years agoutils: add const_* byteswapping functions
Felix Fietkau [Thu, 7 Jun 2018 13:18:51 +0000 (15:18 +0200)]
utils: add const_* byteswapping functions

Some gcc versions have issues with the __builtin_choose_expr construct
which attempts to automatically use the const versions of those
functions.

Make it possible to explicitly use const_* versions to avoid that.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agoutils: fix build error with g++
Felix Fietkau [Thu, 12 Apr 2018 08:26:22 +0000 (10:26 +0200)]
utils: fix build error with g++

g++ does not support __builtin_choose_expr, so we can't support
byte swapping as constant expression there.

Reported-by: Cleynhens Stijn <Stijn.Cleynhens@technicolor.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agoswitch from typeof to the more portable __typeof__
Felix Fietkau [Sat, 7 Apr 2018 13:21:25 +0000 (15:21 +0200)]
switch from typeof to the more portable __typeof__

Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agoutils: ensure that byte-order conversion functions evaluate the argument only once
Felix Fietkau [Sat, 7 Apr 2018 08:43:48 +0000 (10:43 +0200)]
utils: ensure that byte-order conversion functions evaluate the argument only once

Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agojshn: fix format string for int64 type
Felix Fietkau [Sat, 7 Apr 2018 08:36:38 +0000 (10:36 +0200)]
jshn: fix format string for int64 type

Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agoutils: use constant byte-order conversion
Felix Fietkau [Wed, 21 Mar 2018 16:53:40 +0000 (17:53 +0100)]
utils: use constant byte-order conversion

Simplifies portability and ensures that cpu_to_* can be used in const
declarations. If the architecture has special instructions, the compiler
should be able to detect the pattern and use them.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
6 years agolibubox: Plug a small memory leak.
Rosen Penev [Fri, 2 Feb 2018 06:52:12 +0000 (22:52 -0800)]
libubox: Plug a small memory leak.

va_end was not called if calloc fails.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
6 years agosh/jshn.sh: add json_for_each_item()
Hans Dedecker [Thu, 1 Feb 2018 15:41:27 +0000 (16:41 +0100)]
sh/jshn.sh: add json_for_each_item()

Function usefull to iterate through the different elements of an
array or object; the provided callback function is called for each
element which is passed the value, key and user provided arguments.
For field types different from array or object the callback is called
with the retrieved value.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Acked-by: Jo-Philipp Wich <jo@mein.io>
6 years agojshn: add functionality to read big JSON
Christian Beier [Thu, 18 Jan 2018 20:21:09 +0000 (21:21 +0100)]
jshn: add functionality to read big JSON

The existing read functionality feeds the complete JSON to jshn as a
cmdline argument, leading to `-ash: jshn: Argument list too long`
errors for JSONs bigger than ca. 100KB.

This commit adds the ability to read the JSON directly from a file if
wanted, removing this shell-imposed size limit.

Tested on x86-64 and ar71xx. An mmap()-based solution was also evaluated,
but found to make no performance difference on either platform.

Signed-off-by: Christian Beier <dontmind@freeshell.org>
6 years agojshn: properly support JSON "null" type
Jo-Philipp Wich [Sun, 7 Jan 2018 14:46:31 +0000 (15:46 +0100)]
jshn: properly support JSON "null" type

Instead of abort parsing, properly deal with "null" values by implementing
support for reading and formatting such values.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
6 years agojshn: read and write 64-bit integers
Christian Beier [Sat, 21 Oct 2017 23:42:29 +0000 (01:42 +0200)]
jshn: read and write 64-bit integers

This allows for reading in and writing out bigger JSON Numbers.

Following test script (that fails to print correct values _without_ this
commit) verifies the functionality (tested on x86-64 as well as on ar71xx):

---snip---
# assumes you built jshn and sourced jshn.sh
echo testing reading-in JSON
SHELL_BIGNUM=12147483647
json_init
json_load "{ \"bignum\": $SHELL_BIGNUM }"
json_get_var BIGNUM bignum
echo jshn bignum: $BIGNUM
echo shll bignum: $SHELL_BIGNUM
echo testing writing-out JSON
json_init
json_add_int bigint $SHELL_BIGNUM
json_dump
--snap---

Signed-off-by: Christian Beier <dontmind@freeshell.org>
6 years agoutils: nuke bitfield functions and macros
Stijn Tintel [Thu, 17 Aug 2017 13:50:03 +0000 (15:50 +0200)]
utils: nuke bitfield functions and macros

The bitfield functions and macros were committed without explaining
their purpose in the commit message.

As they are only used in uci, and conflict with similar functions added
in hostapd, breaking our hostapd ubus patch, nuke them from libubox and
add them in uci instead.

If we need them anywhere else in the future we can add it to libubox
again, but preferably prefixed with ubox_.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>