Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5354870a authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12235414 from 7b99ad16 to 24Q4-release

Change-Id: I1782b44609a5f621a1e046e1fc397f0a3138c848
parents 73a4204e 7b99ad16
Loading
Loading
Loading
Loading
+85 −2
Original line number Original line Diff line number Diff line
@@ -36,10 +36,12 @@
#include <sys/uio.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <unistd.h>


#include <android-base/macros.h>
#include <android-base/macros.h>
#include <android-base/parsebool.h>
#include <android-base/parsebool.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <android-base/unique_fd.h>
#include <async_safe/log.h>
#include <async_safe/log.h>
@@ -115,6 +117,59 @@ static bool is_permissive_mte() {
         (permissive_env && ParseBool(permissive_env) == ParseBoolResult::kTrue);
         (permissive_env && ParseBool(permissive_env) == ParseBoolResult::kTrue);
}
}


static bool parse_uint_with_error_reporting(const char* s, const char* name, int* v) {
  if (android::base::ParseInt(s, v) && *v >= 0) {
    return true;
  }
  async_safe_format_log(ANDROID_LOG_ERROR, "libc", "invalid %s: %s", name, s);
  return false;
}

// We cannot use base::GetIntProperty, because that internally uses
// std::string, which allocates.
static bool property_parse_int(const char* name, int* out) {
  const prop_info* pi = __system_property_find(name);
  if (!pi) return false;
  struct cookie_t {
    int* out;
    bool empty;
  } cookie{out, true};
  __system_property_read_callback(
      pi,
      [](void* raw_cookie, const char* name, const char* value, uint32_t) {
        // Property is set to empty value, ignoring.
        if (!*value) return;
        cookie_t* cookie = reinterpret_cast<cookie_t*>(raw_cookie);
        if (parse_uint_with_error_reporting(value, name, cookie->out)) cookie->empty = false;
      },
      &cookie);
  return !cookie.empty;
}

static int permissive_mte_renable_timer() {
  if (char* env = getenv("MTE_PERMISSIVE_REENABLE_TIME_CPUMS")) {
    int v;
    if (parse_uint_with_error_reporting(env, "MTE_PERMISSIVE_REENABLE_TIME_CPUMS", &v)) return v;
  }

  char process_sysprop_name[512];
  async_safe_format_buffer(process_sysprop_name, sizeof(process_sysprop_name),
                           "persist.sys.mte.permissive_reenable_timer.process.%s", getprogname());
  int v;
  if (property_parse_int(process_sysprop_name, &v)) return v;
  if (property_parse_int("persist.sys.mte.permissive_reenable_timer.default", &v)) return v;
  char process_deviceconf_sysprop_name[512];
  async_safe_format_buffer(
      process_deviceconf_sysprop_name, sizeof(process_deviceconf_sysprop_name),
      "persist.device_config.memory_safety_native.permissive_reenable_timer.process.%s",
      getprogname());
  if (property_parse_int(process_deviceconf_sysprop_name, &v)) return v;
  if (property_parse_int(
          "persist.device_config.memory_safety_native.permissive_reenable_timer.default", &v))
    return v;
  return 0;
}

static inline void futex_wait(volatile void* ftx, int value) {
static inline void futex_wait(volatile void* ftx, int value) {
  syscall(__NR_futex, ftx, FUTEX_WAIT, value, nullptr, nullptr, 0);
  syscall(__NR_futex, ftx, FUTEX_WAIT, value, nullptr, nullptr, 0);
}
}
@@ -599,12 +654,40 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
    if (tagged_addr_ctrl < 0) {
    if (tagged_addr_ctrl < 0) {
      fatal_errno("failed to PR_GET_TAGGED_ADDR_CTRL");
      fatal_errno("failed to PR_GET_TAGGED_ADDR_CTRL");
    }
    }
    int previous = tagged_addr_ctrl & PR_MTE_TCF_MASK;
    tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | PR_MTE_TCF_NONE;
    tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | PR_MTE_TCF_NONE;
    if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) {
    if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) {
      fatal_errno("failed to PR_SET_TAGGED_ADDR_CTRL");
      fatal_errno("failed to PR_SET_TAGGED_ADDR_CTRL");
    }
    }
    if (int reenable_timer = permissive_mte_renable_timer()) {
      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
                          "MTE ERROR DETECTED BUT RUNNING IN PERMISSIVE MODE. CONTINUING.");
                            "MTE ERROR DETECTED BUT RUNNING IN PERMISSIVE MODE. CONTINUING WITH "
                            "MTE DISABLED FOR %d MS OF CPU TIME.",
                            reenable_timer);
      timer_t timerid{};
      struct sigevent sev {};
      sev.sigev_signo = BIONIC_ENABLE_MTE;
      sev.sigev_notify = SIGEV_THREAD_ID;
      sev.sigev_value.sival_int = previous;
      sev.sigev_notify_thread_id = __gettid();
      // This MUST be CLOCK_THREAD_CPUTIME_ID. If we used CLOCK_MONOTONIC we could get stuck
      // in an endless loop of re-running the same instruction, calling this signal handler,
      // and re-enabling MTE before we had a chance to re-run the instruction.
      if (timer_create(CLOCK_THREAD_CPUTIME_ID, &sev, &timerid) == -1) {
        fatal_errno("timer_create() failed");
      }
      struct itimerspec its {};
      its.it_value.tv_sec = reenable_timer / 1000;
      its.it_value.tv_nsec = (reenable_timer % 1000) * 1000000;

      if (timer_settime(timerid, 0, &its, nullptr) == -1) {
        fatal_errno("timer_settime() failed");
      }
    } else {
      async_safe_format_log(
          ANDROID_LOG_ERROR, "libc",
          "MTE ERROR DETECTED BUT RUNNING IN PERMISSIVE MODE. CONTINUING WITH MTE DISABLED.");
    }
    pthread_mutex_unlock(&crash_mutex);
    pthread_mutex_unlock(&crash_mutex);
  }
  }


+9 −0
Original line number Original line Diff line number Diff line
@@ -20,5 +20,14 @@
int main(int, char**) {
int main(int, char**) {
  volatile char* f = (char*)malloc(1);
  volatile char* f = (char*)malloc(1);
  printf("%c\n", f[17]);
  printf("%c\n", f[17]);
#ifdef __aarch64__
  if (getenv("MTE_PERMISSIVE_REENABLE_TIME_CPUMS")) {
    // Burn some cycles because the MTE_PERMISSIVE_REENABLE_TIME_CPUMS is based on CPU clock.
    for (int i = 0; i < 1000000000; ++i) {
      asm("isb");
    }
    printf("%c\n", f[17]);
  }
#endif
  return 0;
  return 0;
}
}
+28 −0
Original line number Original line Diff line number Diff line
@@ -97,6 +97,34 @@ public class PermissiveMteTest extends BaseHostJUnit4Test {
    }
    }
    assertThat(numberTombstones).isEqualTo(1);
    assertThat(numberTombstones).isEqualTo(1);
  }
  }

  @Test
  public void testReenableCrash() throws Exception {
    CommandResult result =
        getDevice().executeShellV2Command("MTE_PERMISSIVE=1 MTE_PERMISSIVE_REENABLE_TIME_CPUMS=1 "
                                          + "/data/local/tmp/mte_crash testReenableCrash "
                                          + mUUID);
    assertThat(result.getExitCode()).isEqualTo(0);
    int numberTombstones = 0;
    String[] tombstones = getDevice().getChildren("/data/tombstones");
    for (String tombstone : tombstones) {
      if (!tombstone.endsWith(".pb")) {
        continue;
      }
      String tombstonePath = "/data/tombstones/" + tombstone;
      Tombstone tombstoneProto = parseTombstone(tombstonePath);
      if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains(mUUID))) {
        continue;
      }
      if (!tombstoneProto.getCommandLineList().stream().anyMatch(
              x -> x.contains("testReenableCrash"))) {
        continue;
      }
      numberTombstones++;
    }
    assertThat(numberTombstones).isEqualTo(2);
  }

  @Test
  @Test
  public void testCrashProperty() throws Exception {
  public void testCrashProperty() throws Exception {
    String prevValue = getDevice().getProperty("persist.sys.mte.permissive");
    String prevValue = getDevice().getProperty("persist.sys.mte.permissive");
+0 −1
Original line number Original line Diff line number Diff line
@@ -226,7 +226,6 @@ cc_defaults {
    ],
    ],
    whole_static_libs: [
    whole_static_libs: [
        "libcap",
        "libcap",
        "libcom.android.sysprop.init",
    ],
    ],
    header_libs: ["bootimg_headers"],
    header_libs: ["bootimg_headers"],
    proto: {
    proto: {
+0 −1
Original line number Original line Diff line number Diff line
@@ -46,7 +46,6 @@
#include <map>
#include <map>
#include <memory>
#include <memory>


#include <InitProperties.sysprop.h>
#include <android-base/chrono_utils.h>
#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/logging.h>
Loading