Changeset 239787 in webkit


Ignore:
Timestamp:
Jan 9, 2019, 2:45:06 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Gigacage disabling checks should handle the GIGACAGE_ALLOCATION_CAN_FAIL case properly.
https://bugs.webkit.org/show_bug.cgi?id=193292
<rdar://problem/46485450>

Reviewed by Yusuke Suzuki.

Source/bmalloc:

Previously, when GIGACAGE_ALLOCATION_CAN_FAIL is true, we allow the Gigacage to
be disabled if we fail to allocate memory for it. However, Gigacage::primitiveGigacageDisabled()
still always assumes that the Gigacage is always enabled after ensureGigacage() is
called.

This patch updates Gigacage::primitiveGigacageDisabled() to allow the Gigacage to
already be disabled if GIGACAGE_ALLOCATION_CAN_FAIL is true and wasEnabled() is
false.

In this patch, we also put the wasEnabled flag in the 0th slot of the
g_gigacageBasePtrs buffer to ensure that it is also protected against writes just
like the Gigacage base pointers.

To achieve this, we do the following:

  1. Added a reservedForFlags field in struct BasePtrs.
  2. Added a ReservedForFlagsAndNotABasePtr Gigacage::Kind.
  3. Added assertions to ensure that the BasePtrs::primitive is at the offset matching the offset computed from Gigacage::Primitive. Ditto for BasePtrs::jsValue and Gigacage::JSValue.
  4. Added assertions to ensure that Gigacage::ReservedForFlagsAndNotABasePtr is not used for fetching a Gigacage base pointer.
  5. Added RELEASE_BASSERT_NOT_REACHED() to implement such assertions in bmalloc.

No test added because this issue requires Gigacage allocation to fail in order to
manifest. I've tested it manually by modifying the code locally to force an
allocation failure.

  • bmalloc/BAssert.h:
  • bmalloc/Gigacage.cpp:

(Gigacage::ensureGigacage):
(Gigacage::primitiveGigacageDisabled):

  • bmalloc/Gigacage.h:

(Gigacage::wasEnabled):
(Gigacage::setWasEnabled):
(Gigacage::name):
(Gigacage::basePtr):
(Gigacage::size):

  • bmalloc/HeapKind.h:

(bmalloc::heapKind):

Source/JavaScriptCore:

  • runtime/VM.h:

(JSC::VM::gigacageAuxiliarySpace):

Source/WTF:

Update the USE_SYSTEM_MALLOC version of Gigacage.h to match the bmalloc version.

  • wtf/Gigacage.h:
Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/Source/JavaScriptCore/ChangeLog

    r239774 r239787  
     12019-01-09  Mark Lam  <mark.lam@apple.com>
     2
     3        Gigacage disabling checks should handle the GIGACAGE_ALLOCATION_CAN_FAIL case properly.
     4        https://bugs.webkit.org/show_bug.cgi?id=193292
     5        <rdar://problem/46485450>
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        * runtime/VM.h:
     10        (JSC::VM::gigacageAuxiliarySpace):
     11
    1122019-01-08  Keith Miller  <keith_miller@apple.com>
    213
  • TabularUnified trunk/Source/JavaScriptCore/runtime/VM.h

    r239427 r239787  
    11/*
    2  * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    347347    {
    348348        switch (kind) {
     349        case Gigacage::ReservedForFlagsAndNotABasePtr:
     350            RELEASE_ASSERT_NOT_REACHED();
    349351        case Gigacage::Primitive:
    350352            return primitiveGigacageAuxiliarySpace;
  • TabularUnified trunk/Source/WTF/ChangeLog

    r239709 r239787  
     12019-01-09  Mark Lam  <mark.lam@apple.com>
     2
     3        Gigacage disabling checks should handle the GIGACAGE_ALLOCATION_CAN_FAIL case properly.
     4        https://bugs.webkit.org/show_bug.cgi?id=193292
     5        <rdar://problem/46485450>
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        Update the USE_SYSTEM_MALLOC version of Gigacage.h to match the bmalloc version.
     10
     11        * wtf/Gigacage.h:
     12
    1132019-01-07  David Kilzer  <ddkilzer@apple.com>
    214
  • TabularUnified trunk/Source/WTF/wtf/Gigacage.h

    r231337 r239787  
    11/*
    2  * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4141
    4242struct BasePtrs {
     43    uintptr_t reservedForFlags;
    4344    void* primitive;
    4445    void* jsValue;
     
    4647
    4748enum Kind {
     49    ReservedForFlagsAndNotABasePtr = 0,
    4850    Primitive,
    4951    JSValue,
    5052};
     53
     54static_assert(offsetof(BasePtrs, primitive) == Kind::Primitive * sizeof(void*), "");
     55static_assert(offsetof(BasePtrs, jsValue) == Kind::JSValue * sizeof(void*), "");
    5156
    5257inline void ensureGigacage() { }
     
    6671{
    6772    switch (kind) {
     73    case ReservedForFlagsAndNotABasePtr:
     74        RELEASE_ASSERT_NOT_REACHED();
    6875    case Primitive:
    6976        return "Primitive";
     
    7885{
    7986    switch (kind) {
     87    case ReservedForFlagsAndNotABasePtr:
     88        RELEASE_ASSERT_NOT_REACHED();
    8089    case Primitive:
    8190        return basePtrs.primitive;
  • TabularUnified trunk/Source/bmalloc/ChangeLog

    r239257 r239787  
     12019-01-09  Mark Lam  <mark.lam@apple.com>
     2
     3        Gigacage disabling checks should handle the GIGACAGE_ALLOCATION_CAN_FAIL case properly.
     4        https://bugs.webkit.org/show_bug.cgi?id=193292
     5        <rdar://problem/46485450>
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        Previously, when GIGACAGE_ALLOCATION_CAN_FAIL is true, we allow the Gigacage to
     10        be disabled if we fail to allocate memory for it.  However, Gigacage::primitiveGigacageDisabled()
     11        still always assumes that the Gigacage is always enabled after ensureGigacage() is
     12        called.
     13
     14        This patch updates Gigacage::primitiveGigacageDisabled() to allow the Gigacage to
     15        already be disabled if GIGACAGE_ALLOCATION_CAN_FAIL is true and wasEnabled() is
     16        false.
     17
     18        In this patch, we also put the wasEnabled flag in the 0th slot of the
     19        g_gigacageBasePtrs buffer to ensure that it is also protected against writes just
     20        like the Gigacage base pointers.
     21
     22        To achieve this, we do the following:
     23        1. Added a reservedForFlags field in struct BasePtrs.
     24        2. Added a ReservedForFlagsAndNotABasePtr Gigacage::Kind.
     25        3. Added assertions to ensure that the BasePtrs::primitive is at the offset
     26           matching the offset computed from Gigacage::Primitive.  Ditto for
     27           BasePtrs::jsValue and Gigacage::JSValue.
     28        4. Added assertions to ensure that Gigacage::ReservedForFlagsAndNotABasePtr is not
     29           used for fetching a Gigacage base pointer.
     30        5. Added RELEASE_BASSERT_NOT_REACHED() to implement such assertions in bmalloc.
     31
     32        No test added because this issue requires Gigacage allocation to fail in order to
     33        manifest.  I've tested it manually by modifying the code locally to force an
     34        allocation failure.
     35
     36        * bmalloc/BAssert.h:
     37        * bmalloc/Gigacage.cpp:
     38        (Gigacage::ensureGigacage):
     39        (Gigacage::primitiveGigacageDisabled):
     40        * bmalloc/Gigacage.h:
     41        (Gigacage::wasEnabled):
     42        (Gigacage::setWasEnabled):
     43        (Gigacage::name):
     44        (Gigacage::basePtr):
     45        (Gigacage::size):
     46        * bmalloc/HeapKind.h:
     47        (bmalloc::heapKind):
     48
    1492018-12-15  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
    250
  • TabularUnified trunk/Source/bmalloc/bmalloc/BAssert.h

    r230463 r239787  
    8282
    8383#define RELEASE_BASSERT(x) BASSERT_IMPL(x)
     84#define RELEASE_BASSERT_NOT_REACHED() BCRASH()
    8485
    8586#if BUSE(OS_LOG)
  • TabularUnified trunk/Source/bmalloc/bmalloc/Gigacage.cpp

    r239257 r239787  
    11/*
    2  * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343#define GIGACAGE_RUNWAY (32llu * 1024 * 1024 * 1024)
    4444
     45// Note: g_gigacageBasePtrs[0] is reserved for storing the wasEnabled flag.
     46// The first gigacageBasePtr will start at g_gigacageBasePtrs[sizeof(void*)].
     47// This is done so that the wasEnabled flag will also be protected along with the
     48// gigacageBasePtrs.
    4549alignas(GIGACAGE_BASE_PTRS_SIZE) char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE];
    4650
     
    4852
    4953namespace Gigacage {
    50 
    51 bool g_wasEnabled;
    5254
    5355namespace {
     
    104106{
    105107    switch (kind) {
     108    case Kind::ReservedForFlagsAndNotABasePtr:
     109        RELEASE_BASSERT_NOT_REACHED();
    106110    case Kind::Primitive:
    107111        return static_cast<size_t>(GIGACAGE_RUNWAY);
     
    127131            Kind shuffledKinds[numKinds];
    128132            for (unsigned i = 0; i < numKinds; ++i)
    129                 shuffledKinds[i] = static_cast<Kind>(i);
     133                shuffledKinds[i] = static_cast<Kind>(i + 1); // + 1 to skip Kind::ReservedForFlagsAndNotABasePtr.
    130134           
    131135            // We just go ahead and assume that 64 bits is enough randomness. That's trivially true right
     
    183187           
    184188            vmDeallocatePhysicalPages(base, totalSize);
     189            setWasEnabled();
    185190            protectGigacageBasePtrs();
    186             g_wasEnabled = true;
    187191        });
    188192#endif // GIGACAGE_ENABLED
     
    237241static void primitiveGigacageDisabled(void*)
    238242{
     243    if (GIGACAGE_ALLOCATION_CAN_FAIL && !wasEnabled())
     244        return;
     245
    239246    static bool s_false;
    240247    fprintf(stderr, "FATAL: Primitive gigacage disabled, but we don't want that in this process.\n");
  • TabularUnified trunk/Source/bmalloc/bmalloc/Gigacage.h

    r237399 r239787  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7676namespace Gigacage {
    7777
    78 extern BEXPORT bool g_wasEnabled;
    79 BINLINE bool wasEnabled() { return g_wasEnabled; }
     78BINLINE bool wasEnabled() { return g_gigacageBasePtrs[0]; }
     79BINLINE void setWasEnabled() { g_gigacageBasePtrs[0] = true; }
    8080
    8181struct BasePtrs {
     82    uintptr_t reservedForFlags;
    8283    void* primitive;
    8384    void* jsValue;
     
    8586
    8687enum Kind {
     88    ReservedForFlagsAndNotABasePtr = 0,
    8789    Primitive,
    8890    JSValue,
    8991};
    9092
     93static_assert(offsetof(BasePtrs, primitive) == Kind::Primitive * sizeof(void*), "");
     94static_assert(offsetof(BasePtrs, jsValue) == Kind::JSValue * sizeof(void*), "");
     95
    9196static constexpr unsigned numKinds = 2;
    9297
     
    108113{
    109114    switch (kind) {
     115    case ReservedForFlagsAndNotABasePtr:
     116        RELEASE_BASSERT_NOT_REACHED();
    110117    case Primitive:
    111118        return "Primitive";
     
    120127{
    121128    switch (kind) {
     129    case ReservedForFlagsAndNotABasePtr:
     130        RELEASE_BASSERT_NOT_REACHED();
    122131    case Primitive:
    123132        return basePtrs.primitive;
     
    147156{
    148157    switch (kind) {
     158    case ReservedForFlagsAndNotABasePtr:
     159        RELEASE_BASSERT_NOT_REACHED();
    149160    case Primitive:
    150161        return static_cast<size_t>(PRIMITIVE_GIGACAGE_SIZE);
  • TabularUnified trunk/Source/bmalloc/bmalloc/HeapKind.h

    r231337 r239787  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7171{
    7272    switch (kind) {
     73    case Gigacage::ReservedForFlagsAndNotABasePtr:
     74        RELEASE_BASSERT_NOT_REACHED();
    7375    case Gigacage::Primitive:
    7476        return HeapKind::PrimitiveGigacage;
Note: See TracChangeset for help on using the changeset viewer.