10a2301598c207fd1b50015984942fee5e8511593Nick Kralevich/*
20a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * Copyright (C) 2012 The Android Open Source Project
30a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * All rights reserved.
40a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *
50a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * Redistribution and use in source and binary forms, with or without
60a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * modification, are permitted provided that the following conditions
70a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * are met:
80a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *  * Redistributions of source code must retain the above copyright
90a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *    notice, this list of conditions and the following disclaimer.
100a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *  * Redistributions in binary form must reproduce the above copyright
110a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *    notice, this list of conditions and the following disclaimer in
120a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *    the documentation and/or other materials provided with the
130a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *    distribution.
140a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *
150a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
160a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
170a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
180a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
190a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
200a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
210a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
220a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
230a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
240a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
250a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
260a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * SUCH DAMAGE.
270a2301598c207fd1b50015984942fee5e8511593Nick Kralevich */
280a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
290a2301598c207fd1b50015984942fee5e8511593Nick Kralevich#include <string.h>
300a2301598c207fd1b50015984942fee5e8511593Nick Kralevich#include <stdlib.h>
310a2301598c207fd1b50015984942fee5e8511593Nick Kralevich#include <private/logd.h>
3276656afc6dd069fcfda5768e6e54bb85e4e99942Nick Kralevich#include <safe_iop.h>
330a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
340a2301598c207fd1b50015984942fee5e8511593Nick Kralevich/*
350a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * Runtime implementation of __builtin____strcat_chk.
360a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *
370a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * See
380a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *   http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
390a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
400a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * for details.
410a2301598c207fd1b50015984942fee5e8511593Nick Kralevich *
420a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * This strcat check is called if _FORTIFY_SOURCE is defined and
430a2301598c207fd1b50015984942fee5e8511593Nick Kralevich * greater than 0.
440a2301598c207fd1b50015984942fee5e8511593Nick Kralevich */
450a2301598c207fd1b50015984942fee5e8511593Nick Kralevichchar *__strcat_chk (char *dest, const char *src, size_t dest_buf_size)
460a2301598c207fd1b50015984942fee5e8511593Nick Kralevich{
470a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    // TODO: optimize so we don't scan src/dest twice.
480a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    size_t src_len  = strlen(src);
490a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    size_t dest_len = strlen(dest);
5076656afc6dd069fcfda5768e6e54bb85e4e99942Nick Kralevich    size_t sum;
510a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
5276656afc6dd069fcfda5768e6e54bb85e4e99942Nick Kralevich    // sum = src_len + dest_len + 1 (with overflow protection)
53009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra    if (!safe_add3(&sum, src_len, dest_len, 1U)) {
54009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
55009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra            "*** strcat integer overflow detected ***\n");
56009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra        __libc_android_log_event_uid(BIONIC_EVENT_STRCAT_INTEGER_OVERFLOW);
57009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra        abort();
58009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra    }
5976656afc6dd069fcfda5768e6e54bb85e4e99942Nick Kralevich
6076656afc6dd069fcfda5768e6e54bb85e4e99942Nick Kralevich    if (sum > dest_buf_size) {
610a2301598c207fd1b50015984942fee5e8511593Nick Kralevich        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
620a2301598c207fd1b50015984942fee5e8511593Nick Kralevich            "*** strcat buffer overflow detected ***\n");
63009f38478e6a1c47aa355b0aed80b69ba91b9c61Geremy Condra        __libc_android_log_event_uid(BIONIC_EVENT_STRNCAT_BUFFER_OVERFLOW);
640a2301598c207fd1b50015984942fee5e8511593Nick Kralevich        abort();
650a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    }
660a2301598c207fd1b50015984942fee5e8511593Nick Kralevich
670a2301598c207fd1b50015984942fee5e8511593Nick Kralevich    return strcat(dest, src);
680a2301598c207fd1b50015984942fee5e8511593Nick Kralevich}
69