Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/trusty/trusty/user/base/lib/hwasan/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 4 kB image not shown  

Quelle  hwasan.c

  Sprache: C
 

/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#define TLOG_TAG "hwasan-rt"

#include "hwasan.h"
#include <lib/hwasan/hwasan_shadow.h>

#include <assert.h>
#include <lk/compiler.h>
#include <lk/macros.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/auxv.h>
#include <trusty_log.h>
#include <uapi/err.h>

uintptr_t __hwasan_shadow_memory_dynamic_address = 0;

static inline uint8_t get_tag(uintptr_t ptr) {
    return (uint64_t)ptr >> hwasan_addr_tag_shift;
}

static inline uintptr_t remove_ptr_tag(uintptr_t ptr) {
    return ptr & ~hwasan_addr_tag_mask;
}

static inline uintptr_t tag_ptr(uintptr_t ptr, uint8_t tag) {
    uint64_t tag_mask = (uint64_t)tag << hwasan_addr_tag_shift;
    return remove_ptr_tag(ptr) | tag_mask;
}

/* Tagging granularity is 1 tag per 16 bytes */
static inline uintptr_t mem_to_shadow(uintptr_t ptr) {
    ptr = remove_ptr_tag(ptr);
    return (ptr >> HWASAN_SHADOW_SCALE) +
           __hwasan_shadow_memory_dynamic_address;
}

static inline bool is_valid_user_ptr(uintptr_t ptr) {
    ptr = remove_ptr_tag(ptr);
    return !ptr || (ptr >= USER_ASPACE_BASE &&
                    ptr < USER_ASPACE_BASE + USER_ASPACE_SIZE);
}

__WEAK void __hwasan_report_error(uintptr_t far) {
    /* TODO(b/149918767): unwind stack, analyze, and report error */
    uint8_t ptr_tag = get_tag(far);
    uint8_t* shadow_tag = (uint8_t*)mem_to_shadow(far);

    TLOGE("Failed address check. Fault address: 0x%16lx, pointer tag: 0x%x, "
          "expected tag: 0x%x\n",
          far, ptr_tag, *shadow_tag);

    abort();
}

static void check_address(uintptr_t ptr, size_t size) {
    assert(is_valid_user_ptr(ptr));

    if (!ptr || size == 0) {
        /* Pass the address check since NULL pointer dereference segfaults
         * anyways */

        return;
    }

    uint8_t ptr_tag = get_tag(ptr);
    uint8_t* first_tag = (uint8_t*)mem_to_shadow(ptr);
    uint8_t* last_tag = (uint8_t*)mem_to_shadow(ptr + size - 1);
    for (uint8_t* tag = first_tag; tag <= last_tag; tag++) {
        if (ptr_tag != *tag) {
            uintptr_t far =
                    ptr + ((uintptr_t)(tag - first_tag) << HWASAN_SHADOW_SCALE);
            __hwasan_report_error(far);
        }
    }
}

void __hwasan_init(void) {
    if (!__hwasan_shadow_memory_dynamic_address) {
        __hwasan_shadow_memory_dynamic_address =
                getauxval(TRUSTY_AT_HWASAN_SHADOW);
        assert(__hwasan_shadow_memory_dynamic_address);
    }
}

void* __hwasan_memset(uintptr_t ptr, int val, size_t size) {
    check_address(ptr, size);
    return memset((void*)ptr, val, size);
}

void* __hwasan_memcpy(uintptr_t dst, const uintptr_t src, size_t size) {
    check_address(dst, size);
    check_address(src, size);
    return memcpy((void*)dst, (void*)src, size);
}

void* __hwasan_memmove(uintptr_t dst, const uintptr_t src, size_t size) {
    check_address(dst, size);
    check_address(src, size);
    return memmove((void*)dst, (void*)src, size);
}

void __hwasan_loadN(uintptr_t ptr, size_t size) {
    check_address(ptr, size);
}

void __hwasan_storeN(uintptr_t ptr, size_t size) {
    check_address(ptr, size);
}

static uint8_t hwasan_generate_tag() {
    static uint8_t tag = 0;
    /* 0 tag corresponds to untagged memory, so avoid generating it */
    if (__builtin_add_overflow(tag, 1, &tag)) {
        tag = 1;
    }
    return tag;
}

static uintptr_t hwasan_tag_memory_etc(uintptr_t ptr,
                                       size_t size,
                                       uint8_t tag) {
    assert(IS_ALIGNED(ptr, 1U << HWASAN_SHADOW_SCALE));
    assert(is_valid_user_ptr(ptr));

    /*
     * It's possible that dlmalloc() fails to allocate memory, in which case it
     * passes NULL here.
     */

    if (!ptr || !size) {
        return ptr;
    }

    uint8_t* first_tag = (uint8_t*)mem_to_shadow(ptr);
    uint8_t* last_tag = (uint8_t*)mem_to_shadow(ptr + size - 1);
    for (uint8_t* i = first_tag; i <= last_tag; i++) {
        *i = tag;
    }
    return tag_ptr(ptr, tag);
}

void* hwasan_tag_memory(void* ptr, size_t size) {
    return (void*)hwasan_tag_memory_etc((uintptr_t)ptr, size,
                                        hwasan_generate_tag());
}

void hwasan_untag_memory(void* ptr, size_t size) {
    hwasan_tag_memory_etc((uintptr_t)ptr, size, 0);
}

void* hwasan_remove_ptr_tag(void* ptr) {
    return (void*)remove_ptr_tag((uintptr_t)ptr);
}

Messung V0.5 in Prozent
C=85 H=85 G=84

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.