Integer overflows in size calculations of buffers (GArray and GPtrArray)
allow subsequent buffer overflows. This happens due to conversions
between gsize and guint.
Proof of concept demonstrations of the overflows can be found in issue
2578. They are not being added as unit tests as they require too much
memory to test.
This will affect `GArray`s which are 4GB in size, or `GPtrArray`s which
are 48GB in size.
Fixes: #2578
This fixes a bug in 7c4e6e9fbe473de0401c778c6b0c4aad27d5145a.
The original approach in that commit accidentally only checked the depth
at the leaf nodes in the variant tree, whereas actually the depth should
be checked before recursing to avoid stack overflow.
It neglected to consider that `g_variant_serialised_is_normal()` would
be recursed into by some of the `DISPATCH(_is_normal)` cases. When that
happened, the depth check was after the recursion so couldn’t prevent a
stack overflow.
Fixes: #2572
Glib cannot be built statically on Windows because glib, gobject and gio
modules need to perform specific initialization when DLL are loaded and
cleanup when unloaded. Those initializations and cleanups are performed
using the DllMain function which is not called with static builds.
Issue is known for a while and solutions were already proposed but never
merged (see: https://gitlab.gnome.org/GNOME/glib/-/issues/692). Last
patch is from version 2.36.x and since then the
"constructor/destructor" mechanism has been implemented and used in
other part of the system.
This patch takes back the old idea and updates it to the last version of
glib to allow static compilation on Windows.
WARNING: because DllMain doesn't exist anymore in static compilation
mode, there is no easy way of knowing when a Windows thread finishes.
This patch implements a workaround for glib threads created by calling
g_thread_new(), so all glib threads created through glib API will behave
exactly the same way in static and dynamic compilation modes.
Unfortunately, Windows threads created by using CreateThread() or
_beginthread/ex() will not work with glib TLS functions. If users need
absolutely to use a thread NOT created with glib API under Windows and
in static compilation mode, they should not use glib functions within
their thread or they may encounter memory leaks when the thread finishes.
This should not be an issue as users should use exclusively the glib API
to manipulate threads in order to be cross-platform compatible and this
would be very unlikely and cumbersome that they may mix up Windows native
threads API with glib one.
Closes#692
According to build system (meson.build file), G_PLATFORM_WIN32 and G_OS_WIN32
are synonym. This commit just unify the usage of this define to prepare
for the static build conditional compilation code.
../glib/gsequence.c: In function 'g_sequence_move_range':
../glib/gsequence.c:640:24: warning:
'dest_seq' may be used uninitialized in this function [-Wmaybe-uninitialized]
640 | if (dest && dest_seq == src_seq &&
| ~~~~~~~~~^~~~~~~~~~
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
This function creates a new hash table, but inherits the functions used
for the hash, comparison, and key/value memory management functions from
another hash table.
The primary use case is to implement a behaviour where you maintain a
hash table by regenerating it, letting the values not migrated be freed.
See the following pseudo code:
```
GHashTable *ht;
init(GList *resources) {
ht = g_hash_table_new (g_str_hash, g_str_equal, g_free, g_free);
for (r in resources)
g_hash_table_insert (ht, strdup (resource_get_key (r)), create_value (r));
}
update(GList *resources) {
GHashTable *new_ht = g_hash_table_new_similar (ht);
for (r in resources) {
if (g_hash_table_steal_extended (ht, resource_get_key (r), &key, &value))
g_hash_table_insert (new_ht, key, value);
else
g_hash_table_insert (new_ht, strdup (resource_get_key (r)), create_value (r));
}
g_hash_table_unref (ht);
ht = new_ht;
}
```
This code was skipping fsync on BTRFS because of an old guarantee about
the overwrite-by-rename behavior that no longer holds true. This has
been confirmed by the BTRFS developers to no longer be guaranteed since
Kernel 3.17 (August 2014), but it was guaranteed when this optimization
was first introduced in 2010.
This could result in empty files after crashes in applications using
g_file_set_contents(). Most prominently this might have been the cause
of dconf settings getting lost on BTRFS after crashes due to the
frequency with which such writes can happen in dconf.
See: https://gitlab.gnome.org/GNOME/dconf/-/issues/73
Some test suites try to call g_test_build_filename() after g_test_run()
has returned. In the installed-tests use-case where G_TEST_BUILDDIR and
G_TEST_SRCDIR are unset, that call uses test_argv0_dirname, which
is freed in test_cleanup(). Defer test_cleanup() using atexit() so it
isn't freed until after we return from main().
Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2563
Signed-off-by: Simon McVittie <smcv@collabora.com>
This is a follow-up from commit 995823b9d9, which added the condition
```
```
to the array test. On most platforms, both of those symbols are numeric
literals, but on 64-bit Windows `G_MAXSIZE` includes some widening
casts, which means it can’t be used in a preprocessor condition.
We don’t expose an appropriate symbol in `glibconfig.h` which could be
used instead, but the standard `*_WIDTH` symbols from `limits.h` will be
identical and can be used instead.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2565
This mirrors what `wcwidth()` from glibc does as of June 2020 (commit
6e540caa2).
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2564
Using ld_flags would work, but that does not propagate ldflags to users
of glib. Meson's dependency() call will propagate apple framework
dependencies to downstream users.
Fix for commit 20c8ea1bc651bc4b79d39b80d42b468f6e7a2dc8; while Linux
seems happy to return the value for the invalid key we set above, BSD
returns NULL (which is probably a more valid thing to do).
Accept both.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Many UCRT (and msvcrt/msvcxx) functions open dialog boxes
by default for .... some reason. This is a problem because a test runner
waiting on a process to exit won't see it exit unless someone actually
clicks away the box, which won't happen on a CI machine.
Additionally g_abort unconditionally raises a debugging exception,
which, if uncaught, will cause windows error reporting to pop a dialog
Resolve the first problem by calling platform specific (but documented)
functions to change the CRT's behavior in g_test_init
Resolve the second by only throwing a debug exception if we're under
debugging, and just calling abort() otherwise.
This reduces the number of popups triggerd by `meson test` from
over 10 to about three on my machine, mostly in the spawn test code.
This warning warns on widening casts from integer to pointer type,
because those casts can be problematic for porting to new pointer
sizes. The code in question didn't do any bad things here so an
intermediate cast to size_t was added to silence the warning
This test was exploiting unspecified behavior w.r.t. the address of string
literals, It expected them to be pooled (the same literal has the same
address, at least within a TU), but MSVC does not pool by default,
leading to a failure.
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.