1/* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// Shell code that sets the current SELinux context to a given string. 18// 19// The desired SELinux context is appended to the payload as a null-terminated 20// string. 21// 22// After the SELinux context has been updated the current process will raise 23// SIGSTOP. 24 25#include "./shell-code/constants.S" 26#include "./shell-code/constants-x86.S" 27 28.globl __setcon_shell_code_start 29.globl __setcon_shell_code_end 30 31__setcon_shell_code_start: 32 33 // x86 does not have RIP relative addressing. To work around this, relative 34 // calls are used to obtain the runtime address of a label. Once the location 35 // of one label is known, other labels can be addressed relative to the known 36 // label. 37 call constant_relative_address 38constant_relative_address: 39 pop %esi 40 41 // Ensure that the context and SELinux /proc file are readable. This assumes 42 // that the max length of these two strings is shorter than 0x1000. 43 // 44 // mprotect(context & ~0xFFF, 0x2000, PROT_READ | PROT_EXEC) 45 mov $SYS_MPROTECT, %eax 46 mov $~0xFFF, %ebx 47 and %esi, %ebx 48 mov $0x2000, %ecx 49 mov $(PROT_READ | PROT_EXEC), %edx 50 int $0x80 51 52 // ebx = open("/proc/self/attr/current", O_WRONLY, O_WRONLY) 53 mov $SYS_OPEN, %eax 54 lea (selinux_proc_file - constant_relative_address)(%esi), %ebx 55 mov $O_WRONLY, %ecx 56 mov $O_WRONLY, %edx 57 int $0x80 58 mov %eax, %ebx 59 60 // write(ebx, context, strlen(context)) 61 xor %edx, %edx 62 leal (context - constant_relative_address)(%esi), %ecx 63strlen_start: 64 movb (%ecx, %edx), %al 65 test %al, %al 66 jz strlen_done 67 inc %edx 68 jmp strlen_start 69strlen_done: 70 mov $SYS_WRITE, %eax 71 int $0x80 72 73 // close(ebx) 74 mov $SYS_CLOSE, %eax 75 int $0x80 76 77 // ebx = getpid() 78 mov $SYS_GETPID, %eax 79 int $0x80 80 mov %eax, %ebx 81 82 // kill(ebx, SIGSTOP) 83 mov $SYS_KILL, %eax 84 mov $SIGSTOP, %ecx 85 int $0x80 86 87selinux_proc_file: 88 .asciz "/proc/self/attr/current" 89 90context: 91__setcon_shell_code_end: 92