1// SPDX-License-Identifier: GPL-2.0-only 2// 3// Copyright 2024 Arm Limited 4// 5// Give ourselves GCS write permissions then use them 6 7#include <asm/unistd.h> 8 9/* Shadow Stack/Guarded Control Stack interface */ 10#define PR_GET_SHADOW_STACK_STATUS 74 11#define PR_SET_SHADOW_STACK_STATUS 75 12#define PR_LOCK_SHADOW_STACK_STATUS 76 13 14# define PR_SHADOW_STACK_ENABLE (1UL << 0) 15# define PR_SHADOW_STACK_WRITE (1UL << 1) 16# define PR_SHADOW_STACK_PUSH (1UL << 2) 17 18#define GCSPR_EL0 S3_3_C2_C5_1 19 20#define KSFT_SKIP 4 21 22.macro function name 23 .macro endfunction 24 .type \name, @function 25 .purgem endfunction 26 .endm 27\name: 28.endm 29 30// Print a single character x0 to stdout 31// Clobbers x0-x2,x8 32function putc 33 str x0, [sp, #-16]! 34 35 mov x0, #1 // STDOUT_FILENO 36 mov x1, sp 37 mov x2, #1 38 mov x8, #__NR_write 39 svc #0 40 41 add sp, sp, #16 42 ret 43endfunction 44.globl putc 45 46// Print a NUL-terminated string starting at address x0 to stdout 47// Clobbers x0-x3,x8 48function puts 49 mov x1, x0 50 51 mov x2, #0 520: ldrb w3, [x0], #1 53 cbz w3, 1f 54 add x2, x2, #1 55 b 0b 56 571: mov w0, #1 // STDOUT_FILENO 58 mov x8, #__NR_write 59 svc #0 60 61 ret 62endfunction 63.globl puts 64 65// Utility macro to print a literal string 66// Clobbers x0-x4,x8 67.macro puts string 68 .pushsection .rodata.str1.1, "aMS", @progbits, 1 69.L__puts_literal\@: .string "\string" 70 .popsection 71 72 ldr x0, =.L__puts_literal\@ 73 bl puts 74.endm 75 76.globl _start 77function _start 78 // Run with GCS 79 mov x0, PR_SET_SHADOW_STACK_STATUS 80 mov x1, PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE 81 mov x2, xzr 82 mov x3, xzr 83 mov x4, xzr 84 mov x5, xzr 85 mov x8, #__NR_prctl 86 svc #0 87 cbz x0, 1f 88 puts "Failed to enable GCS with write permission\n" 89 mov x0, #KSFT_SKIP 90 b 2f 911: 92 mrs x0, GCSPR_EL0 93 sub x0, x0, #8 94 .inst 0xd91f1c01 // GCSSTR x1, x0 95 96 mov x0, #0 972: 98 mov x8, #__NR_exit 99 svc #0 100