From c51cd764a2d0897234762abd4dbd21420cb9f17d Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 22 Jan 2013 14:41:23 -0800 Subject: [PATCH] Avoid overflow in memccpy. Just take the upstream NetBSD code. Bug: http://code.google.com/p/android/issues/detail?id=43078 Change-Id: Ibbbde9d00e8bc6a09c9503aab2b04b4e3d1f98b0 --- libc/Android.mk | 2 +- libc/bionic/memccpy.c | 47 ----------------------- libc/upstream-netbsd/libc/string/memccpy.c | 61 ++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 48 deletions(-) delete mode 100644 libc/bionic/memccpy.c create mode 100644 libc/upstream-netbsd/libc/string/memccpy.c diff --git a/libc/Android.mk b/libc/Android.mk index 05373dc43..7d66805c9 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -182,7 +182,6 @@ libc_common_src_files := \ bionic/logd_write.c \ bionic/lseek64.c \ bionic/md5.c \ - bionic/memccpy.c \ bionic/memchr.c \ bionic/memmem.c \ bionic/memmove_words.c \ @@ -343,6 +342,7 @@ libc_upstream_netbsd_src_files := \ upstream-netbsd/libc/stdlib/tdelete.c \ upstream-netbsd/libc/stdlib/tfind.c \ upstream-netbsd/libc/stdlib/tsearch.c \ + upstream-netbsd/libc/string/memccpy.c \ upstream-netbsd/libc/string/strcasestr.c \ upstream-netbsd/libc/string/strxfrm.c \ upstream-netbsd/libc/unistd/killpg.c \ diff --git a/libc/bionic/memccpy.c b/libc/bionic/memccpy.c deleted file mode 100644 index 789fde61f..000000000 --- a/libc/bionic/memccpy.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 *memccpy(void *dst, const void *src, int c, size_t n) -{ - char* q = dst; - const char* p = src; - const char* p_end = p + n; - char ch = ~(char)c; /* ensure ch != c */ - - for (;;) { - if (ch == c || p >= p_end) break; - *q++ = ch = *p++; - } - - if (p >= p_end && ch != c) - return NULL; - - return q; -} diff --git a/libc/upstream-netbsd/libc/string/memccpy.c b/libc/upstream-netbsd/libc/string/memccpy.c new file mode 100644 index 000000000..c08624161 --- /dev/null +++ b/libc/upstream-netbsd/libc/string/memccpy.c @@ -0,0 +1,61 @@ +/* $NetBSD: memccpy.c,v 1.13 2012/06/25 22:32:46 abs Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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 +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: memccpy.c,v 1.13 2012/06/25 22:32:46 abs Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +void * +memccpy(void *t, const void *f, int c, size_t n) +{ + + _DIAGASSERT(t != 0); + _DIAGASSERT(f != 0); + + if (n) { + unsigned char *tp = t; + const unsigned char *fp = f; + unsigned char uc = c; + do { + if ((*tp++ = *fp++) == uc) + return (tp); + } while (--n != 0); + } + return (0); +} -- 2.11.0