__strcpy_chk.S revision f0c3d909136167fdbe32b7815e5e1e02b4c35d62
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 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 .cfi_def_cfa_offset 8 44 .cfi_rel_offset r0, 0 45 .cfi_rel_offset lr, 4 46 47 mov lr, r2 48 mov r0, r1 49 50 ands r3, r1, #7 51 beq .L_mainloop 52 53 // Align to a double word (64 bits). 54 rsb r3, r3, #8 55 lsls ip, r3, #31 56 beq .L_align_to_32 57 58 ldrb r2, [r0], #1 59 cbz r2, .L_update_count_and_finish 60 61.L_align_to_32: 62 bcc .L_align_to_64 63 ands ip, r3, #2 64 beq .L_align_to_64 65 66 ldrb r2, [r0], #1 67 cbz r2, .L_update_count_and_finish 68 ldrb r2, [r0], #1 69 cbz r2, .L_update_count_and_finish 70 71.L_align_to_64: 72 tst r3, #4 73 beq .L_mainloop 74 ldr r3, [r0], #4 75 76 sub ip, r3, #0x01010101 77 bic ip, ip, r3 78 ands ip, ip, #0x80808080 79 bne .L_zero_in_second_register 80 81 .p2align 2 82.L_mainloop: 83 ldrd r2, r3, [r0], #8 84 85 pld [r0, #64] 86 87 sub ip, r2, #0x01010101 88 bic ip, ip, r2 89 ands ip, ip, #0x80808080 90 bne .L_zero_in_first_register 91 92 sub ip, r3, #0x01010101 93 bic ip, ip, r3 94 ands ip, ip, #0x80808080 95 bne .L_zero_in_second_register 96 b .L_mainloop 97 98.L_update_count_and_finish: 99 sub r3, r0, r1 100 sub r3, r3, #1 101 b .L_check_size 102 103.L_zero_in_first_register: 104 sub r3, r0, r1 105 lsls r2, ip, #17 106 bne .L_sub8_and_finish 107 bcs .L_sub7_and_finish 108 lsls ip, ip, #1 109 bne .L_sub6_and_finish 110 111 sub r3, r3, #5 112 b .L_check_size 113 114.L_sub8_and_finish: 115 sub r3, r3, #8 116 b .L_check_size 117 118.L_sub7_and_finish: 119 sub r3, r3, #7 120 b .L_check_size 121 122.L_sub6_and_finish: 123 sub r3, r3, #6 124 b .L_check_size 125 126.L_zero_in_second_register: 127 sub r3, r0, r1 128 lsls r2, ip, #17 129 bne .L_sub4_and_finish 130 bcs .L_sub3_and_finish 131 lsls ip, ip, #1 132 bne .L_sub2_and_finish 133 134 sub r3, r3, #1 135 b .L_check_size 136 137.L_sub4_and_finish: 138 sub r3, r3, #4 139 b .L_check_size 140 141.L_sub3_and_finish: 142 sub r3, r3, #3 143 b .L_check_size 144 145.L_sub2_and_finish: 146 sub r3, r3, #2 147 148.L_check_size: 149 pld [r1, #0] 150 pld [r1, #64] 151 ldr r0, [sp] 152 cmp r3, lr 153 bge .L_fortify_check_failed 154 155 // Add 1 for copy length to get the string terminator. 156 add r2, r3, #1 157 158 #include "memcpy_base.S" 159 160.L_fortify_check_failed: 161 ldr r0, error_message 162 ldr r1, error_code 1631: 164 add r0, pc 165 bl __fortify_chk_fail 166error_code: 167 .word BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW 168error_message: 169 .word error_string-(1b+4) 170 171 .cfi_endproc 172END(__strcpy_chk) 173 174 .data 175error_string: 176 .string "strcpy buffer overflow" 177