am 027a8fae: am 8539961f: Merge "FORTIFY_SOURCE: strcat / strncat optimize"

* commit '027a8fae7750855af2ec0f8dd655e4a48ebf9352':
  FORTIFY_SOURCE: strcat / strncat optimize
This commit is contained in:
Nick Kralevich
2013-05-31 11:21:18 -07:00
committed by Android Git Automerger
7 changed files with 354 additions and 40 deletions

View File

@@ -29,7 +29,6 @@
#include <string.h>
#include <stdlib.h>
#include "libc_logging.h"
#include <safe_iop.h>
/*
* Runtime implementation of __builtin____strcat_chk.
@@ -42,22 +41,24 @@
* This strcat check is called if _FORTIFY_SOURCE is defined and
* greater than 0.
*/
extern "C" char *__strcat_chk (char *dest, const char *src, size_t dest_buf_size) {
// TODO: optimize so we don't scan src/dest twice.
size_t src_len = strlen(src);
size_t dest_len = strlen(dest);
size_t sum;
extern "C" char* __strcat_chk(
char* __restrict dest,
const char* __restrict src,
size_t dest_buf_size)
{
char* save = dest;
size_t dest_len = __strlen_chk(dest, dest_buf_size);
// sum = src_len + dest_len + 1 (with overflow protection)
if (!safe_add3(&sum, src_len, dest_len, 1U)) {
__fortify_chk_fail("strcat integer overflow",
BIONIC_EVENT_STRCAT_INTEGER_OVERFLOW);
dest += dest_len;
dest_buf_size -= dest_len;
while ((*dest++ = *src++) != '\0') {
dest_buf_size--;
if (__predict_false(dest_buf_size == 0)) {
__fortify_chk_fail("strcat buffer overflow",
BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW);
}
}
if (sum > dest_buf_size) {
__fortify_chk_fail("strcat buffer overflow",
BIONIC_EVENT_STRCAT_BUFFER_OVERFLOW);
}
return strcat(dest, src);
return save;
}

View File

@@ -29,7 +29,6 @@
#include <string.h>
#include <stdlib.h>
#include "libc_logging.h"
#include <safe_iop.h>
/*
* Runtime implementation of __builtin____strncat_chk.
@@ -42,27 +41,33 @@
* This strncat check is called if _FORTIFY_SOURCE is defined and
* greater than 0.
*/
extern "C" char *__strncat_chk (char *dest, const char *src,
size_t len, size_t dest_buf_size)
extern "C" char *__strncat_chk(
char* __restrict dest,
const char* __restrict src,
size_t len, size_t dest_buf_size)
{
// TODO: optimize so we don't scan src/dest twice.
size_t dest_len = strlen(dest);
size_t src_len = strlen(src);
if (src_len > len) {
src_len = len;
if (len == 0) {
return dest;
}
size_t sum;
// sum = src_len + dest_len + 1 (with overflow protection)
if (!safe_add3(&sum, src_len, dest_len, 1U)) {
__fortify_chk_fail("strncat integer overflow",
BIONIC_EVENT_STRNCAT_INTEGER_OVERFLOW);
size_t dest_len = __strlen_chk(dest, dest_buf_size);
char *d = dest + dest_len;
dest_buf_size -= dest_len;
while (*src != '\0') {
*d++ = *src++;
len--; dest_buf_size--;
if (__predict_false(dest_buf_size == 0)) {
__fortify_chk_fail("strncat buffer overflow",
BIONIC_EVENT_STRNCAT_BUFFER_OVERFLOW);
}
if (len == 0) {
break;
}
}
if (sum > dest_buf_size) {
__fortify_chk_fail("strncat buffer overflow",
BIONIC_EVENT_STRNCAT_BUFFER_OVERFLOW);
}
return strncat(dest, src, len);
*d = '\0';
return dest;
}

View File

@@ -49,6 +49,7 @@ extern char* strchr(const char *, int) __purefunc;
extern char* strrchr(const char *, int) __purefunc;
extern size_t strlen(const char *) __purefunc;
extern size_t __strlen_chk(const char *, size_t);
extern int strcmp(const char *, const char *) __purefunc;
extern char* strcpy(char* __restrict, const char* __restrict);
extern char* strcat(char* __restrict, const char* __restrict);
@@ -207,8 +208,6 @@ size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {
return __strlcat_chk(dest, src, size, bos);
}
extern size_t __strlen_chk(const char *, size_t);
__BIONIC_FORTIFY_INLINE
size_t strlen(const char *s) {
size_t bos = __bos(s);

View File

@@ -45,9 +45,6 @@ enum {
BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW = 80125,
BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW = 80130,
BIONIC_EVENT_STRCAT_INTEGER_OVERFLOW = 80200,
BIONIC_EVENT_STRNCAT_INTEGER_OVERFLOW = 80205,
BIONIC_EVENT_RESOLVER_OLD_RESPONSE = 80300,
BIONIC_EVENT_RESOLVER_WRONG_SERVER = 80305,
BIONIC_EVENT_RESOLVER_WRONG_QUERY = 80310,