blob: dc25098b69fca12653a32f4d991a88d97e0d376d [file] [log] [blame]
Peter Collingbourne6f1fd682020-01-29 16:27:31 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#pragma once
30
Mitch Phillipse8139f52022-11-23 15:18:01 -080031#include <stddef.h>
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080032#include <sys/auxv.h>
Mitch Phillips4cded972021-01-07 17:32:00 -080033#include <sys/prctl.h>
34
35// Note: Most PR_MTE_* constants come from the upstream kernel. This tag mask
36// allows for the hardware to provision any nonzero tag. Zero tags are reserved
37// for scudo to use for the chunk headers in order to prevent linear heap
38// overflow/underflow.
39#define PR_MTE_TAG_SET_NONZERO (0xfffeUL << PR_MTE_TAG_SHIFT)
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080040
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080041inline bool mte_supported() {
Peter Collingbourne7e201172020-12-21 14:08:38 -080042#if defined(__aarch64__)
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080043 static bool supported = getauxval(AT_HWCAP2) & HWCAP2_MTE;
44#else
45 static bool supported = false;
46#endif
47 return supported;
48}
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080049
Mitch Phillipse8139f52022-11-23 15:18:01 -080050inline void* get_tagged_address(const void* ptr) {
51#if defined(__aarch64__)
52 if (mte_supported()) {
53 __asm__ __volatile__(".arch_extension mte; ldg %0, [%0]" : "+r"(ptr));
54 }
55#endif // aarch64
56 return const_cast<void*>(ptr);
57}
58
59// Inserts a random tag tag to `ptr`, using any of the set lower 16 bits in
60// `mask` to exclude the corresponding tag from being generated. Note: This does
61// not tag memory.
62inline void* insert_random_tag(const void* ptr, __attribute__((unused)) uint64_t mask = 0) {
63#if defined(__aarch64__)
64 if (mte_supported() && ptr) {
65 __asm__ __volatile__(".arch_extension mte; irg %0, %0, %1" : "+r"(ptr) : "r"(mask));
66 }
67#endif // aarch64
68 return const_cast<void*>(ptr);
69}
70
71// Stores the address tag in `ptr` to memory, at `ptr`.
72inline void set_memory_tag(__attribute__((unused)) void* ptr) {
73#if defined(__aarch64__)
74 if (mte_supported()) {
75 __asm__ __volatile__(".arch_extension mte; stg %0, [%0]" : "+r"(ptr));
76 }
77#endif // aarch64
78}
79
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080080#ifdef __aarch64__
Peter Collingbournec8cef932020-02-14 19:19:32 -080081class ScopedDisableMTE {
82 size_t prev_tco_;
83
84 public:
85 ScopedDisableMTE() {
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080086 if (mte_supported()) {
Peter Collingbournec8cef932020-02-14 19:19:32 -080087 __asm__ __volatile__(".arch_extension mte; mrs %0, tco; msr tco, #1" : "=r"(prev_tco_));
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080088 }
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080089 }
90
91 ~ScopedDisableMTE() {
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080092 if (mte_supported()) {
Peter Collingbournec8cef932020-02-14 19:19:32 -080093 __asm__ __volatile__(".arch_extension mte; msr tco, %0" : : "r"(prev_tco_));
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080094 }
Peter Collingbourne6f1fd682020-01-29 16:27:31 -080095 }
96};
Peter Collingbournec8cef932020-02-14 19:19:32 -080097#else
98struct ScopedDisableMTE {
99 // Silence unused variable warnings in non-aarch64 builds.
100 ScopedDisableMTE() {}
101};
102#endif