Commit Graph

7239 Commits

Author SHA1 Message Date
Philip Withnall
b53b26c559 gvariant: Track checked and ordered offsets independently
The past few commits introduced the concept of known-good offsets in the
offset table (which is used for variable-width arrays and tuples).
Good offsets are ones which are non-overlapping with all the previous
offsets in the table.

If a bad offset is encountered when indexing into the array or tuple,
the cached known-good offset index will not be increased. In this way,
all child variants at and beyond the first bad offset can be returned as
default values rather than dereferencing potentially invalid data.

In this case, there was no information about the fact that the indexes
between the highest known-good index and the requested one had been
checked already. That could lead to a pathological case where an offset
table with an invalid first offset is repeatedly checked in full when
trying to access higher-indexed children.

Avoid that by storing the index of the highest checked offset in the
table, as well as the index of the highest good/ordered offset.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2121
2023-03-24 08:55:17 -05:00
Philip Withnall
98d5b84c2c gvariant: Don’t allow child elements of a tuple to overlap each other
This is similar to the earlier commit which prevents child elements of a
variable-sized array from overlapping each other, but this time for
tuples. It is based heavily on ideas by William Manley.

Tuples are slightly different from variable-sized arrays in that they
contain a mixture of fixed and variable sized elements. All but one of
the variable sized elements have an entry in the frame offsets table.
This means that if we were to just check the ordering of the frame
offsets table, the variable sized elements could still overlap
interleaving fixed sized elements, which would be bad.

Therefore we have to check the elements rather than the frame offsets.

The logic of checking the elements up to the index currently being
requested, and caching the result in `ordered_offsets_up_to`, means that
the algorithmic cost implications are the same for this commit as for
variable-sized arrays: an O(N) cost for these checks is amortised out
over N accesses to O(1) per access.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2121
2023-03-24 08:54:44 -05:00
Philip Withnall
a4ddf8ea87 gvariant: Don’t allow child elements of a tuple to overlap each other
This is similar to the earlier commit which prevents child elements of a
variable-sized array from overlapping each other, but this time for
tuples. It is based heavily on ideas by William Manley.

Tuples are slightly different from variable-sized arrays in that they
contain a mixture of fixed and variable sized elements. All but one of
the variable sized elements have an entry in the frame offsets table.
This means that if we were to just check the ordering of the frame
offsets table, the variable sized elements could still overlap
interleaving fixed sized elements, which would be bad.

Therefore we have to check the elements rather than the frame offsets.

The logic of checking the elements up to the index currently being
requested, and caching the result in `ordered_offsets_up_to`, means that
the algorithmic cost implications are the same for this commit as for
variable-sized arrays: an O(N) cost for these checks is amortised out
over N accesses to O(1) per access.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2121
2023-03-24 08:53:54 -05:00
Philip Withnall
44ae51d046 gvariant-serialiser: Rework child size calculation
This reduces a few duplicate calls to `g_variant_type_info_query()` and
explains why they’re needed.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2121
2023-03-24 08:53:48 -05:00
Philip Withnall
21fba6a534 gvariant-serialiser: Factor out code to get bounds of a tuple member
This introduces no functional changes.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2121
2023-03-24 08:53:39 -05:00
William Manley
96e27afc7a gvariant: Don’t allow child elements to overlap with each other
If different elements of a variable sized array can overlap with each
other then we can cause a `GVariant` to normalise to a much larger type.

This commit changes the behaviour of `GVariant` with non-normal form data. If
an invalid frame offset is found all subsequent elements are given their
default value.

When retrieving an element at index `n` we scan the frame offsets up to index
`n` and if they are not in order we return an element with the default value
for that type.  This guarantees that elements don't overlap with each
other.  We remember the offset we've scanned up to so we don't need to
repeat this work on subsequent accesses.  We skip these checks for trusted
data.

Unfortunately this makes random access of untrusted data O(n) — at least
on first access.  It doesn't affect the algorithmic complexity of accessing
elements in order, such as when using the `GVariantIter` interface.  Also:
the cost of validation will be amortised as the `GVariant` instance is
continued to be used.

I've implemented this with 4 different functions, 1 for each element size,
rather than looping calling `gvs_read_unaligned_le` in the hope that the
compiler will find it easy to optimise and should produce fairly tight
code.

Fixes: #2121
2023-03-24 08:53:32 -05:00
Philip Withnall
fd215233ae gvariant: Zero-initialise various GVariantSerialised objects
The following few commits will add a couple of new fields to
`GVariantSerialised`, and they should be zero-filled by default.

Try and pre-empt that a bit by zero-filling `GVariantSerialised` by
default in a few places.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2121
2023-03-24 08:53:26 -05:00
William Manley
d51c16a7c8 gvariant-serialiser: Factor out functions for dealing with framing offsets
This introduces no functional changes.

Helps: #2121
2023-03-24 08:53:21 -05:00
William Manley
b4ae1179cb gvariant-core: Consolidate construction of GVariantSerialised
So I only need to change it in one place.

This introduces no functional changes.

Helps: #2121
2023-03-24 08:53:15 -05:00
Philip Withnall
a879d08e91 gspawn: Report errors with closing file descriptors between fork/exec
If a seccomp policy is set up incorrectly so that it returns `EPERM` for
`close_range()` rather than `ENOSYS` due to it not being recognised, no
error would previously be reported from GLib, but some file descriptors
wouldn’t be closed, and that would cause a hung zombie process. The
zombie process would be waiting for one half of a socket to be closed.

Fix that by correctly propagating errors from `close_range()` back to the
parent process so they can be reported correctly.

Distributions which aren’t yet carrying the Docker fix to correctly
return `ENOSYS` from unrecognised syscalls may want to temporarily carry
an additional patch to fall back to `safe_fdwalk()` if `close_range()`
fails with `EPERM`. This change will not be accepted upstream as `EPERM`
is not the right error for `close_range()` to be returning.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2580
2022-01-27 10:24:38 -06:00
Jamie Bainbridge
ffc00caa73 gutils: Avoid segfault in g_get_user_database_entry
g_get_user_database_entry() uses variable pwd to store the contents of
the call to getpwnam_r(), then capitalises the first letter of pw_name
with g_ascii_toupper (pw->pw_name[0]).

However, as per the getpwnam manpage, the result of that call "may point
to a static area". When this happens, GLib is trying to edit static
memory which belongs to a shared library, so segfaults.

Instead, copy pw_name off to a temporary variable, set uppercase on
that variable, and use the variable to join into the desired string.
Free the new variable after it is no longer needed.

Signed-off-by: Jamie Bainbridge <jamie.bainbridge@gmail.com>
2022-01-27 10:14:14 -06:00
Michael Catanzaro
3e1d6e9e58 gspawn: add new error message for open() failures
Reporting these as dup2() failures is bogus.
2022-01-27 10:14:02 -06:00
Michael Catanzaro
cbb72948f6 gspawn: Check from errors from safe_dup2() and dupfd_cloexec()
Although unlikely, these functions can fail, e.g. if we run out of file
descriptors. Check for errors to improve robustness. This is especially
important now that I changed our use of dupfd_cloexec() to avoid
returning fds smaller than the largest fd in target_fds. An application
that attempts to remap to the highest-allowed fd value deserves at least
some sort of attempt at error reporting, not silent failure.
2022-01-27 10:14:02 -06:00
Michael Catanzaro
59da3753d1 gspawn: Implement fd remapping for posix_spawn codepath
This means that GSubprocess will (sometimes) be able to use the
optimized posix_spawn codepath instead of having to fall back to
fork/exec.
2022-01-27 10:14:02 -06:00
Michael Catanzaro
87257f1f46 gspawn: fix fd remapping conflation issue
We currently dup all source fds to avoid possible conflation with the
target fds, but fail to consider that the result of a dup might itself
conflict with one of the target fds. Solve this the easy way by duping
all source_fds to values that are greater than the largest fd in
target_fds.

Fixes #2503
2022-01-27 10:14:02 -06:00
Michael Catanzaro
dc4e25832c gspawn: fix hangs when duping child_err_report_fd
In case child_err_report_fd conflicts with one of the target_fds, the
code here is careful to dup child_err_report_fd in order to avoid
conflating the two. It was a good idea, but evidently was not tested,
because the newly-created fd is not created with CLOEXEC set. This means
it stays open in the child process, causing the parent to hang forever
waiting to read from the other end of the pipe. Oops!

The fix is simple: just set CLOEXEC. This removes our only usage of the
safe_dup() function, so it can be dropped.

Fixes #2506
2022-01-27 10:14:02 -06:00
Michael Catanzaro
1e1002469c gspawn: Improve error message when dup fails
This error message is no longer accurate now that we allow arbitrary fd
remapping.
2022-01-27 10:14:02 -06:00
Michael Catanzaro
ecde1b75d0 gspawn: use close_and_invalidate more 2022-01-27 10:14:02 -06:00
Simon McVittie
2f489d0b0f gversionmacros: Add version macros for GLib 2.70
Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-01-27 10:13:58 -06:00
Simon McVittie
4ce606878e g_string_replace: Document behaviour of zero-length match pattern
Signed-off-by: Simon McVittie <smcv@collabora.com>
2021-08-02 13:49:19 +01:00
Simon McVittie
79fa8db828 test_string_replace: Exercise zero-length replacements
Previously, these would have done 2**32 replacements, and the first one
would have consumed 6GB of memory in the process. They now match what
Python `str.replace()` does.

Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/2452
Signed-off-by: Simon McVittie <smcv@collabora.com>
2021-08-02 13:49:19 +01:00
Simon McVittie
c70eb3f0aa g_string_replace: Don't replace empty string more than once per location
This matches the behaviour of Python `str.replace()`, and avoids carrying
out 2**32 replacements before n wraps around, which is almost certainly
not what we want.

Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2452
Signed-off-by: Simon McVittie <smcv@collabora.com>
2021-08-02 13:49:19 +01:00
Simon McVittie
d587690534 test_string_replace: Expand test coverage
These are taken from another project (steam-runtime-tools) where I
implemented a similar replace method before realising that more recent
GLib versions had g_string_replace().

Signed-off-by: Simon McVittie <smcv@collabora.com>
2021-08-02 13:49:19 +01:00
Simon McVittie
5162562903 test_string_replace: Make the test table-driven
This makes it straightforward to add more test-cases.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2021-08-02 13:49:19 +01:00
Simon McVittie
3798abd5ea test_string_replace: Make types agree
g_string_replace() returns guint, not gint.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2021-08-02 13:49:19 +01:00
Michael Catanzaro
be84555c73 tests: Add missing return value check in string test
Coverity noticed that we were not testing the return value here. Good
Coverity!
2021-08-02 13:49:19 +01:00
Khem Raj
6e59d21b27 correctly use 3 parameters for close_range
libc implementation has 3 parameter e.g.
https://www.freebsd.org/cgi/man.cgi?query=close_range&sektion=2&format=html

Signed-off-by: Khem Raj <raj.khem@gmail.com>
2021-07-09 12:24:56 +01:00
Ignacio Casal Quinteiro
7d392d7ebc gmacros: missing check if __STDC_VERSION__ is defined
This fixes warnings when compiling on old distros like centos 7
2021-04-27 13:11:03 +02:00
Ignacio Casal Quinteiro
f954aff882 gmacros: check that __cplusplus or _MSC_VER is defined
Otherwise it will fail to compile in old distros like Centos 7
Fixes #2387
2021-04-23 10:09:49 +02:00
Emmanuele Bassi
2e37754261 Split g_test_log() messages that contain multiple lines
When using TAP we want every single line to be one of the following:

 - a valid TAP clause
 - a comment
 - a blank line

Typical explicit test logs are single line comments, but in some cases
we might end up printing debug messages from libraries, and those may
contain multiple lines. When that happens, we break the TAP and fail the
test in conditions entirely outside of our control.

One option to avoid outright failure is to always prepend each line of a
messge with `#`, to ensure that the whole thing is considered a comment.
2021-04-07 16:36:06 +01:00
Chun-wei Fan
20bd716d4c option-context.c: Define NAN if not defined on MSVC
This will enable the build to succeed on older Visual Studio versions
that don't support NAN yet.  Other supported compilers should support
this.
2021-03-31 21:47:49 +08:00
Philip Withnall
77649d3d3d gkeyfile: Fix crash when parsing translations on a second load
If the same `GKeyFile` is reused to load multiple different key files,
any loads after the first which encounter translated keys will crash,
because clearing the data from the first load cleared the cached
language names, but didn’t clear `checked_locales`, so they were never
reloaded.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2361
2021-03-23 16:56:33 +00:00
Philip Withnall
07ab2e26c9 gkeyfile: Drop a redundant check
It should not be possible for `->locales` to be set without
`->checked_locales` being set, so drop the redundant check. This helps
with branch code coverage.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-03-23 16:56:33 +00:00
Andy Fiddaman
08f2ed7535 Include glibconfig.h to get the G_OS_UNIX token 2021-03-18 19:42:18 +00:00
Michael Catanzaro
3a74ad128e tests: Fix copy/paste error in queue test
Coverity is pretty good at detecting copy/paste errors.
2021-03-16 12:53:44 -05:00
Philip Withnall
c92d9dc267 enums: Add missing GLIB_AVAILABLE_ENUMERATOR_IN_2_68 annotations
In the 2.68 cycle we’d added 3 new enumerator elements. Due to the
preceding commit, they can now be annotated with
`GLIB_AVAILABLE_ENUMERATOR_IN_2_68`, which will make it a bit easier for
third party projects to notice when they’re using these symbols without
having bumped their GLib dependency.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2327
2021-03-11 13:37:49 +00:00
Aleksandr Mezin
d18bdef42d gbitlock.c: replace remaining 'asm' with '__asm__'
Commit 2330f7e65e changed 'asm' to '__asm__' in
g_bit_lock and g_bit_trylock.

Replace 'asm' with '__asm__' in the remaining functions.

Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/2344
2021-03-04 04:39:27 +06:00
Philip Withnall
6cc6df230a Merge branch 'glib-typeof-gatomic-h' into 'master'
gatomic.h: Make `glib_typeof` API break opt in.

See merge request GNOME/glib!1975
2021-03-01 13:19:08 +00:00
Iain Lane
5b3e4f94b0 gatomic.h: Make glib_typeof API break opt in.
The changes in 4273c43902 did not guard
macros in `gatomic.h` which use `glib_typeof`. This meant that when
552b8fd862 was committed, moving the
include of `<type_traits>` under such a guard, these macros were still
trying to use it. This broke the build of at least vte.

Fix this by guarding the API break in `gatomic.h` too.
2021-03-01 09:18:03 +00:00
Olivier Brunel
ddb2b5fe54 GRWLock: Tweak doc to make things a bit clearer
The doc used different phrasing for the same thing, e.g. "if any thread"
vs "any other thread."

Also make it clear that trying to take a write lock while already having
a lock, or trying to take a read lock while having a write lock, is
undefined.
2021-02-27 20:34:30 +01:00
Iain Lane
552b8fd862 glib/gmacros.h: Move <type_traits> include to consumers
When included inside an `extern "C"` block, this causes build failures
that look something like:

  /usr/include/c++/10/type_traits:2930:3: error: template with C linkage
   2930 |   template<typename _Fn, typename... _Args>
        |   ^~~~~~~~
  ../../disas/arm-a64.cc:20:1: note: ‘extern "C"’ linkage started here
     20 | extern "C" {
        | ^~~~~~~~~~

Commit 4273c43902 made this opt in for
projects which are defining `GLIB_VERSION_MIN_REQUIRED`, but the include
of `<type_traits>` via `gmacros.h` was not included in this. If we move
the include out to the places where `glib_typeof` is called, we can make
it covered by this macro too, and save a few consumers from FTBFSing.

That also means that, if you don't want to fix your use of the headers,
and as long as this version is sufficient for you, a quick workaround is
to define `GLIB_VERSION_MIN_REQUIRED` to `GLIB_VERSION_2_66` or lower.

Suggested by Simon McVittie.

Alternative to: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1935
Fixes: https://gitlab.gnome.org/GNOME/glib/-/issues/2331
2021-02-25 15:33:59 +00:00
Philip Withnall
b018730087 tests: Add missing NULL terminator to spawn-singlethread test
This should have been in commit
b31f3f5f80.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-02-16 15:08:47 +00:00
Philip Withnall
51e964849b Merge branch '2097-spawn-fd-rewriting' into 'master'
Resolve "GSubprocessLauncher with FD assignment can clash with g_spawn_async internal pipe"

Closes #2097

See merge request GNOME/glib!1690
2021-02-16 14:04:39 +00:00
Philip Withnall
eebb66280d gspawn-win32: Various minor internal const-correctness fixes
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-02-16 13:44:00 +00:00
Philip Withnall
ea9fd4c2f2 gspawn-win32: Implement g_spawn_async_with_pipes_and_fds()
The `source_fds`/`target_fds` functionality is not supported on Windows
at the moment.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2097
2021-02-16 13:44:00 +00:00
Philip Withnall
a34b674134 gspawn-win32: Refactor internal spawn functions
This should introduce no functional changes, but condenses the variants
of the internal spawn implementation down to be more like `gspawn.c`.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2097
2021-02-16 13:44:00 +00:00
Philip Withnall
ba403908a2 gspawn-win32: Rename a variable for consistency with the public headers
I realise Windows uses handles rather than PIDs, but given that there
are multiple platform-specific implementations of the public
`g_spawn_*()` API, I think it is less confusing for them all to use the
same naming scheme.

This introduces no functional changes.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-02-16 13:44:00 +00:00
Philip Withnall
fd0b20d537 gspawn: Minor improvements to documentation formatting
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-02-16 13:44:00 +00:00
Philip Withnall
b31f3f5f80 gspawn: Add new g_spawn_async_with_pipes_and_fds() API
This is a simple wrapper around the new source/target FD mapping
functionality in `fork_exec()`.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2097
2021-02-16 13:44:00 +00:00
Philip Withnall
52dc7cb9dd tests: Add setlocale() call to spawn-singlethread
This allows non-ASCII characters to be used in test messages from it.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2021-02-16 13:44:00 +00:00