diff options
Diffstat (limited to 'utils/shell-as/shell-code/selinux-arm.S')
-rw-r--r-- | utils/shell-as/shell-code/selinux-arm.S | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/utils/shell-as/shell-code/selinux-arm.S b/utils/shell-as/shell-code/selinux-arm.S new file mode 100644 index 000000000..0c9480f9b --- /dev/null +++ b/utils/shell-as/shell-code/selinux-arm.S @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Shell code that sets the current SELinux context to a given string. +// +// The desired SELinux context is appended to the payload as a null-terminated +// string. +// +// After the SELinux context has been updated the current process will raise +// SIGSTOP. + +#include "./shell-code/constants.S" +#include "./shell-code/constants-arm.S" + +.thumb + +.globl __setcon_shell_code_start +.globl __setcon_shell_code_end + +__setcon_shell_code_start: + // Ensure that the context and SELinux /proc file are readable. This assumes + // that the max length of these two strings is shorter than 0x1000. + // + // mprotect(context & ~0xFFF, 0x2000, PROT_READ | PROT_EXEC) + mov r7, SYS_MPROTECT + adr r0, context + movw r2, 0xF000 + movt r2, 0xFFFF + and r0, r0, r2 + mov r1, 0x2000 + mov r2, (PROT_READ | PROT_EXEC) + swi 0 + + // r10 = open("/proc/self/attr/current", O_WRONLY, O_WRONLY) + mov r7, SYS_OPEN + adr r0, selinux_proc_file + mov r1, O_WRONLY + mov r2, O_WRONLY + swi 0 + mov r10, r0 + + // r11 = strlen(context) + mov r11, 0 + adr r0, context +strlen_start: + ldrb r1, [r0, r11] + cmp r1, 0 + beq strlen_done + add r11, r11, 1 + b strlen_start +strlen_done: + + // write(r10, context, r11) + mov r7, SYS_WRITE + mov r0, r10 + adr r1, context + mov r2, r11 + swi 0 + + // close(r10) + mov r7, SYS_CLOSE + mov r0, r10 + swi 0 + + // r0 = getpid() + mov r7, SYS_GETPID + swi 0 + + // kill(r0, SIGSTOP) + mov r7, SYS_KILL + mov r1, SIGSTOP + swi 0 + +selinux_proc_file: + .asciz "/proc/thread-self/attr/current" + +context: +__setcon_shell_code_end: |