linux/tools/testing/selftests/arm64/signal/testcases/testcases.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/* Copyright (C) 2019 ARM Limited */
   3#ifndef __TESTCASES_H__
   4#define __TESTCASES_H__
   5
   6#include <stddef.h>
   7#include <stdio.h>
   8#include <stdbool.h>
   9#include <stdint.h>
  10#include <stdlib.h>
  11#include <ucontext.h>
  12#include <signal.h>
  13
  14/* Architecture specific sigframe definitions */
  15#include <asm/sigcontext.h>
  16
  17#define FPSIMD_CTX      (1 << 0)
  18#define SVE_CTX         (1 << 1)
  19#define EXTRA_CTX       (1 << 2)
  20
  21#define KSFT_BAD_MAGIC  0xdeadbeef
  22
  23#define HDR_SZ \
  24        sizeof(struct _aarch64_ctx)
  25
  26#define GET_SF_RESV_HEAD(sf) \
  27        (struct _aarch64_ctx *)(&(sf).uc.uc_mcontext.__reserved)
  28
  29#define GET_SF_RESV_SIZE(sf) \
  30        sizeof((sf).uc.uc_mcontext.__reserved)
  31
  32#define GET_UCP_RESV_SIZE(ucp) \
  33        sizeof((ucp)->uc_mcontext.__reserved)
  34
  35#define ASSERT_BAD_CONTEXT(uc) do {                                     \
  36        char *err = NULL;                                               \
  37        if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) {  \
  38                if (err)                                                \
  39                        fprintf(stderr,                                 \
  40                                "Using badly built context - ERR: %s\n",\
  41                                err);                                   \
  42        } else {                                                        \
  43                abort();                                                \
  44        }                                                               \
  45} while (0)
  46
  47#define ASSERT_GOOD_CONTEXT(uc) do {                                     \
  48        char *err = NULL;                                                \
  49        if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) {   \
  50                if (err)                                                 \
  51                        fprintf(stderr,                                  \
  52                                "Detected BAD context - ERR: %s\n", err);\
  53                abort();                                                 \
  54        } else {                                                         \
  55                fprintf(stderr, "uc context validated.\n");              \
  56        }                                                                \
  57} while (0)
  58
  59/*
  60 * A simple record-walker for __reserved area: it walks through assuming
  61 * only to find a proper struct __aarch64_ctx header descriptor.
  62 *
  63 * Instead it makes no assumptions on the content and ordering of the
  64 * records, any needed bounds checking must be enforced by the caller
  65 * if wanted: this way can be used by caller on any maliciously built bad
  66 * contexts.
  67 *
  68 * head->size accounts both for payload and header _aarch64_ctx size !
  69 */
  70#define GET_RESV_NEXT_HEAD(h) \
  71        (struct _aarch64_ctx *)((char *)(h) + (h)->size)
  72
  73struct fake_sigframe {
  74        siginfo_t       info;
  75        ucontext_t      uc;
  76};
  77
  78
  79bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err);
  80
  81bool validate_extra_context(struct extra_context *extra, char **err);
  82
  83struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
  84                                size_t resv_sz, size_t *offset);
  85
  86static inline struct _aarch64_ctx *get_terminator(struct _aarch64_ctx *head,
  87                                                  size_t resv_sz,
  88                                                  size_t *offset)
  89{
  90        return get_header(head, 0, resv_sz, offset);
  91}
  92
  93static inline void write_terminator_record(struct _aarch64_ctx *tail)
  94{
  95        if (tail) {
  96                tail->magic = 0;
  97                tail->size = 0;
  98        }
  99}
 100
 101struct _aarch64_ctx *get_starting_head(struct _aarch64_ctx *shead,
 102                                       size_t need_sz, size_t resv_sz,
 103                                       size_t *offset);
 104#endif
 105