From 41ef902379ba24bd8a3ca6d7733b8376efb55ebd Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Sat, 14 Feb 2015 13:21:22 -0800 Subject: [PATCH] Fix memchr overflow. The overflow's actually in the generic C implementation of memchr. While I'm here, let's switch our generic memrchr to the OpenBSD version too. Bug: https://code.google.com/p/android/issues/detail?id=147048 Change-Id: I296ae06a1ee196d2c77c95a22f11ee4d658962da --- libc/arch-arm/arm.mk | 4 +- libc/arch-arm64/arm64.mk | 2 +- libc/arch-mips/mips.mk | 4 +- libc/arch-mips64/mips64.mk | 4 +- libc/arch-x86_64/x86_64.mk | 6 ++- libc/bionic/memchr.c | 46 ------------------ libc/bionic/memrchr.c | 47 ------------------ .../upstream-openbsd/lib/libc/string/memchr.c | 48 +++++++++++++++++++ .../lib/libc/string/memrchr.c | 38 +++++++++++++++ tests/string_test.cpp | 10 ++++ 10 files changed, 107 insertions(+), 102 deletions(-) delete mode 100644 libc/bionic/memchr.c delete mode 100644 libc/bionic/memrchr.c create mode 100644 libc/upstream-openbsd/lib/libc/string/memchr.c create mode 100644 libc/upstream-openbsd/lib/libc/string/memrchr.c diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk index 60600e5fd..d72a160d0 100644 --- a/libc/arch-arm/arm.mk +++ b/libc/arch-arm/arm.mk @@ -5,8 +5,6 @@ # libc_bionic_src_files_arm += \ - bionic/memchr.c \ - bionic/memrchr.c \ bionic/strchr.cpp \ bionic/strnlen.c \ bionic/strrchr.cpp \ @@ -22,6 +20,8 @@ libc_freebsd_src_files_arm += \ upstream-freebsd/lib/libc/string/wmemmove.c \ libc_openbsd_src_files_arm += \ + upstream-openbsd/lib/libc/string/memchr.c \ + upstream-openbsd/lib/libc/string/memrchr.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ upstream-openbsd/lib/libc/string/strlcat.c \ upstream-openbsd/lib/libc/string/strlcpy.c \ diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk index 841899329..470a03838 100644 --- a/libc/arch-arm64/arm64.mk +++ b/libc/arch-arm64/arm64.mk @@ -8,7 +8,6 @@ libc_bionic_src_files_arm64 += \ bionic/__memset_chk.cpp \ bionic/__strcpy_chk.cpp \ bionic/__strcat_chk.cpp \ - bionic/memrchr.c \ bionic/strrchr.cpp \ libc_freebsd_src_files_arm64 += \ @@ -21,6 +20,7 @@ libc_freebsd_src_files_arm64 += \ upstream-freebsd/lib/libc/string/wmemcmp.c \ libc_openbsd_src_files_arm64 += \ + upstream-openbsd/lib/libc/string/memrchr.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ upstream-openbsd/lib/libc/string/strcat.c \ upstream-openbsd/lib/libc/string/strlcat.c \ diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk index 7e3fe25ae..33eceab72 100644 --- a/libc/arch-mips/mips.mk +++ b/libc/arch-mips/mips.mk @@ -10,8 +10,6 @@ libc_bionic_src_files_mips += \ bionic/__memset_chk.cpp \ bionic/__strcpy_chk.cpp \ bionic/__strcat_chk.cpp \ - bionic/memchr.c \ - bionic/memrchr.c \ bionic/strchr.cpp \ bionic/strnlen.c \ bionic/strrchr.cpp \ @@ -27,7 +25,9 @@ libc_freebsd_src_files_mips += \ upstream-freebsd/lib/libc/string/wmemmove.c \ libc_openbsd_src_files_mips += \ + upstream-openbsd/lib/libc/string/memchr.c \ upstream-openbsd/lib/libc/string/memmove.c \ + upstream-openbsd/lib/libc/string/memrchr.c \ upstream-openbsd/lib/libc/string/stpcpy.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ upstream-openbsd/lib/libc/string/strcat.c \ diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk index 137639550..2b81e635c 100644 --- a/libc/arch-mips64/mips64.mk +++ b/libc/arch-mips64/mips64.mk @@ -9,8 +9,6 @@ libc_bionic_src_files_mips64 += \ bionic/__memset_chk.cpp \ bionic/__strcpy_chk.cpp \ bionic/__strcat_chk.cpp \ - bionic/memchr.c \ - bionic/memrchr.c \ bionic/strchr.cpp \ bionic/strnlen.c \ bionic/strrchr.cpp \ @@ -30,7 +28,9 @@ libc_freebsd_src_files_mips64 += \ upstream-freebsd/lib/libc/string/wmemmove.c \ libc_openbsd_src_files_mips64 += \ + upstream-openbsd/lib/libc/string/memchr.c \ upstream-openbsd/lib/libc/string/memmove.c \ + upstream-openbsd/lib/libc/string/memrchr.c \ upstream-openbsd/lib/libc/string/stpcpy.c \ upstream-openbsd/lib/libc/string/stpncpy.c \ upstream-openbsd/lib/libc/string/strcat.c \ diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk index ae01d2a0a..06d318574 100644 --- a/libc/arch-x86_64/x86_64.mk +++ b/libc/arch-x86_64/x86_64.mk @@ -9,8 +9,6 @@ libc_bionic_src_files_x86_64 += \ bionic/__memset_chk.cpp \ bionic/__strcpy_chk.cpp \ bionic/__strcat_chk.cpp \ - bionic/memchr.c \ - bionic/memrchr.c \ bionic/strchr.cpp \ bionic/strnlen.c \ bionic/strrchr.cpp \ @@ -25,6 +23,10 @@ libc_freebsd_src_files_x86_64 += \ upstream-freebsd/lib/libc/string/wmemcmp.c \ upstream-freebsd/lib/libc/string/wmemmove.c \ +libc_openbsd_src_files_x86_64 += \ + upstream-openbsd/lib/libc/string/memchr.c \ + upstream-openbsd/lib/libc/string/memrchr.c \ + # # Inherently architecture-specific code. # diff --git a/libc/bionic/memchr.c b/libc/bionic/memchr.c deleted file mode 100644 index b14167abd..000000000 --- a/libc/bionic/memchr.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include -#include - -void *memchr(const void *s, int c, size_t n) -{ - const unsigned char* p = s; - const unsigned char* end = p + n; - - for (;;) { - if (p >= end || p[0] == c) break; p++; - if (p >= end || p[0] == c) break; p++; - if (p >= end || p[0] == c) break; p++; - if (p >= end || p[0] == c) break; p++; - } - if (p >= end) - return NULL; - else - return (void*) p; -} diff --git a/libc/bionic/memrchr.c b/libc/bionic/memrchr.c deleted file mode 100644 index aeb5643b0..000000000 --- a/libc/bionic/memrchr.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include -#include - -void *memrchr(const void *s, int c, size_t n) -{ - if (n > 0) { - const char* p = (const char*) s; - const char* q = p + n; - - while (1) { - q--; if (q < p || q[0] == (char) c) break; - q--; if (q < p || q[0] == (char) c) break; - q--; if (q < p || q[0] == (char) c) break; - q--; if (q < p || q[0] == (char) c) break; - } - if (q >= p) - return (void*)q; - } - return NULL; -} diff --git a/libc/upstream-openbsd/lib/libc/string/memchr.c b/libc/upstream-openbsd/lib/libc/string/memchr.c new file mode 100644 index 000000000..4573e3ceb --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/string/memchr.c @@ -0,0 +1,48 @@ +/* $OpenBSD: memchr.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +void * +memchr(const void *s, int c, size_t n) +{ + if (n != 0) { + const unsigned char *p = s; + + do { + if (*p++ == (unsigned char)c) + return ((void *)(p - 1)); + } while (--n != 0); + } + return (NULL); +} diff --git a/libc/upstream-openbsd/lib/libc/string/memrchr.c b/libc/upstream-openbsd/lib/libc/string/memrchr.c new file mode 100644 index 000000000..bd27ebc62 --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/string/memrchr.c @@ -0,0 +1,38 @@ +/* $OpenBSD: memrchr.c,v 1.2 2007/11/27 16:22:12 martynas Exp $ */ + +/* + * Copyright (c) 2007 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +/* + * Reverse memchr() + * Find the last occurrence of 'c' in the buffer 's' of size 'n'. + */ +void * +memrchr(const void *s, int c, size_t n) +{ + const unsigned char *cp; + + if (n != 0) { + cp = (unsigned char *)s + n; + do { + if (*(--cp) == (unsigned char)c) + return((void *)cp); + } while (--n != 0); + } + return(NULL); +} diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 137565e25..66cf848c9 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -1385,3 +1385,13 @@ TEST(string, __gnu_basename) { TestBasename("///", ""); TestBasename("//usr//lib//", ""); } + +TEST(string, strnlen_147048) { + // https://code.google.com/p/android/issues/detail?id=147048 + char stack_src[64] = {0}; + EXPECT_EQ(0U, strnlen(stack_src, 1024*1024*1024)); + char* heap_src = new char[1]; + *heap_src = '\0'; + EXPECT_EQ(0U, strnlen(heap_src, 1024*1024*1024)); + delete[] heap_src; +}