Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* Copyright (C) 2019 ARM Limited */
0003 #ifndef __TESTCASES_H__
0004 #define __TESTCASES_H__
0005 
0006 #include <stddef.h>
0007 #include <stdio.h>
0008 #include <stdbool.h>
0009 #include <stdint.h>
0010 #include <stdlib.h>
0011 #include <ucontext.h>
0012 #include <signal.h>
0013 
0014 /* Architecture specific sigframe definitions */
0015 #include <asm/sigcontext.h>
0016 
0017 #define FPSIMD_CTX  (1 << 0)
0018 #define SVE_CTX     (1 << 1)
0019 #define ZA_CTX      (1 << 2)
0020 #define EXTRA_CTX   (1 << 3)
0021 
0022 #define KSFT_BAD_MAGIC  0xdeadbeef
0023 
0024 #define HDR_SZ \
0025     sizeof(struct _aarch64_ctx)
0026 
0027 #define GET_SF_RESV_HEAD(sf) \
0028     (struct _aarch64_ctx *)(&(sf).uc.uc_mcontext.__reserved)
0029 
0030 #define GET_SF_RESV_SIZE(sf) \
0031     sizeof((sf).uc.uc_mcontext.__reserved)
0032 
0033 #define GET_UCP_RESV_SIZE(ucp) \
0034     sizeof((ucp)->uc_mcontext.__reserved)
0035 
0036 #define ASSERT_BAD_CONTEXT(uc) do {                 \
0037     char *err = NULL;                       \
0038     if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) {  \
0039         if (err)                        \
0040             fprintf(stderr,                 \
0041                 "Using badly built context - ERR: %s\n",\
0042                 err);                   \
0043     } else {                            \
0044         abort();                        \
0045     }                               \
0046 } while (0)
0047 
0048 #define ASSERT_GOOD_CONTEXT(uc) do {                     \
0049     char *err = NULL;                        \
0050     if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) {   \
0051         if (err)                         \
0052             fprintf(stderr,                  \
0053                 "Detected BAD context - ERR: %s\n", err);\
0054         abort();                         \
0055     } else {                             \
0056         fprintf(stderr, "uc context validated.\n");      \
0057     }                                \
0058 } while (0)
0059 
0060 /*
0061  * A simple record-walker for __reserved area: it walks through assuming
0062  * only to find a proper struct __aarch64_ctx header descriptor.
0063  *
0064  * Instead it makes no assumptions on the content and ordering of the
0065  * records, any needed bounds checking must be enforced by the caller
0066  * if wanted: this way can be used by caller on any maliciously built bad
0067  * contexts.
0068  *
0069  * head->size accounts both for payload and header _aarch64_ctx size !
0070  */
0071 #define GET_RESV_NEXT_HEAD(h) \
0072     (struct _aarch64_ctx *)((char *)(h) + (h)->size)
0073 
0074 struct fake_sigframe {
0075     siginfo_t   info;
0076     ucontext_t  uc;
0077 };
0078 
0079 
0080 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err);
0081 
0082 bool validate_extra_context(struct extra_context *extra, char **err);
0083 
0084 struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
0085                 size_t resv_sz, size_t *offset);
0086 
0087 static inline struct _aarch64_ctx *get_terminator(struct _aarch64_ctx *head,
0088                           size_t resv_sz,
0089                           size_t *offset)
0090 {
0091     return get_header(head, 0, resv_sz, offset);
0092 }
0093 
0094 static inline void write_terminator_record(struct _aarch64_ctx *tail)
0095 {
0096     if (tail) {
0097         tail->magic = 0;
0098         tail->size = 0;
0099     }
0100 }
0101 
0102 struct _aarch64_ctx *get_starting_head(struct _aarch64_ctx *shead,
0103                        size_t need_sz, size_t resv_sz,
0104                        size_t *offset);
0105 #endif