glibc marks various allocation functions as `throw()`. This addition
hasn't been a problem until we tried to enable C++17, where clang
started complaining that we were redeclaring functions with mismatched
exception specifications. Peculiarly, glibc declares virtually
everything we redeclare as `throw()`, but clang only complains about the
mismatches for a particular subset of functions.
The approach taken in this patch is to add another potentially defined
macro to malloc_decls.h, `NOTHROW_MALLOC_DECL`. This macro works
exactly like `MALLOC_DECL`, except that clients can define
`NOTHROW_MALLOC_DECL` to add appropriate `throw()` specifiers when
declaring functions at global scope, and thereby avoid mismatched
exception specifications.
Differential Revision: https://phabricator.services.mozilla.com/D44045
--HG--
extra : moz-landing-system : lando
In the MinGW build, calls to malloc inside mozglue were not being
redirected as defined in the .def file. We create aliases for the
redirected functions to correctly redirect them inside mozglue.
An alternate solution for this exists. Rather than creating the
importlib during the linking step for mozglue, we could have used
dlltool to create it, and then provided it during linking. This
would allow mozglue to know that it should redirect calls to malloc
to je_malloc as specified in the .def file.
Differential Revision: https://phabricator.services.mozilla.com/D38407
--HG--
extra : moz-landing-system : lando
- On Android, we were already doing it, but using fallible allocations.
- On *nix, it probably doesn't make a difference, but can't hurt. For
most things in Gecko, operator new/delete are inlined and thus
replaced by direct calls to the underlying allocator functions
(moz_xmalloc, malloc, etc.). This may have a benefit for some third
party libraries that would otherwise go through libstdc++'s to
eventually end up back into our allocator via the zone allocator
on macOS and via the exported symbols on others.
- On Windows, because of how some CRT static libraries are, a non-inlined
operator new (thanks to some disabled STL wrapping) would end up linked
against the system malloc, causing problems.
Overall, this can only be better. This also reduces the number of places
where we define those functions.
And on Android, this means operator new within mozglue becomes infallible,
which is more consistent with everything else.
Differential Revision: https://phabricator.services.mozilla.com/D36166
--HG--
extra : moz-landing-system : lando
- On Android, we were already doing it, but using fallible allocations.
- On *nix, it probably doesn't make a difference, but can't hurt. For
most things in Gecko, operator new/delete are inlined and thus
replaced by direct calls to the underlying allocator functions
(moz_xmalloc, malloc, etc.). This may have a benefit for some third
party libraries that would otherwise go through libstdc++'s to
eventually end up back into our allocator via the zone allocator
on macOS and via the exported symbols on others.
- On Windows, because of how some CRT static libraries are, a non-inlined
operator new (thanks to some disabled STL wrapping) would end up linked
against the system malloc, causing problems.
Overall, this can only be better. This also reduces the number of places
where we define those functions.
And on Android, this means operator new within mozglue becomes infallible,
which is more consistent with everything else.
Differential Revision: https://phabricator.services.mozilla.com/D36166
--HG--
extra : moz-landing-system : lando
This allows freelist randomization on a per-arena basis, by supplying parameters to
arena creation.
It uses an xorshift PRNG with a 128-bit state. It is not cryptographically secure. An
attacker who can observe outputs of the RNG, or read its state, is already in a position
to bypass the randomization applied. At the same time we make its state 128 bit to prevent
a trivial bypass if one or two outputs are observed.
The way a run selects masks to check has not been modified, so the randomization is limited
to at most 32 bits in the current mask being tested. It should be noted that while allocations
from the same run may now be non deterministic (up to the maximum entropy as previously
stated), an attacker who can perform multiple allocations will still be able to allocate
a targeted free region (for example while exploiting a use after free vulnerability in the
DOM). Non deterministic allocations will only impede an attacker who has less control over
how they allocate a targeted free region, and may provide some benefit during exploitation
of a heap based buffer overflow vulnerability where the attacker wishes to construct a
precise layout of regions pre overflow.
Differential Revision: https://phabricator.services.mozilla.com/D32219
--HG--
extra : moz-landing-system : lando
`jemalloc_replace_dynamic()` is badly broken. If you install a malloc table
other than the default at startup (e.g. DMD's or PHC's), when you call
`jemalloc_replace_dynamic()` it installs a new allocator that wraps the
*default* allocator, and then when you call `jemalloc_replace_dynamic(nullptr)`
it switches back to the *default* allocator.
This commits makes numerous improvements.
- It removes the "flip-flopping" between malloc tables, which didn't really
work and isn't necessary.
- `jemalloc_replace_dynamic()` now switches between the *original* malloc table
and the new one, rather than the *default* malloc table and the new one.
- It renames various things, to make the names shorter and clearer.
- It clearly documents the dangers and limitations of
`jemalloc_replace_dynamic()`.
- It removes and inlines `profiler::Init()`, because there was only one call
site.
- It rearranges `install_memory_counter()` so the control flow is simpler.
Differential Revision: https://phabricator.services.mozilla.com/D34266
--HG--
extra : moz-landing-system : lando
This makes it less mozjemalloc-specific, which is helpful for PHC. No non-test
code uses the extra detail anyway.
Differential Revision: https://phabricator.services.mozilla.com/D34441
--HG--
extra : moz-landing-system : lando
MALLOC_STATIC_PAGESIZE is only set on some platforms. Specifically, it's
not set on ia64 and sparc. Which means the case MALLOC_STATIC_PAGESIZE
&& (sparc || ia64) never happens, and gPageSize is never 8 KiB.
Differential Revision: https://phabricator.services.mozilla.com/D31965
--HG--
extra : moz-landing-system : lando
To ensure that any new JSString has its char buffer allocated in the new arena,
it is useful to be able to query a pointer and assert that it is in the
correct arena (at-least in Debug Build).
This adds the required functionality to mozjemalloc, and JSString can use it
for its new assertion in a later change.
Differential Revision: https://phabricator.services.mozilla.com/D25711
--HG--
extra : moz-landing-system : lando
To ensure that any new JSString has its char buffer allocated in the new arena,
it is useful to be able to query a pointer and assert that it is in the
correct arena (at-least in Debug Build).
This adds the required functionality to mozjemalloc, and JSString can use it
for its new assertion in a later change.
Differential Revision: https://phabricator.services.mozilla.com/D25711
Consequently, this removes:
- MOZ_LIBPRIO, which is now always enabled.
- non_msvc_compiler, which is now always true.
- The cl.py wrapper, since it's not used anymore.
- CL_INCLUDES_PREFIX, which was only used for the cl.py wrapper.
- NONASCII, which was only there to ensure CL_INCLUDES_PREFIX still
worked in non-ASCII cases.
This however keeps a large part of detecting and configuring for MSVC,
because we still do need it for at least headers, libraries, and midl.
Depends on D19614
Differential Revision: https://phabricator.services.mozilla.com/D19615
--HG--
extra : moz-landing-system : lando
The diagnostic assert (so fortunately, it doesn't impact release builds)
as added in bug 1405159, but is costly because it uses the modulus of
the division with a variable integer, which is a slow operation.
However, in arena_run_reg_dalloc, we end up doing the same diagnostic
assert, in a different form: after performing the division in a faster
manner, we assert that the result, multiplied by the diviser, returns
the original number.
Differential Revision: https://phabricator.services.mozilla.com/D13501
--HG--
extra : moz-landing-system : lando
Previously the id for a new arena was just a counter that increased by one
every time. For hardening purposes, we want to make private arenas use a secure
random ID, so an attacker will have a more difficult time finding the memory
they are looking for.
Differential Revision: https://phabricator.services.mozilla.com/D10158
--HG--
extra : moz-landing-system : lando
Previously the id for a new arena was just a counter that increased by one
every time. For hardening purposes, we want to make the new counter a secure
random ID, so an attacker will have a more difficult time finding the memory
they are looking for.
Differential Revision: https://phabricator.services.mozilla.com/D10158
--HG--
extra : moz-landing-system : lando
Bug 1364359 is to fix a leaked arena. Until that is fixed; it is unsafe to
call moz_dispose_arena more than once.
MozReview-Commit-ID: KIby1RLtrPK
--HG--
extra : rebase_source : 6ea41001e9f0c4d5eb24ee678d6c1c0218991ac3
This behavior matches what gets used in mozalloc.h to define these
wrappers, and is particularly necessary for newer versions of clang to
not complain about our definitions.
Base allocator commit stats were added in bug 515556, along other commit
stats, but they have actually been wrong since then: the committed count
is updated with the difference between pbase_next_addr and
base_next_decommitted *after* the latter is set to the former, making
the difference always 0.
--HG--
extra : rebase_source : a2aed523314549a37a61bd4ab300c98f198f9252
Since TreeNode::{Left,Right,Color} is always a valid call to make, we
don't need to check if for nullity before calling those functions.
This effectively kind of reverts some parts of bug 1412722.
--HG--
extra : rebase_source : 3deb316f463b51fdbb3aebc2e57e437018b3a829
The code before bug 1412722 benefitted from the sentinel being an actual
node object, and some code paths ended up checking its color (always
black) or getting its right and left node, that always returned to the
sentinel.
When TreeNode currently contains a nullptr, all those lead to a null
deref if the calling code is not doing the right checks, which happens
to be the case in at least some places. Instead of relying on the
callers doing the right thing, make the TreeNode do the right thing when
it contains a nullptr, effectively acting as the sentinel in that case.
We additionally ensure that nothing in the calling code will be trying
to change the color or left/right pointers on the sentinel, which is an
extra safe net compared to the code before bug 1412722.
--HG--
extra : rebase_source : 09ab0bf8682092ef6d9a0a5921be3da787d0d548
This will allow the upcoming changes to add some safety back to the code
after bug 1412722.
--HG--
extra : rebase_source : 5033b8034cabaf5a7fdd578459588d5099402d02