Commit graph

1006 commits

Author SHA1 Message Date
Thomas Haller
43ba2cb933 shared/strbuf: allow forward declaring "struct _NMStrBuf" 2020-04-10 10:44:39 +02:00
Thomas Haller
abacc1e919 shared/strbuf: only clear the bytes that we actually wrote to
The allocated buffes are not known to be written. It is unnecessary to
clear them.

If the user writes sensitive data to those locations, without using
the NMStrBuf API, then it is up to the user to bzero the memory
accordingly.
2020-04-10 10:44:38 +02:00
Thomas Haller
d1c2572e11 shared: add NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 define
When we have a buffer that we want to grow exponentially with
nm_utils_get_next_realloc_size(), then there are certain buffer
sizes that are better suited.

For example, if you have an empty NMStrBuf (len == 0), and you
want to allocate roughly one kilobyte, then 1024 is a bad choice,
because nm_utils_get_next_realloc_size() will give you 2024 bytes.

NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 might be better in this case.
2020-04-10 10:44:37 +02:00
Thomas Haller
ef0c289104 shared/tests: avoid undefined behavior in test_nm_utils_get_next_realloc_size() test 2020-04-10 10:27:27 +02:00
Thomas Haller
2c2ed2374f shared: fix static assert in NM_MORE_ASSERT_ONCE()
NM_MORE_ASSERTS 0 means that more assertions are disabled.
NM_MORE_ASSERT_ONCE() should never be triggered when more
assertions are disabled altogether. It is thus not allowed
to called "if (NM_MORE_ASSERT_ONCE (0))", because that code
would always be enabled.
2020-04-10 08:11:52 +02:00
Thomas Haller
be8be0f091 shared: fix crash in _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE()
If you have a LIST with 7 elements, and you lookup a value that
is not in the (sorted) list and would lie before the first element,
the binary search will dig down to imin=0, imid=0, imax=0 and
strcmp will give positive cmp value (indicating that the searched
value is sorted before).

Then, we would do "imax = imid - 1;", which wrapped to G_MAXUINT,
and the following "if (G_UNLIKELY (imin > imax))" would not hit,
resulting in an out of bound access next.

The easy fix is to not used unsigned integers.

The binary search was adapted from nm_utils_array_find_binary_search()
and nm_utils_ptrarray_find_binary_search(), which already used signed
integers to avoid this problem.

Fixes: 17d9b852c8 ('shared: explicitly implement binary search in NM_UTILS_STRING_TABLE_LOOKUP_DEFINE*()')
2020-04-10 07:57:08 +02:00
Thomas Haller
c3969425ec systemd: merge branch systemd into master 2020-04-08 09:08:49 +02:00
Thomas Haller
c5189cffc1 systemd: update code from upstream (2020-04-08)
This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=8ff8ce62845e708186077d11eba83adae7b02e61

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files -z :/src/systemd/src/ \
                :/shared/systemd/src/ \
                :/shared/nm-std-aux/unaligned.h | \
  xargs -0 rm -f

nm_copy_sd_shared() {
    mkdir -p "./shared/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1"
}

nm_copy_sd_core() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_stdaux() {
    mkdir -p "./shared/nm-std-aux/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-std-aux/${1##*/}"
}

nm_copy_sd_core "src/libsystemd-network/arp-util.c"
nm_copy_sd_core "src/libsystemd-network/arp-util.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd_core "src/libsystemd-network/lldp-internal.h"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd_core "src/libsystemd-network/lldp-network.c"
nm_copy_sd_core "src/libsystemd-network/lldp-network.h"
nm_copy_sd_core "src/libsystemd-network/network-internal.c"
nm_copy_sd_core "src/libsystemd-network/network-internal.h"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd_core "src/libsystemd-network/sd-lldp.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-source.h"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.h"
nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd_core "src/systemd/_sd-common.h"
nm_copy_sd_core "src/systemd/sd-dhcp-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp-lease.h"
nm_copy_sd_core "src/systemd/sd-dhcp-option.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd_core "src/systemd/sd-event.h"
nm_copy_sd_core "src/systemd/sd-id128.h"
nm_copy_sd_core "src/systemd/sd-ipv4acd.h"
nm_copy_sd_core "src/systemd/sd-ipv4ll.h"
nm_copy_sd_core "src/systemd/sd-lldp.h"
nm_copy_sd_core "src/systemd/sd-ndisc.h"
nm_copy_sd_shared "src/basic/alloc-util.c"
nm_copy_sd_shared "src/basic/alloc-util.h"
nm_copy_sd_shared "src/basic/async.h"
nm_copy_sd_shared "src/basic/cgroup-util.h"
nm_copy_sd_shared "src/basic/env-file.c"
nm_copy_sd_shared "src/basic/env-file.h"
nm_copy_sd_shared "src/basic/env-util.c"
nm_copy_sd_shared "src/basic/env-util.h"
nm_copy_sd_shared "src/basic/errno-util.h"
nm_copy_sd_shared "src/basic/escape.c"
nm_copy_sd_shared "src/basic/escape.h"
nm_copy_sd_shared "src/basic/ether-addr-util.c"
nm_copy_sd_shared "src/basic/ether-addr-util.h"
nm_copy_sd_shared "src/basic/extract-word.c"
nm_copy_sd_shared "src/basic/extract-word.h"
nm_copy_sd_shared "src/basic/fd-util.c"
nm_copy_sd_shared "src/basic/fd-util.h"
nm_copy_sd_shared "src/basic/fileio.c"
nm_copy_sd_shared "src/basic/fileio.h"
nm_copy_sd_shared "src/basic/format-util.c"
nm_copy_sd_shared "src/basic/format-util.h"
nm_copy_sd_shared "src/basic/fs-util.c"
nm_copy_sd_shared "src/basic/fs-util.h"
nm_copy_sd_shared "src/basic/hash-funcs.c"
nm_copy_sd_shared "src/basic/hash-funcs.h"
nm_copy_sd_shared "src/basic/hashmap.c"
nm_copy_sd_shared "src/basic/hashmap.h"
nm_copy_sd_shared "src/basic/hexdecoct.c"
nm_copy_sd_shared "src/basic/hexdecoct.h"
nm_copy_sd_shared "src/basic/hostname-util.c"
nm_copy_sd_shared "src/basic/hostname-util.h"
nm_copy_sd_shared "src/basic/in-addr-util.c"
nm_copy_sd_shared "src/basic/in-addr-util.h"
nm_copy_sd_shared "src/basic/io-util.c"
nm_copy_sd_shared "src/basic/io-util.h"
nm_copy_sd_shared "src/basic/list.h"
nm_copy_sd_shared "src/basic/log.h"
nm_copy_sd_shared "src/basic/macro.h"
nm_copy_sd_shared "src/basic/memory-util.c"
nm_copy_sd_shared "src/basic/memory-util.h"
nm_copy_sd_shared "src/basic/mempool.c"
nm_copy_sd_shared "src/basic/mempool.h"
nm_copy_sd_shared "src/basic/missing_fcntl.h"
nm_copy_sd_shared "src/basic/missing_random.h"
nm_copy_sd_shared "src/basic/missing_socket.h"
nm_copy_sd_shared "src/basic/missing_stat.h"
nm_copy_sd_shared "src/basic/missing_syscall.h"
nm_copy_sd_shared "src/basic/missing_type.h"
nm_copy_sd_shared "src/basic/parse-util.c"
nm_copy_sd_shared "src/basic/parse-util.h"
nm_copy_sd_shared "src/basic/path-util.c"
nm_copy_sd_shared "src/basic/path-util.h"
nm_copy_sd_shared "src/basic/prioq.c"
nm_copy_sd_shared "src/basic/prioq.h"
nm_copy_sd_shared "src/basic/process-util.c"
nm_copy_sd_shared "src/basic/process-util.h"
nm_copy_sd_shared "src/basic/random-util.c"
nm_copy_sd_shared "src/basic/random-util.h"
nm_copy_sd_shared "src/basic/set.h"
nm_copy_sd_shared "src/basic/signal-util.c"
nm_copy_sd_shared "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd_shared "src/basic/socket-util.c"
nm_copy_sd_shared "src/basic/socket-util.h"
nm_copy_sd_shared "src/basic/sort-util.h"
nm_copy_sd_shared "src/basic/sparse-endian.h"
nm_copy_sd_shared "src/basic/stat-util.c"
nm_copy_sd_shared "src/basic/stat-util.h"
nm_copy_sd_shared "src/basic/stdio-util.h"
nm_copy_sd_shared "src/basic/string-table.c"
nm_copy_sd_shared "src/basic/string-table.h"
nm_copy_sd_shared "src/basic/string-util.c"
nm_copy_sd_shared "src/basic/string-util.h"
nm_copy_sd_shared "src/basic/strv.c"
nm_copy_sd_shared "src/basic/strv.h"
nm_copy_sd_shared "src/basic/strxcpyx.c"
nm_copy_sd_shared "src/basic/strxcpyx.h"
nm_copy_sd_shared "src/basic/time-util.c"
nm_copy_sd_shared "src/basic/time-util.h"
nm_copy_sd_shared "src/basic/tmpfile-util.c"
nm_copy_sd_shared "src/basic/tmpfile-util.h"
nm_copy_sd_shared "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/user-util.h"
nm_copy_sd_shared "src/basic/utf8.c"
nm_copy_sd_shared "src/basic/utf8.h"
nm_copy_sd_shared "src/basic/util.c"
nm_copy_sd_shared "src/basic/util.h"
nm_copy_sd_shared "src/shared/dns-domain.c"
nm_copy_sd_shared "src/shared/dns-domain.h"
nm_copy_sd_shared "src/shared/web-util.c"
nm_copy_sd_shared "src/shared/web-util.h"
nm_copy_sd_stdaux "src/basic/unaligned.h"
2020-04-08 09:02:12 +02:00
Antonio Cardace
93e38cbe56
nm-setting-bridge: add 'group-address' bridge option
Also add related unit test.

https://bugzilla.redhat.com/show_bug.cgi?id=1755768
2020-04-06 09:56:11 +02:00
Thomas Haller
5cc7abd7a4 shared: add nm_utils_escaped_tokens_options_*() API
This will be used for splitting and escaping option parameters in
nmcli (vpn.data).
2020-04-04 19:51:34 +02:00
Thomas Haller
d1a9c2bd42 shared: add flags for nm_utils_escaped_tokens_escape_full()
Add flags to explicitly escape leading or trailing spaces. Note
that we were already escaping trailing spaces.

This will be used later when supporting backslash escapes for
option parameters for nmcli (vpn.data).
2020-04-04 19:51:34 +02:00
Thomas Haller
ab9dc9f6d4 shared: refactor initializing character lookup tables for strsplit 2020-04-04 19:51:34 +02:00
Thomas Haller
484d44fc87 shared/trivial: improve code comments about NMUtilsStrsplitSetFlags flags 2020-04-04 19:51:34 +02:00
Thomas Haller
76784e0c97 shared: add nm_str_is_stripped() util 2020-04-04 19:51:34 +02:00
Thomas Haller
5f6dfcfc92 shared/tests: add nmtst_get_rand_word_length()
Will be used to get a random number with a certain distribution,
that suitable to generate input values.
2020-04-04 19:51:34 +02:00
Thomas Haller
63545d31ca shared: add nm_g_hash_table_*() utils for accepting %NULL hash argument 2020-04-04 19:51:34 +02:00
Thomas Haller
55a058aeef libnmm,shared: extract and move nm_utils_strdict_to_variant_ass() to shared
This is a helper function that converts a string dictionary to an "a{ss}"
GVariant. It is generally useful, and should be independent from the
caller.
2020-04-04 19:51:34 +02:00
Thomas Haller
09dcb18381 shared: use NMStrBuf in _nm_utils_enum_to_str_full()
Just for showcase and to hit the code from the unit-tests
that we have.

Also, just to show, the following runs about 25 % faster than before,
which isn't bad for such a simple replacement.

    {
         GType gtype = nm_test_general_color_flags_get_type ();
         const int N_RUN = 1000000;
         int i_run;
         guint8 c = 0;

         for (i_run = 0; i_run < N_RUN; i_run++) {
              gs_free char *str = NULL;

              str = _nm_utils_enum_to_str_full (gtype, i_run % 10, ",", NULL);
              c += str[0];
         }
         return c % 3;
    }

$ perf stat -r 200 -B libnm-core/tests/test-general

Before:

 Performance counter stats for 'libnm-core/tests/test-general' (200 runs):

            204.48 msec task-clock:u              #    0.997 CPUs utilized            ( +-  0.53% )
                 0      context-switches:u        #    0.000 K/sec
                 0      cpu-migrations:u          #    0.000 K/sec
               267      page-faults:u             #    0.001 M/sec                    ( +-  0.05% )
       702,987,494      cycles:u                  #    3.438 GHz                      ( +-  0.54% )
     1,698,874,415      instructions:u            #    2.42  insn per cycle           ( +-  0.00% )
       410,394,229      branches:u                # 2006.970 M/sec                    ( +-  0.00% )
         1,770,484      branch-misses:u           #    0.43% of all branches          ( +-  0.40% )

           0.20502 +- 0.00108 seconds time elapsed  ( +-  0.53% )

After:

 Performance counter stats for 'libnm-core/tests/test-general' (200 runs):

            155.71 msec task-clock:u              #    0.996 CPUs utilized            ( +-  0.50% )
                 0      context-switches:u        #    0.000 K/sec
                 0      cpu-migrations:u          #    0.000 K/sec
               266      page-faults:u             #    0.002 M/sec                    ( +-  0.05% )
       539,994,118      cycles:u                  #    3.468 GHz                      ( +-  0.49% )
     1,116,016,733      instructions:u            #    2.07  insn per cycle           ( +-  0.00% )
       283,974,158      branches:u                # 1823.760 M/sec                    ( +-  0.00% )
         1,377,786      branch-misses:u           #    0.49% of all branches          ( +-  0.43% )

          0.156255 +- 0.000786 seconds time elapsed  ( +-  0.50% )
2020-04-03 11:31:12 +02:00
Thomas Haller
d5d7b4781e shared: pre-allocate GString with 16 bytes for _nm_utils_enum_to_str_full()
In the next commit, GString will be replaced by NMStrBuf. Then, we will
pre-allocate a string buffer with 16 bytes, and measure the performance
difference. To have it comparable, adjust the pre-allocation size also
with GString.
2020-04-03 11:31:12 +02:00
Thomas Haller
686b58571b shared: use NMStrBuf for implementing nm_utils_str_utf8safe_unescape() 2020-04-03 11:31:12 +02:00
Thomas Haller
beec47e70a shared: use nm_utils_buf_utf8safe_unescape() for nm_utils_str_utf8safe_unescape()
nm_utils_buf_utf8safe_unescape() is almost the same as g_strcompress(),
with the only difference is that if the string contains NUL escapes "\000",
it will be handled correctly.

In other words, g_strcompress() and nm_utils_str_utf8safe_unescape() can only
unescape values, that contain no NUL escapes. That's why we added our
own binary unescape function.

As we already have our g_strcompress() variant, use it. It just gives it more
testing and usage. Also, we have full control over it's behavior. For example,
g_strcompress() issues a g_warning() when encountering a trailing '\\'. I
think this makes it unsuitable to unescape untrusted data. Either the function
should fail, or just make the best of it. Currently, our implementation
does the latter.
2020-04-03 11:31:12 +02:00
Thomas Haller
27e788cce8 shared: add NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET flag
The new flag tells that as we re-allocate data buffers during
escaping, we bzero the memory to avoid leaking secrets.
2020-04-03 11:31:12 +02:00
Thomas Haller
eda47170ed shared: add NMStrBuf util
Our own implementation of a string buffer like GString.

Advantages (in decreasing relevance):

- Since we are in control, we can easily let it nm_explicit_bzero()
  the memory. The regular GString API cannot be used in such a case.
  While nm_explicit_bzero() may or may not be of questionable benefit,
  the problem is that if the underlying API counteracts the aim of
  clearing memory, it gets impossible. As API like NMStrBuf supports
  it, clearing memory is a easy as enable the right flag.
  This would for example be useful for example when we read passwords
  from a file or file descriptor (e.g. try_spawn_vpn_auth_helper()).

- We have API like

    nmp_object_to_string (const NMPObject *obj,
                          NMPObjectToStringMode to_string_mode,
                          char *buf,
                          gsize buf_size);

  which accept a fixed size output buffer. This has the problem of
  how choosing the right sized buffer. With NMStrBuf such API could
  be instead

    nmp_object_to_string (const NMPObject *obj,
                          NMPObjectToStringMode to_string_mode,
                          NMStrBuf *buf);

  which can automatically grow (using heap allocation). It would be
  easy to extend NMStrBuf to use a fixed buffer or limiting the
  maximum string length. The point is, that the to-string API wouldn't
  have to change. Depending on the NMStrBuf passed in, you can fill
  an unbounded heap allocated string, a heap allocated string up to
  a fixed length, or a static string of fixed length. NMStrBuf currently
  only implements the unbounded heap allocate string case, but it would
  be simple to extend.

  Note that we already have API like nm_utils_strbuf_*() to fill a buffer
  of fixed size. GString is not useable for that (efficiently), hence
  this API exists. NMStrBuf could be easily extended to replace this API
  without usability or performance penalty. So, while this adds one new
  API, it could replace other APIs.

- GString always requires a heap allocation for the container. In by far
  most of the cases where we use GString, we use it to simply construct
  a string dynamically. There is zero use for this overhead. If one
  really needs a heap allocated buffer, NMStrBuf can easily embedded
  in a malloc'ed memory and boxed that way.

- GString API supports inserting and removing range. We almost never
  make use of that. We only require append-only, which is simple to
  implement.

- GString needs to NUL terminate the buffer on every append. It
  has unnecessary overhead for allowing a usage of where intermediate
  buffer contents are valid strings too. That is not the case with
  NMStrBuf: the API requires the user to call nm_str_buf_get_str() or
  nm_str_buf_finalize(). In most cases, you would only access the string
  once at the end, and not while constructing it.

- GString always grows the buffer size by doubling it. I don't think
  that is optimal. I don't think there is one optimal approach for how
  to grow the buffer, it depends on the usage patterns. However, trying
  to make an optimal choice here makes a difference. QT also thinks so,
  and I adopted their approach in nm_utils_get_next_realloc_size().
2020-04-03 11:31:12 +02:00
Thomas Haller
04d0d1bbe5 shared: add nm_utils_get_next_realloc_size() helper
When growing a buffer by appending a previously unknown number
of elements, the often preferable strategy is growing it exponentially,
so that the amortized runtime and re-allocation costs scale linearly.
GString just always increases the buffer length to the next power of
two. That works.

I think there is value in trying to find an optimal next size. Because
while it doesn't matter in terms of asymptotic behavior, in practice
a better choice should make a difference. This is inspired by what QT
does ([1]), to take more care when growing the buffers:

  - QString allocates 4 characters at a time until it reaches size 20.
  - From 20 to 4084, it advances by doubling the size each time. More
    precisely, it advances to the next power of two, minus 12. (Some memory
    allocators perform worst when requested exact powers of two, because
    they use a few bytes per block for book-keeping.)
  - From 4084 on, it advances by blocks of 2048 characters (4096 bytes).
    This makes sense because modern operating systems don't copy the entire
    data when reallocating a buffer; the physical memory pages are simply
    reordered, and only the data on the first and last pages actually needs
    to be copied.

Note that a QT is talking about 12 characters, so we use 24 bytes
head room.

[1] https://doc.qt.io/qt-5/containers.html#growth-strategies
2020-04-03 11:31:12 +02:00
Thomas Haller
d51be7e963 shared: use nm_secret_mem_try_realloc_take() in nm_utils_fd_get_contents() 2020-04-03 11:31:12 +02:00
Thomas Haller
e9a2a85799 shared: add nm_secret_mem_realloc() helpers 2020-04-03 11:31:12 +02:00
Thomas Haller
5ab04919a2 shared: use G_UNLIKELY() macro for unlikely branch in nm_explicit_bzero() 2020-04-03 11:31:12 +02:00
Thomas Haller
a4da47bc47 shared/tests: add nmtst_get_rand_size() 2020-04-03 11:31:12 +02:00
Thomas Haller
b6fdc30a88 shared: cleanup _get_hash_key_init() and better explain the reasoning
- add more code comments

- refactor the code flow in _get_hash_key_init() to follow a simpler
  code path.

- use c_siphash_hash() instead of 3 separate steps.

- Drop "?: static_seed" from nm_hash_static(). It's not useful, because
  the only _get_hash_key() for which _get_hash_key()^static_seed is zero
  is ~static_seed. That means, only one value of all the static seeds
  can result in zero here. At that point, we can just coerce that value
  to 3679500967u directly.
2020-04-03 11:26:49 +02:00
Thomas Haller
573b02f7d7 shared: add nm_pgbytes_hash()/nm_pgbytes_equal()
For hashing of a pointer to a GBytes*.

This is useful if your key is a GBytes array, and the
first field in your to be hashed struct.
2020-04-03 11:26:49 +02:00
Thomas Haller
b1503d8a72 shared: add nm_hash_mem() helper 2020-04-03 11:26:49 +02:00
Thomas Haller
962ad7f850 shared: accept empty buffer for nm_hash_update()
There is no need to reject empty buffers. c_siphash_append() handles
them gracefully.
2020-04-03 11:26:49 +02:00
Thomas Haller
7e49f4a199 all: use wrappers for g_ascii_strtoll(), g_ascii_strtoull(), g_ascii_strtod()
Sometimes these function may set errno to unexpected values like EAGAIN.
This causes confusion. Avoid that by using our own wrappers that retry
in that case. For example, in rhbz#1797915 we have failures like:

    errno = 0;
    v = g_ascii_strtoll ("10", 0, &end);
    if (errno != 0)
        g_assert_not_reached ();

as g_ascii_strtoll() would return 10, but also set errno to EAGAIN.

Work around that by using wrapper functions that retry. This certainly
should be fixed in glib (or glibc), but the issues are severe enough to
warrant a workaround.

Note that our workarounds are very defensive. We only retry 2 times, if
we get an unexpected errno value. This is in the hope to recover from
a spurious EAGAIN. It won't recover from other errors.

https://bugzilla.redhat.com/show_bug.cgi?id=1797915
2020-04-01 17:18:37 +02:00
Thomas Haller
3b58c5fef4 shared: add nm_g_ascii_strtoull() to workaround bug 2020-04-01 17:18:01 +02:00
Thomas Haller
35a9f632a8 shared: add nm_g_ascii_strtod() to workaround bug 2020-04-01 17:18:01 +02:00
Thomas Haller
f4446e34c6 shared: add nm_g_ascii_strtoll() to workaround bug 2020-04-01 17:18:00 +02:00
Thomas Haller
87b0d4cd7c shared: add assertions to _parse_legacy_addr4() and _nm_utils_ascii_str_to_int64()
Add more assertion for hunting down assertion failure at [1].

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1797915
2020-03-31 13:48:52 +02:00
Thomas Haller
46dd4d0fbf meson: merge branch 'inigomartinez/meson-license'
Add SPDX license headers for meson files.

As far as I can tell, according to RELICENSE.md file, almost everybody
who contributed to the meson files agreed to the LGPL-2.1+ licensing.
This entails the vast majority of code in question.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/397
2020-03-28 12:45:19 +01:00
Thomas Haller
6f9a478b7d tests: replace NMTST_SWAP() by new NM_SWAP() macro
NMTST_SWAP() used memcpy() for copying the value, while NM_SWAP() uses
a temporary variable with typeof(). I think the latter is preferable.

Also, the macro is essentially doing the same thing.
2020-03-26 21:28:56 +01:00
Thomas Haller
cec06138f1 shared: add NM_SWAP() macro 2020-03-26 21:28:56 +01:00
Thomas Haller
999c569585 shared: add NM_ASCII_WHITESPACES macro
NM_ASCII_SPACES contains the ASCII characters according to
g_ascii_isspace().

Add NM_ASCII_WHITESPACES which differs from NM_ASCII_SPACES by not
including "\f". In some cases, that character shall be excluded.
For example, this is what systemd uses as "WHITESPACE" define at
various places.

Also, reorder the spaces string so that plain space comes first. It is
expected that ' ' is much more frequently than newlines or tabs. While
the order here shouldn't matter, it seems preferably to order frequent
characters in front.
2020-03-24 20:43:55 +01:00
Thomas Haller
e75d62ce76 systemd: merge branch systemd into master 2020-03-23 17:50:12 +01:00
Thomas Haller
46a1816034 systemd: update code from upstream (2020-03-23)
This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=cdc6c95737d26b1746b446dfe662872d593d23c6

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files -z :/src/systemd/src/ \
                :/shared/systemd/src/ \
                :/shared/nm-std-aux/unaligned.h | \
  xargs -0 rm -f

nm_copy_sd_shared() {
    mkdir -p "./shared/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1"
}

nm_copy_sd_core() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_stdaux() {
    mkdir -p "./shared/nm-std-aux/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-std-aux/${1##*/}"
}

nm_copy_sd_core "src/libsystemd-network/arp-util.c"
nm_copy_sd_core "src/libsystemd-network/arp-util.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd_core "src/libsystemd-network/lldp-internal.h"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd_core "src/libsystemd-network/lldp-network.c"
nm_copy_sd_core "src/libsystemd-network/lldp-network.h"
nm_copy_sd_core "src/libsystemd-network/network-internal.c"
nm_copy_sd_core "src/libsystemd-network/network-internal.h"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd_core "src/libsystemd-network/sd-lldp.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-source.h"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.h"
nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd_core "src/systemd/_sd-common.h"
nm_copy_sd_core "src/systemd/sd-dhcp-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp-lease.h"
nm_copy_sd_core "src/systemd/sd-dhcp-option.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd_core "src/systemd/sd-event.h"
nm_copy_sd_core "src/systemd/sd-id128.h"
nm_copy_sd_core "src/systemd/sd-ipv4acd.h"
nm_copy_sd_core "src/systemd/sd-ipv4ll.h"
nm_copy_sd_core "src/systemd/sd-lldp.h"
nm_copy_sd_core "src/systemd/sd-ndisc.h"
nm_copy_sd_shared "src/basic/alloc-util.c"
nm_copy_sd_shared "src/basic/alloc-util.h"
nm_copy_sd_shared "src/basic/async.h"
nm_copy_sd_shared "src/basic/cgroup-util.h"
nm_copy_sd_shared "src/basic/env-file.c"
nm_copy_sd_shared "src/basic/env-file.h"
nm_copy_sd_shared "src/basic/env-util.c"
nm_copy_sd_shared "src/basic/env-util.h"
nm_copy_sd_shared "src/basic/errno-util.h"
nm_copy_sd_shared "src/basic/escape.c"
nm_copy_sd_shared "src/basic/escape.h"
nm_copy_sd_shared "src/basic/ether-addr-util.c"
nm_copy_sd_shared "src/basic/ether-addr-util.h"
nm_copy_sd_shared "src/basic/extract-word.c"
nm_copy_sd_shared "src/basic/extract-word.h"
nm_copy_sd_shared "src/basic/fd-util.c"
nm_copy_sd_shared "src/basic/fd-util.h"
nm_copy_sd_shared "src/basic/fileio.c"
nm_copy_sd_shared "src/basic/fileio.h"
nm_copy_sd_shared "src/basic/format-util.c"
nm_copy_sd_shared "src/basic/format-util.h"
nm_copy_sd_shared "src/basic/fs-util.c"
nm_copy_sd_shared "src/basic/fs-util.h"
nm_copy_sd_shared "src/basic/hash-funcs.c"
nm_copy_sd_shared "src/basic/hash-funcs.h"
nm_copy_sd_shared "src/basic/hashmap.c"
nm_copy_sd_shared "src/basic/hashmap.h"
nm_copy_sd_shared "src/basic/hexdecoct.c"
nm_copy_sd_shared "src/basic/hexdecoct.h"
nm_copy_sd_shared "src/basic/hostname-util.c"
nm_copy_sd_shared "src/basic/hostname-util.h"
nm_copy_sd_shared "src/basic/in-addr-util.c"
nm_copy_sd_shared "src/basic/in-addr-util.h"
nm_copy_sd_shared "src/basic/io-util.c"
nm_copy_sd_shared "src/basic/io-util.h"
nm_copy_sd_shared "src/basic/list.h"
nm_copy_sd_shared "src/basic/log.h"
nm_copy_sd_shared "src/basic/macro.h"
nm_copy_sd_shared "src/basic/memory-util.c"
nm_copy_sd_shared "src/basic/memory-util.h"
nm_copy_sd_shared "src/basic/mempool.c"
nm_copy_sd_shared "src/basic/mempool.h"
nm_copy_sd_shared "src/basic/missing_fcntl.h"
nm_copy_sd_shared "src/basic/missing_random.h"
nm_copy_sd_shared "src/basic/missing_socket.h"
nm_copy_sd_shared "src/basic/missing_stat.h"
nm_copy_sd_shared "src/basic/missing_syscall.h"
nm_copy_sd_shared "src/basic/missing_type.h"
nm_copy_sd_shared "src/basic/parse-util.c"
nm_copy_sd_shared "src/basic/parse-util.h"
nm_copy_sd_shared "src/basic/path-util.c"
nm_copy_sd_shared "src/basic/path-util.h"
nm_copy_sd_shared "src/basic/prioq.c"
nm_copy_sd_shared "src/basic/prioq.h"
nm_copy_sd_shared "src/basic/process-util.c"
nm_copy_sd_shared "src/basic/process-util.h"
nm_copy_sd_shared "src/basic/random-util.c"
nm_copy_sd_shared "src/basic/random-util.h"
nm_copy_sd_shared "src/basic/set.h"
nm_copy_sd_shared "src/basic/signal-util.c"
nm_copy_sd_shared "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd_shared "src/basic/socket-util.c"
nm_copy_sd_shared "src/basic/socket-util.h"
nm_copy_sd_shared "src/basic/sort-util.h"
nm_copy_sd_shared "src/basic/sparse-endian.h"
nm_copy_sd_shared "src/basic/stat-util.c"
nm_copy_sd_shared "src/basic/stat-util.h"
nm_copy_sd_shared "src/basic/stdio-util.h"
nm_copy_sd_shared "src/basic/string-table.c"
nm_copy_sd_shared "src/basic/string-table.h"
nm_copy_sd_shared "src/basic/string-util.c"
nm_copy_sd_shared "src/basic/string-util.h"
nm_copy_sd_shared "src/basic/strv.c"
nm_copy_sd_shared "src/basic/strv.h"
nm_copy_sd_shared "src/basic/strxcpyx.c"
nm_copy_sd_shared "src/basic/strxcpyx.h"
nm_copy_sd_shared "src/basic/time-util.c"
nm_copy_sd_shared "src/basic/time-util.h"
nm_copy_sd_shared "src/basic/tmpfile-util.c"
nm_copy_sd_shared "src/basic/tmpfile-util.h"
nm_copy_sd_shared "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/user-util.h"
nm_copy_sd_shared "src/basic/utf8.c"
nm_copy_sd_shared "src/basic/utf8.h"
nm_copy_sd_shared "src/basic/util.c"
nm_copy_sd_shared "src/basic/util.h"
nm_copy_sd_shared "src/shared/dns-domain.c"
nm_copy_sd_shared "src/shared/dns-domain.h"
nm_copy_sd_stdaux "src/basic/unaligned.h"
2020-03-23 16:39:32 +01:00
Thomas Haller
073994ca42 all: use nm_clear_g_free() instead of g_clear_pointer()
I think it's preferable to use nm_clear_g_free() instead of
g_clear_pointer(, g_free). The reasons are not very strong,
but I think it is overall preferable to have a shorthand for this
frequently used functionality.

   sed 's/\<g_clear_pointer *(\([^;]*\), *\(g_free\) *)/nm_clear_g_free (\1)/g' $(git grep -l g_clear_pointer) -i
2020-03-23 11:05:34 +01:00
Thomas Haller
0f15d5aa40 shared: allow nm_dbus_connection_call_finish_variant_cb() with D-Bus methods that have no return value 2020-03-23 09:32:04 +01:00
Thomas Haller
a6574b7124 n-dhcp4: fallback to CLOCK_MONOTONIC for timerfd (resync with upstream)
The upstream merge request [1] was solved differently from
commit f49ce41214 ('client: fallback to CLOCK_MONOTONIC for timerfd').

Resync with upstream.

[1] https://github.com/nettools/n-dhcp4/pull/13
[2] a0bb7c69a1
2020-03-18 16:10:49 +01:00
Thomas Haller
d3e5eab734 shared: add nm_g_variant_is_of_type() helper 2020-03-17 08:02:54 +01:00
Thomas Haller
d1d50324a4 shared: expose size of nm_ethtool_data array in header 2020-03-06 09:49:32 +01:00
Thomas Haller
4087024a9b shared: move assertion in _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE()
Move the assertion for valid LIST first. It only checks static data,
and regardless of the entry_cmd, it should be done first.

Fixes: f4d12f7b59 ('shared: add NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE() macro for lookup of structs')
2020-03-02 16:20:50 +01:00
Thomas Haller
8b63fd8cc0 shared: fix handling %NULL argument in nm_ref_string_equals_str()
Fixes: 190a8ed425 ('shared: add nm_ref_string_equals_str() helper')
2020-03-02 15:49:41 +01:00