Commit graph

483 commits

Author SHA1 Message Date
Peter Seiderer
2e52c7e9a9 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>
2021-03-02 12:06:24 +00:00
Rui Salvaterra
5bc0146a1d utils: simplify mkdir_p boolean conditions
Just a trivial simplification.

Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
2020-12-13 12:05:45 +00:00
Daniel Golle
357877693c 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>
2020-12-12 22:50:50 +00:00
Daniel Golle
9e52171d70 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>
2020-08-06 14:29:36 +01:00
Karl Palsson
f4e9bf73ac 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>
2020-07-11 11:15:12 +02:00
Karl Palsson
53b9a2123f 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>
2020-07-11 11:15:12 +02:00
Karl Palsson
c0941d3289 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>
2020-07-11 11:15:12 +02:00
Karl Palsson
161c25960b 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>
2020-07-11 11:15:12 +02:00
Rafał Miłecki
e85cb73976 blobmsg: drop old comment about json formatting functions
Those functions were moved out of blobmsg.h.

Fixes: 0918243e90 ("move json formatting to the blobmsg_json library")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2020-05-26 10:52:32 +02:00
Felix Fietkau
66195aee50 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>
2020-05-26 10:06:53 +02:00
Felix Fietkau
639c29d197 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>
2020-05-26 10:06:53 +02:00
Felix Fietkau
c2fc622b77 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>
2020-05-26 10:06:53 +02:00
Petr Štetiar
cf2e8eb485 tests: add fuzzer seed file for crash in blob_len
Following regression was introduced in commit 5e75160f48 ("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>
2020-05-26 09:48:07 +02:00
Matthias Schiffer
86818eaa97
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>
2020-05-24 16:54:37 +02:00
Rafał Miłecki
5e75160f48 blobmsg: fix attrs iteration in the blobmsg_check_array_len()
Starting with 75e300aeec ("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 cd75136b13 ("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: 75e300aeec ("blobmsg: fix wrong payload len passed from blobmsg_check_array")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2020-05-24 15:22:58 +02:00
Petr Štetiar
eeddf22d9c 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>
2020-05-21 16:28:29 +02:00
Alban Bedel
89fb6136ad 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>
2020-05-21 15:58:46 +02:00
Chris Nisbet
1db3e7df31 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>
2020-05-21 13:44:08 +02:00
Petr Štetiar
7c4ef0d9ae tests: list: add test case for list_empty iterator
Increasing unit testing code coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-05-21 13:43:00 +02:00
Chris Nisbet
7da66430de 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>
2020-02-27 21:56:20 +01:00
Chris Nisbet
75e300aeec 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 379cd33d19
("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: 379cd33d19 ("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>
2020-02-27 21:56:01 +01:00
Juraj Vijtiuk
43a103ff17 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>
2020-01-20 16:54:10 +01:00
Petr Štetiar
5c0faaf4f5 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>
2020-01-20 16:54:10 +01:00
Petr Štetiar
1ffa415353 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>
2020-01-20 16:54:10 +01:00
Petr Štetiar
132ecb563d 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>
2020-01-20 16:54:10 +01:00
Petr Štetiar
a2aab30fc9 jshn: prefer snprintf usage
Better safe than sorry.

Reviewed-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
2020-01-20 16:54:10 +01:00
Petr Štetiar
b0886a37f3 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>
2020-01-20 16:54:10 +01:00
Dainis Jonitis
a36ee96618 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>
2020-01-20 16:16:49 +01:00
Petr Štetiar
f0da3a4283 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>
2020-01-20 16:15:34 +01:00
Petr Štetiar
20a070f081 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>
2020-01-12 23:11:29 +01:00
Petr Štetiar
379cd33d19 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>
2020-01-12 19:17:17 +01:00
Petr Štetiar
cd75136b13 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 b0e21553ae ("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: b0e21553ae ("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>
2019-12-28 21:17:46 +01:00
Petr Štetiar
eb7eb6393d 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>
2019-12-25 17:14:32 +01:00
Petr Štetiar
86f6a5b8d1 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
586ce031ea tests: fuzz: fuzz _len variants of checking methods
In order to increase test coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2019-12-25 10:31:58 +01:00
Tobias Schramm
b0e21553ae 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>
2019-12-25 10:31:58 +01:00
Tobias Schramm
cd3059796a 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>
2019-12-25 10:31:58 +01:00
Tobias Schramm
143303149c 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
f2b2ee441a 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
4dfd24ed88 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
2df6d35e32 tests: add test cases for blobmsg parsing
Increasing test coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2019-12-25 10:31:58 +01:00
Petr Štetiar
8a34788b46 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
478597b9f9 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
325418a7a3 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
0b24e24b93 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
6d27336e4a blob: refactor attr parsing into separate function
Making blob_parse easier to review.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2019-12-25 10:31:58 +01:00
Petr Štetiar
833d25797b 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
09ee90f8d6 tests: add test cases for blob parsing
Increasing test coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
2019-12-25 10:31:58 +01:00
Petr Štetiar
436d6363a1 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>
2019-12-25 10:31:58 +01:00
Petr Štetiar
bf680707ac 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>
2019-12-25 10:31:58 +01:00