__strcpy_chk.S revision 32bbf8a63bb43a540cc0f1dd5037736d10b70e0b
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <machine/asm.h> 30#include "libc_events.h" 31 32 .syntax unified 33 .fpu neon 34 .thumb 35 .thumb_func 36 37// Get the length of the source string first, then do a memcpy of the data 38// instead of a strcpy. 39ENTRY(__strcpy_chk) 40 .cfi_startproc 41 pld [r0, #0] 42 push {r0, lr} 43 .save {r0, lr} 44 .cfi_def_cfa_offset 8 45 .cfi_rel_offset r0, 0 46 .cfi_rel_offset lr, 4 47 48 mov lr, r2 49 mov r0, r1 50 51 ands r3, r0, #7 52 bne .L_align_src 53 54 .p2align 2 55.L_mainloop: 56 ldmia r0!, {r2, r3} 57 58 pld [r0, #64] 59 60 sub ip, r2, #0x01010101 61 bic ip, ip, r2 62 ands ip, ip, #0x80808080 63 bne .L_zero_in_first_register 64 65 sub ip, r3, #0x01010101 66 bic ip, ip, r3 67 ands ip, ip, #0x80808080 68 bne .L_zero_in_second_register 69 b .L_mainloop 70 71.L_zero_in_first_register: 72 sub r3, r0, r1 73 // Check for zero in byte 0. 74 lsls r2, ip, #17 75 beq .L_check_byte1_reg1 76 77 sub r3, r3, #8 78 b .L_check_size 79 80.L_check_byte1_reg1: 81 bcc .L_check_byte2_reg1 82 83 sub r3, r3, #7 84 b .L_check_size 85 86.L_check_byte2_reg1: 87 // Check for zero in byte 2. 88 tst ip, #0x800000 89 it ne 90 subne r3, r3, #6 91 bne .L_check_size 92 sub r3, r3, #5 93 b .L_check_size 94 95.L_zero_in_second_register: 96 sub r3, r0, r1 97 // Check for zero in byte 0. 98 lsls r2, ip, #17 99 beq .L_check_byte1_reg2 100 101 sub r3, r3, #4 102 b .L_check_size 103 104.L_check_byte1_reg2: 105 bcc .L_check_byte2_reg2 106 107 sub r3, r3, #3 108 b .L_check_size 109 110.L_check_byte2_reg2: 111 // Check for zero in byte 2. 112 tst ip, #0x800000 113 it ne 114 subne r3, r3, #2 115 bne .L_check_size 116 sub r3, r3, #1 117 b .L_check_size 118 119.L_align_src: 120 // Align to a double word (64 bits). 121 rsb r3, r3, #8 122 lsls ip, r3, #31 123 beq .L_align_to_32 124 125 ldrb r2, [r0], #1 126 cbz r2, .L_done 127 128.L_align_to_32: 129 bcc .L_align_to_64 130 131 ldrb r2, [r0], #1 132 cbz r2, .L_done 133 ldrb r2, [r0], #1 134 cbz r2, .L_done 135 136.L_align_to_64: 137 tst r3, #4 138 beq .L_mainloop 139 ldr r2, [r0], #4 140 141 sub ip, r2, #0x01010101 142 bic ip, ip, r2 143 ands ip, ip, #0x80808080 144 bne .L_zero_in_second_register 145 b .L_mainloop 146 147.L_done: 148 sub r3, r0, r1 149 sub r3, r3, #1 150 151.L_check_size: 152 pld [r1, #0] 153 pld [r1, #64] 154 ldr r0, [sp] 155 cmp r3, lr 156 bhs __strcpy_chk_fail 157 158 // Add 1 for copy length to get the string terminator. 159 add r2, r3, #1 160 161 .cfi_endproc 162 163 // Fall through into the memcpy_base function. 164END(__strcpy_chk) 165 166#define MEMCPY_BASE __strcpy_chk_memcpy_base 167#define MEMCPY_BASE_ALIGNED __strcpy_chk_memcpy_base_aligned 168#include "memcpy_base.S" 169 170ENTRY_PRIVATE(__strcpy_chk_fail) 171 .cfi_startproc 172 173 .save {r0, lr} 174 .cfi_def_cfa_offset 8 175 .cfi_rel_offset r0, 0 176 .cfi_rel_offset lr, 4 177 178 ldr r0, error_message 179 ldr r1, error_code 1801: 181 add r0, pc 182 bl __fortify_chk_fail 183 184error_code: 185 .word BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW 186error_message: 187 .word error_string-(1b+4) 188 189 .cfi_endproc 190END(__strcpy_chk_fail) 191 192 .data 193error_string: 194 .string "strcpy buffer overflow" 195