1// SPDX-License-Identifier: GPL-2.0-only 2// 3// Copyright 2024 Arm Limited 4// 5// Give ourselves GCS push 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 KSFT_SKIP 4 19 20.macro function name 21 .macro endfunction 22 .type \name, @function 23 .purgem endfunction 24 .endm 25\name: 26.endm 27 28// Print a single character x0 to stdout 29// Clobbers x0-x2,x8 30function putc 31 str x0, [sp, #-16]! 32 33 mov x0, #1 // STDOUT_FILENO 34 mov x1, sp 35 mov x2, #1 36 mov x8, #__NR_write 37 svc #0 38 39 add sp, sp, #16 40 ret 41endfunction 42.globl putc 43 44// Print a NUL-terminated string starting at address x0 to stdout 45// Clobbers x0-x3,x8 46function puts 47 mov x1, x0 48 49 mov x2, #0 500: ldrb w3, [x0], #1 51 cbz w3, 1f 52 add x2, x2, #1 53 b 0b 54 551: mov w0, #1 // STDOUT_FILENO 56 mov x8, #__NR_write 57 svc #0 58 59 ret 60endfunction 61.globl puts 62 63// Utility macro to print a literal string 64// Clobbers x0-x4,x8 65.macro puts string 66 .pushsection .rodata.str1.1, "aMS", @progbits, 1 67.L__puts_literal\@: .string "\string" 68 .popsection 69 70 ldr x0, =.L__puts_literal\@ 71 bl puts 72.endm 73 74.globl _start 75function _start 76 // Run with GCS 77 mov x0, PR_SET_SHADOW_STACK_STATUS 78 mov x1, PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH 79 mov x2, xzr 80 mov x3, xzr 81 mov x4, xzr 82 mov x5, xzr 83 mov x8, #__NR_prctl 84 svc #0 85 cbz x0, 1f 86 puts "Failed to enable GCS with push permission\n" 87 mov x0, #KSFT_SKIP 88 b 2f 891: 90 sys #3, c7, c7, #0, x0 // GCSPUSHM 91 sysl x0, #3, c7, c7, #1 // GCSPOPM 92 93 mov x0, #0 942: 95 mov x8, #__NR_exit 96 svc #0 97