Index: etc/mtree/BSD.include.dist =================================================================== --- etc/mtree/BSD.include.dist +++ etc/mtree/BSD.include.dist @@ -321,6 +321,8 @@ mac_partition .. .. + secure + .. ssp .. sys Index: include/Makefile =================================================================== --- include/Makefile +++ include/Makefile @@ -6,7 +6,7 @@ .include CLEANFILES= osreldate.h version vers.c -SUBDIR= arpa protocols rpcsvc rpc xlocale +SUBDIR= arpa protocols rpcsvc rpc secure xlocale INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \ db.h \ dirent.h dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \ Index: include/secure/Makefile =================================================================== --- /dev/null +++ include/secure/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +INCS= security.h _poll.h _socket.h _stat.h _stdio.h _string.h _strings.h _unistd.h +INCSDIR= ${INCLUDEDIR}/secure + +.include Index: include/secure/_poll.h =================================================================== --- /dev/null +++ include/secure/_poll.h @@ -0,0 +1,96 @@ +/* + * 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. + * + * bionic rev: eeb9f5e41662828989f3913d81ec23229a668434 + * + * $FreeBSD$ + */ + +#ifndef _SYS_POLL_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_POLL_H_ +#define _SECURE_POLL_H_ + +#include + +__BEGIN_DECLS + +int __poll_chk(struct pollfd *, nfds_t, int, size_t); +int __poll_real(struct pollfd *, nfds_t, int) __RENAME(poll); +__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count"); + +int __ppoll_chk(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *, size_t); +int __ppoll_real(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *) __RENAME(ppoll); +__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count"); + +#ifdef __BSD_FORTIFY + +__FORTIFY_INLINE int +poll(struct pollfd *_fds, nfds_t _fd_count, int _timeout) +{ + size_t _bos = __bos(_fds); + +#ifdef __clang__ + return (__poll_chk(_fds, _fd_count, _timeout, _bos)); +#else + if (_bos != __FORTIFY_UNKNOWN_SIZE) { + if (!__builtin_constant_p(_fd_count)) + return (__poll_chk(_fds, _fd_count, _timeout, _bos)); + else if (_bos / sizeof(*_fds) < _fd_count) + __poll_too_small_error(); + } + return (__poll_real(_fds, _fd_count, _timeout)); +#endif +} + +#if __BSD_VISIBLE +__FORTIFY_INLINE int +ppoll(struct pollfd *_fds, nfds_t _fd_count, const struct timespec *_timeout, const sigset_t *_mask) +{ + size_t _bos = __bos(_fds); + +#ifdef __clang__ + return (__ppoll_chk(_fds, _fd_count, _timeout, _mask, _bos)); +#else + if (_bos != __FORTIFY_UNKNOWN_SIZE) { + if (!__builtin_constant_p(_fd_count)) + return (__ppoll_chk(_fds, _fd_count, _timeout, _mask, _bos)); + else if (_bos / sizeof(*_fds) < _fd_count) + __ppoll_too_small_error(); + } + return (__ppoll_real(_fds, _fd_count, _timeout, _mask)); +#endif +} +#endif + +#endif + +__END_DECLS + +#endif /* !_SECURE_POLL_H_ */ Index: include/secure/_socket.h =================================================================== --- /dev/null +++ include/secure/_socket.h @@ -0,0 +1,83 @@ +/* + * 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. + * + * bionic rev: a8993c994e45ec2dc00dcef15910560e22d67be9 + * + * $FreeBSD$ + */ + + +#ifndef _SYS_SOCKET_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_SOCKET_H_ +#define _SECURE_SOCKET_H_ + +#include +#include + +__BEGIN_DECLS + +extern ssize_t __recvfrom_chk(int, void *, size_t, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict); +extern ssize_t __recvfrom_real(int, void *, size_t, int, const struct sockaddr *, socklen_t *) __RENAME(recvfrom); +__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer"); + +#ifdef __BSD_FORTIFY + +__FORTIFY_INLINE ssize_t +recvfrom(int _s, void *_buf, size_t _len, int _flags, struct sockaddr * __restrict _from, socklen_t * __restrict _fromlen) +{ + size_t _bos = __bos0(_buf); + +#ifndef __clang__ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__recvfrom_real(_s, _buf, _len, _flags, _from, _fromlen)); + + if (__builtin_constant_p(_len) && (_len <= _bos)) + return (__recvfrom_real(_s, _buf, _len, _flags, _from, _fromlen)); + + if (__builtin_constant_p(_len) && (_len > _bos)) + __recvfrom_error(); +#endif + + return (__recvfrom_chk(_s, _buf, _len, _bos, _flags, _from, _fromlen)); +} + + +__FORTIFY_INLINE ssize_t +recv(int _s, void *_buf, size_t _len, int _flags) +{ + + return recvfrom(_s, _buf, _len, _flags, NULL, 0); +} + +#endif /* !__BSD_FORTIFY */ + +__END_DECLS + +#endif /* !_SECURE_SOCKET_H */ Index: include/secure/_stat.h =================================================================== --- /dev/null +++ include/secure/_stat.h @@ -0,0 +1,70 @@ +/*- + * 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#ifndef _SYS_STAT_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_STAT_H_ +#define _SECURE_STAT_H_ + +#include + +__BEGIN_DECLS + +extern mode_t __umask_chk(mode_t); +#ifndef __FORTIFY_UMASK_REAL +#define __FORTIFY_UMASK_REAL 1 +extern mode_t __umask_real(mode_t) __RENAME(umask); +#endif +__errordecl(__umask_invalid_mode, "umask called with invalid mode"); + +#ifdef __BSD_FORTIFY + +__FORTIFY_INLINE mode_t +umask(mode_t _mode) +{ +#ifndef __clang__ + if (__builtin_constant_p(_mode)) { + if ((_mode & 0777) != _mode) + __umask_invalid_mode(); + + return (__umask_real(_mode)); + } +#endif + return (__umask_chk(_mode)); +} +#endif /* defined(__BSD_FORTIFY) */ + +__END_DECLS + +#endif /* !_SECURE_STAT_H_ */ Index: include/secure/_stdio.h =================================================================== --- /dev/null +++ include/secure/_stdio.h @@ -0,0 +1,240 @@ +/*- + * 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. + * + * @(#)stdio.h 5.17 (Berkeley) 6/3/91 + * $OpenBSD: stdio.h,v 1.35 2006/01/13 18:10:09 miod Exp $ + * $NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $ + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * $FreeBSD$ + */ + +#ifndef _STDIO_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_STDIO_H_ +#define _SECURE_STDIO_H_ + +#include +#include + +__BEGIN_DECLS + +extern char *__fgets_chk(char *, int, FILE *, size_t); +extern char *__fgets_real(char *, int, FILE *) __RENAME(fgets); +__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer"); +__errordecl(__fgets_too_small_error, "fgets called with size less than zero"); +extern size_t __fread_chk(void * __restrict, size_t, size_t, FILE * __restrict, size_t); +extern size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread); +__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer"); +__errordecl(__fread_overflow, "fread called with overflowing size * count"); +extern size_t __fwrite_chk(const void * __restrict, size_t, size_t, FILE * __restrict, size_t); +extern size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite); +__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer"); +__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count"); +extern int __sprintf_chk(char * __restrict, int, size_t, const char * __restrict, ...); +extern int __sprintf_real(char * __restrict, const char * __restrict, ...) __RENAME(sprintf); +extern int __vsprintf_chk(char * __restrict, int, size_t, const char * __restrict, __va_list); +extern int __vsprintf_real(char * __restrict, const char * __restrict, __va_list) __RENAME(vsprintf); + +#if __ISO_C_VISIBLE >= 1999 +extern int __snprintf_chk(char * __restrict, size_t, int, size_t, const char * __restrict, ...); +extern int __snprintf_real(char * __restrict, size_t, const char * __restrict, ...) __RENAME(snprintf) __printflike(3, 4); +extern int __vsnprintf_chk(char * __restrict, size_t, int, size_t, const char * __restrict, __va_list); +extern int __vsnprintf_real(char * __restrict, size_t, const char * __restrict, __va_list) __RENAME(vsnprintf) __printflike(3, 0); +#endif + +#ifdef __BSD_FORTIFY + +#if __ISO_C_VISIBLE >= 1999 +__FORTIFY_INLINE __printflike(3, 0) int +vsnprintf(char *_dest, size_t _size, const char *_format, __va_list _ap) +{ + size_t _bos = __bos(_dest); + +#ifndef __clang__ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__vsnprintf_real(_dest, _size, _format, _ap)); +#endif + + return (__vsnprintf_chk(_dest, _size, 0, _bos, _format, _ap)); +} +#endif /* __ISO_C_VISIBLE */ + +__FORTIFY_INLINE __printflike(2, 0) int +vsprintf(char *_dest, const char *_format, __va_list _ap) +{ + size_t _bos = __bos(_dest); + +#ifndef __clang__ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__vsprintf_real(_dest, _format, _ap)); +#endif + + return (__vsprintf_chk(_dest, 0, _bos, _format, _ap)); +} + + +#if __ISO_C_VISIBLE >= 1999 +#if !__GNUC_PREREQ__(4, 3) && !__has_builtin(__builtin_va_arg_pack) +#if !defined(snprintf) && !defined(__cplusplus) +#define __wrap_snprintf(_dest, _size, ...) __snprintf_chk(_dest, _size, 0, __bos(_dest), __VA_ARGS__) +#define snprintf(...) __wrap_snprintf(__VA_ARGS__) +#endif /* !snprintf */ +#else /* __GNUC_PREREQ__(4, 3) */ +__FORTIFY_INLINE __printflike(3, 4) int +snprintf(char *_dest, size_t _size, const char *_format, ...) +{ + size_t _bos = __bos(_dest); + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__snprintf_real(_dest, _size, _format, + __builtin_va_arg_pack())); + + return (__snprintf_chk(_dest, _size, 0, _bos, _format, + __builtin_va_arg_pack())); +} +#endif /* !__GNUC_PREREQ__(4, 3) */ +#endif /* __ISO_C_VISIBLE */ + +#if !__GNUC_PREREQ__(4, 3) && !__has_builtin(__builtin_va_arg_pack) +#if !defined(sprintf) && !defined(__cplusplus) +#define __wrap_sprintf(_dest, ...) __sprintf_chk(_dest, 0, __bos(_dest), __VA_ARGS__) +#define sprintf(...) __wrap_sprintf(__VA_ARGS__) +#endif /* !sprintf */ +#else /* __GNUC_PREREQ__(4, 3) */ +__FORTIFY_INLINE __printflike(2, 3) int +sprintf(char *_dest, const char *_format, ...) +{ + size_t _bos = __bos(_dest); + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__sprintf_real(_dest, _format, + __builtin_va_arg_pack())); + + return (__sprintf_chk(_dest, 0, _bos, _format, + __builtin_va_arg_pack())); +} + +#endif /* !__GNUC_PREREQ__(4, 3) */ + +__FORTIFY_INLINE char * +fgets(char *_buf, int _n, FILE *_stream) +{ + size_t _bos = __bos(_buf); + +#ifndef __clang__ + /* + * Compiler can prove, at compile time, that the passed in size + * is always negative. + * Force a compiler error. + */ + if (__builtin_constant_p(_n) && (_n < 0)) + __fgets_too_small_error(); + /* + * Compiler doesn 't know destination size. + * Don' t call __fgets_chk. + */ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__fgets_real(_buf, _n, _stream)); + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. + * Don 't call __fgets_chk. + */ + if (__builtin_constant_p(_n) && (_n <= (int)_bos)) + return (__fgets_real(_buf, _n, _stream)); + /* + * Compiler can prove, at compile time, that the passed in size + * is always > the actual object size. + * Force a compiler error. + */ + if (__builtin_constant_p(_n) && (_n > (int)_bos)) + __fgets_too_big_error(); +#endif + return (__fgets_chk(_buf, _n, _stream, _bos)); +} + + +__FORTIFY_INLINE size_t +fread(void * __restrict _ptr, size_t _size, size_t _nmemb, FILE * __restrict _stream) +{ + size_t _bos = __bos0(_ptr); +#ifndef __clang__ + size_t _total; + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__fread_real(_ptr, _size, _nmemb, _stream)); + + if (__builtin_constant_p(_size) && __builtin_constant_p(_nmemb)) { + if (__size_mul_overflow(_size, _nmemb, &_total)) + __fread_overflow(); + + if (_total > _bos) + __fread_too_big_error(); + + return (__fread_real(_ptr, _size, _nmemb, _stream)); + } +#endif + + return (__fread_chk(_ptr, _size, _nmemb, _stream, _bos)); +} + + +__FORTIFY_INLINE size_t +fwrite(const void * __restrict _ptr, size_t _size, size_t _nmemb, FILE * __restrict _stream) +{ + size_t _bos = __bos0(_ptr); +#ifndef __clang__ + size_t _total; + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return __fwrite_real(_ptr, _size, _nmemb, _stream); + + if (__builtin_constant_p(_size) && __builtin_constant_p(_nmemb)) { + if (__size_mul_overflow(_size, _nmemb, &_total)) + __fwrite_overflow(); + + if (_total > _bos) + __fwrite_too_big_error(); + + return (__fwrite_real(_ptr, _size, _nmemb, _stream)); + } +#endif + + return (__fwrite_chk(_ptr, _size, _nmemb, _stream, _bos)); +} + +#endif /* defined(__BSD_FORTIFY) */ + +__END_DECLS + +#endif /* !_SECURE_STDIO_H_ */ Index: include/secure/_string.h =================================================================== --- /dev/null +++ include/secure/_string.h @@ -0,0 +1,448 @@ +/*- + * Copyright (c) 2015 Olivér Pintér + * 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. + * + * bionic rev: 9ef26a3c4cd2e6d469f771815a07cb820800beb6 + * + * $FreeBSD$ + */ + +#ifndef _STRING_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_STRING_H_ +#define _SECURE_STRING_H_ + +#include + +__BEGIN_DECLS + +extern void *__memccpy_chk(void *, const void *, int, size_t, size_t); +extern void *__memccpy_real(void *, const void *, int, size_t) __RENAME(memccpy); +extern void *__memchr_chk(const void *, int, size_t, size_t); +extern void *__memchr_real(const void *, int, size_t) __RENAME(memchr); +extern void *__memcpy_chk(void *, const void *, size_t, size_t); +extern void *__memcpy_real(void *, const void *, size_t) __RENAME(memcpy); +__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); +extern void *__memmove_chk(void *, const void *, size_t, size_t); +extern void *__memmove_real(void *, const void *, size_t) __RENAME(memmove); +extern void *__memrchr_chk(const void *, int, size_t, size_t); +extern void *__memrchr_real(const void *, int, size_t) __RENAME(memrchr); +__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); +extern void *__memset_chk(void *, int, size_t, size_t); +extern void *__memset_real(void *, int, size_t) __RENAME(memset); +extern char *__strcat_chk(char *__restrict, const char *__restrict, size_t); +extern char *__strcat_real(char *__restrict, const char *__restrict) __RENAME(strcat); +extern char *__strncat_chk(char *__restrict, const char *__restrict, size_t, size_t); +extern char *__strncat_real(char *__restrict, const char *__restrict, size_t) __RENAME(strncat); +extern char *__stpcpy_chk(char *, const char *, size_t); +extern char *__stpcpy_real(char *, const char *) __RENAME(stpcpy); +extern char *__stpncpy_chk(char * __restrict, const char * __restrict, size_t, size_t); +extern char *__stpncpy_chk2(char * __restrict, const char * __restrict, size_t, size_t, size_t); +extern char *__stpncpy_real(char * __restrict, const char * __restrict, size_t) __RENAME(stpncpy); +extern char *__strcpy_chk(char *, const char *, size_t); +extern char *__strcpy_real(char *, const char *) __RENAME(strcpy); +extern char *__strncpy_chk(char *, const char *, size_t, size_t); +extern char *__strncpy_chk2(char * __restrict, const char * __restrict, size_t, size_t, size_t); +extern char *__strncpy_real(char *, const char *, size_t) __RENAME(strncpy); +extern size_t __strlcpy_chk(char *, const char *, size_t, size_t); +extern size_t __strlcpy_real(char * __restrict, const char * __restrict, size_t) __RENAME(strlcpy); +extern size_t __strlcat_chk(char * __restrict, const char * __restrict, size_t, size_t); +extern size_t __strlcat_real(char * __restrict, const char * __restrict, size_t) __RENAME(strlcat); +extern size_t __strlen_chk(const char *, size_t); +extern size_t __strlen_real(const char *) __RENAME(strlen); +extern char *__strchr_chk(const char *, int, size_t); +extern char *__strchr_real(const char *, int) __RENAME(strchr); +extern char *__strchrnul_chk(const char *, int, size_t); +extern char *__strchrnul_real(const char *, int) __RENAME(strchrnul); +extern char *__strrchr_chk(const char *, int, size_t); +extern char *__strrchr_real(const char *, int) __RENAME(strrchr); + +#ifdef __BSD_FORTIFY + +#if __XSI_VISIBLE >= 600 +__FORTIFY_INLINE void * +memccpy(void * __restrict _d, const void * __restrict _s, int _c, size_t _n) +{ + size_t _bos = __bos0(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__memccpy_real(_d, _s, _c, _n)); +#endif + + return (__memccpy_chk(_d, _s, _c, _n, _bos)); +} +#endif /* __XSI_VISIBLE */ + + +__FORTIFY_INLINE void * +memchr(const void *_s, int _c, size_t _n) +{ + size_t _bos = __bos(_s); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__memchr_real(_s, _c, _n)); + + if (__builtin_constant_p(_n) && (_n > _bos)) + __memchr_buf_size_error(); + + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __memchr_chk. + */ + if (__builtin_constant_p(_n) && (_n <= _bos)) + return (__memchr_real(_s, _c, _n)); +#endif + + return (__memchr_chk(_s, _c, _n, _bos)); +} + + +#if __BSD_VISIBLE +__FORTIFY_INLINE void * +memrchr(const void *_s, int _c, size_t _n) +{ + size_t _bos = __bos(_s); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__memrchr_real(_s, _c, _n)); + + if (__builtin_constant_p(_n) && (_n > _bos)) + (__memrchr_buf_size_error()); + + if (__builtin_constant_p(_n) && (_n <= _bos)) + return __memrchr_real(_s, _c, _n); +#endif + + return (__memrchr_chk(_s, _c, _n, _bos)); +} +#endif /* __BSD_VISIBLE */ + + +__FORTIFY_INLINE void * +memcpy(void * __restrict _d, const void * __restrict _s, size_t _n) +{ + size_t _bos = __bos0(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__memcpy_real(_d, _s, _n)); +#endif + + return (__memcpy_chk(_d, _s, _n, _bos)); +} + + +__FORTIFY_INLINE void * +memmove(void *_d, const void *_s, size_t _n) +{ + size_t _bos = __bos0(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__memmove_real(_d, _s, _n)); +#endif + + return (__memmove_chk(_d, _s, _n, _bos)); +} + + +#if __POSIX_VISIBLE >= 200809 +__FORTIFY_INLINE char * +stpcpy(char * __restrict _d, const char * __restrict _s) +{ + size_t _bos = __bos(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__stpcpy_real(_d, _s)); +#endif + + return (__stpcpy_chk(_d, _s, _bos)); +} +#endif /* __POSIX_VISIBLE */ + + +__FORTIFY_INLINE char * +strcpy(char * __restrict _d, const char * __restrict _s) +{ + size_t _bos = __bos(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strcpy_real(_d, _s)); +#endif + + return (__strcpy_chk(_d, _s, _bos)); +} + + +#if __POSIX_VISIBLE >= 200809 +__FORTIFY_INLINE char * +stpncpy(char * __restrict _d, const char * __restrict _s, size_t _n) +{ + size_t _d_bos = __bos(_d); + size_t _s_bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + if (_d_bos == __FORTIFY_UNKNOWN_SIZE) + return (__stpncpy_real(_d, _s, _n)); + + if (_s_bos == __FORTIFY_UNKNOWN_SIZE) + return (__stpncpy_chk(_d, _s, _n, _d_bos)); + + if (__builtin_constant_p(_n) && (_n <= _s_bos)) + return (__stpncpy_chk(_d, _s, _n, _d_bos)); + + _slen = __builtin_strlen(_s); + if (__builtin_constant_p(_slen)) + return (__stpncpy_chk(_d, _s, _n, _d_bos)); +#endif + + return (__stpncpy_chk2(_d, _s, _n, _d_bos, _s_bos)); +} +#endif /* __POSIX_VISIBLE */ + + +__FORTIFY_INLINE char * +strncpy(char * __restrict _d, const char * __restrict _s, size_t _n) +{ + size_t _d_bos = __bos(_d); + size_t _s_bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + if (_d_bos == __FORTIFY_UNKNOWN_SIZE) + return (__strncpy_real(_d, _s, _n)); + + if (_s_bos == __FORTIFY_UNKNOWN_SIZE) + return (__strncpy_chk(_d, _s, _n, _d_bos)); + + if (__builtin_constant_p(_n) && (_n <= _s_bos)) + return (__strncpy_chk(_d, _s, _n, _d_bos)); + + _slen = __builtin_strlen(_s); + if (__builtin_constant_p(_slen)) + return (__strncpy_chk(_d, _s, _n, _d_bos)); +#endif + + return (__strncpy_chk2(_d, _s, _n, _d_bos, _s_bos)); +} + + +__FORTIFY_INLINE char * +strcat(char * __restrict _d, const char * __restrict _s) +{ + size_t _bos = __bos(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strcat_real(_d, _s)); +#endif + + return (__strcat_chk(_d, _s, _bos)); +} + + +__FORTIFY_INLINE char * +strncat(char * __restrict _d, const char * __restrict _s, size_t _n) +{ + size_t _bos = __bos(_d); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strncat_real(_d, _s, _n)); +#endif + + return (__strncat_chk(_d, _s, _n, _bos)); +} + + +__FORTIFY_INLINE void * +memset(void *_s, int _c, size_t _n) +{ + size_t _bos = __bos(_s); + +#ifndef __clang__ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__memset_real(_s, _c, _n)); +#endif + + return (__memset_chk(_s, _c, _n, _bos)); +} + + +#if __BSD_VISIBLE +__FORTIFY_INLINE size_t +strlcpy(char * __restrict _d, const char * __restrict _s, size_t _n) +{ + size_t _bos = __bos(_d); + +#ifndef __clang__ + /* Compiler doesn't know destination size. Don't call __strlcpy_chk. */ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strlcpy_real(_d, _s, _n)); + + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __strlcpy_chk. + */ + if (__builtin_constant_p(_n) && (_n <= _bos)) + return (__strlcpy_real(_d, _s, _n)); +#endif + + return (__strlcpy_chk(_d, _s, _n, _bos)); +} +#endif /* __BSD_VISIBLE */ + + +#if __BSD_VISIBLE +__FORTIFY_INLINE size_t +strlcat(char * __restrict _d, const char * __restrict _s, size_t _n) +{ + size_t _bos = __bos(_d); + +#ifndef __clang__ + /* Compiler doesn't know destination size. Don't call __strlcat_chk. */ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strlcat_real(_d, _s, _n)); + + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __strlcat_chk. + */ + if (__builtin_constant_p(_n) && (_n <= _bos)) + return (__strlcat_real(_d, _s, _n)); +#endif + + return (__strlcat_chk(_d, _s, _n, _bos)); +} +#endif /* __BSD_VISIBLE */ + + +__FORTIFY_INLINE size_t +strlen(const char *_s) +{ + size_t _bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + /* Compiler doesn't know destination size. Don't call __strlen_chk. */ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strlen_real(_s)); + + _slen = __builtin_strlen(_s); + if (__builtin_constant_p(_slen)) + return (_slen); +#endif + + return (__strlen_chk(_s, _bos)); +} + +__FORTIFY_INLINE char * +strchr(const char *_s, int _c) +{ + size_t _bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + /* Compiler doesn't know destination size. Don't call __strchr_chk. */ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strchr_real(_s, _c)); + + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __strlchr_chk. + */ + _slen = __builtin_strlen(_s); + if (__builtin_constant_p(_slen) && (_slen < _bos)) + return (__strchr_real(_s, _c)); +#endif + + return (__strchr_chk(_s, _c, _bos)); +} + + +#if __BSD_VISIBLE +__FORTIFY_INLINE char * +strchrnul(const char *_s, int _c) +{ + size_t _bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + /* Compiler doesn't know destination size. Don't call __strchr_chk. */ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strchrnul_real(_s, _c)); + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __strlchrnul_chk. + */ + _slen = __builtin_strlen(_s); + if (__builtin_constant_p(_slen) && (_slen < _bos)) + return (__strchrnul_real(_s, _c)); +#endif + + return (__strchrnul_chk(_s, _c, _bos)); +} +#endif + + +__FORTIFY_INLINE char * +strrchr(const char *_s, int _c) +{ + size_t _bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + /* Compiler doesn't know destination size. Don't call __strrchr_chk. */ + if (__predict_false(_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strrchr_real(_s, _c)); + + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __strlen_chk. + */ + _slen = __strlen_real(_s); + if (__builtin_constant_p(_slen) && (_slen < _bos)) + return (__strrchr_real(_s, _c)); +#endif + + return (__strrchr_chk(_s, _c, _bos)); +} + + +#endif /* defined(__BSD_FORTIFY) */ + +__END_DECLS + +#endif /* !_SECURE_STRING_H */ Index: include/secure/_strings.h =================================================================== --- /dev/null +++ include/secure/_strings.h @@ -0,0 +1,112 @@ +/*- + * Copyright (C) 2015 Olivér Pintér + * 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. + * + * $FreeBSD$ + */ + +#ifndef _STRINGS_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_STRINGS_H_ +#define _SECURE_STRINGS_H_ + +#include + +__BEGIN_DECLS + +extern void *__bcopy_chk(void *, const void *, size_t, size_t) __RENAME(__memmove_chk); +extern void __bcopy_real(const void *, void *, size_t) __RENAME(bcopy); +extern void *__bzero_chk(void *, int, size_t, size_t) __RENAME(__memset_chk); +extern void __bzero_real(void *, size_t) __RENAME(bzero); +extern char *__rindex_chk(const char *, int, size_t); +extern char *__rindex_real(const char *, int) __RENAME(rindex); + +#ifdef __BSD_FORTIFY +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +__FORTIFY_INLINE void +bcopy(const void *_s, void *_d, size_t _l) +{ + size_t _bos = __bos0(_d); + +#ifndef __clang__ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + __bcopy_real(_s, _d, _l); +#endif + + (void)(__bcopy_chk(_d, _s, _l, _bos)); +} +#endif + + +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +__FORTIFY_INLINE void +bzero(void *_s, size_t _n) +{ + size_t _bos = __bos(_s); + +#ifndef __clang__ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + __bzero_real(_s, _n); +#endif + + (void)(__bzero_chk(_s, '\0', _n, _bos)); +} +#endif + + +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +__FORTIFY_INLINE char * +rindex(const char *_s, int _c) +{ + size_t _bos = __bos(_s); +#ifndef __clang__ + size_t _slen; + + /* Compiler doesn't know destination size. Don't call __strrchr_chk. */ + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__rindex_real(_s, _c)); + + /* + * Compiler can prove, at compile time, that the passed in size + * is always <= the actual object size. Don't call __rindex_chk. + */ + _slen = __builtin_strlen(_s); + if (__builtin_constant_p(_slen) && (_slen < _bos)) + return (__rindex_real(_s, _c)); +#endif + + return (__rindex_chk(_s, _c, _bos)); +} +#endif + + +#endif /* !__BSD_FORTIFY */ + +__END_DECLS + +#endif /* !defined(_SECURE_STRINGS_H_) */ Index: include/secure/_unistd.h =================================================================== --- /dev/null +++ include/secure/_unistd.h @@ -0,0 +1,200 @@ +/*- + * Copyright (c) 2015 Olivér Pintér + * 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. + * + * bionic rev: 9ef26a3c4cd2e6d469f771815a07cb820800beb6 + * + * $FreeBSD$ + */ + +#ifndef _UNISTD_H_ +#error "You should not use directly; include instead." +#endif + +#ifndef _SECURE_UNISTD_H_ +#define _SECURE_UNISTD_H_ + +#include +#include + +__BEGIN_DECLS + +extern char *__getcwd_chk(char*, size_t, size_t); +extern char *__getcwd_real(char*, size_t) __RENAME(getcwd); +__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination"); +extern ssize_t __pread_chk(int, void *, size_t, off_t, size_t); +extern ssize_t __pread_real(int, void *, size_t, off_t) __RENAME(pread); +__errordecl(__pread_dest_size_error, "pread called with size bigger than destination"); +__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX"); +extern ssize_t __read_chk(int, void *, size_t, size_t); +extern ssize_t __read_real(int, void *, size_t) __RENAME(read); +__errordecl(__read_dest_size_error, "read called with size bigger than destination"); +__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX"); +extern ssize_t __readlink_chk(const char *, char *, size_t, size_t); +extern ssize_t __readlink_real(const char *, char *, size_t) __RENAME(readlink); +__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination"); +__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX"); +extern ssize_t __readlinkat_chk(int, const char *, char *, size_t, size_t); +extern ssize_t __readlinkat_real(int, const char *, char *, size_t) __RENAME(readlinkat); +__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination"); +__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX"); + +#ifdef __BSD_FORTIFY + +__FORTIFY_INLINE +char * +getcwd(char *_buf, size_t _size) +{ + size_t _bos = __bos(_buf); + +#ifdef __clang__ + /* + * Work around LLVM's incorrect __builtin_object_size implementation + * here to avoid needing the workaround in the __getcwd_chk ABI + * forever. + * + * https://llvm.org/bugs/show_bug.cgi?id=23277 + */ + if (_buf == NULL) + _bos = __FORTIFY_UNKNOWN_SIZE; +#else + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__getcwd_real(_buf, _size)); + if (__builtin_constant_p(_size) && (_size > _bos)) + __getcwd_dest_size_error(); + if (__builtin_constant_p(_size) && (_size <= _bos)) + return (__getcwd_real(_buf, _size)); +#endif + + return (__getcwd_chk(_buf, _size, _bos)); +} + + +/* 1003.1-2008 */ +#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE +__FORTIFY_INLINE ssize_t +pread(int _fd, void *_buf, size_t _count, off_t _offset) +{ + size_t _bos = __bos0(_buf); + +#ifndef __clang__ + if (__builtin_constant_p(_count) && (_count > SSIZE_MAX)) + __pread_count_toobig_error(); + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__pread_real(_fd, _buf, _count, _offset)); + + if (__builtin_constant_p(_count) && (_count > _bos)) + __pread_dest_size_error(); + + if (__builtin_constant_p(_count) && (_count <= _bos)) + return (__pread_real(_fd, _buf, _count, _offset)); +#endif + + return (__pread_chk(_fd, _buf, _count, _offset, _bos)); +} +#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */ + + +__FORTIFY_INLINE ssize_t +read(int _fd, void *_buf, size_t _count) +{ + size_t _bos = __bos0(_buf); + +#ifndef __clang__ + if (__builtin_constant_p(_count) && (_count > SSIZE_MAX)) + __read_count_toobig_error(); + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__read_real(_fd, _buf, _count)); + + if (__builtin_constant_p(_count) && (_count > _bos)) + __read_dest_size_error(); + + if (__builtin_constant_p(_count) && (_count <= _bos)) + return (__read_real(_fd, _buf, _count)); +#endif + + return (__read_chk(_fd, _buf, _count, _bos)); +} + + +/* 1003.1-2001 */ +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +__FORTIFY_INLINE ssize_t +readlink(const char *_path, char *_buf, size_t _size) +{ + size_t _bos = __bos(_buf); + +#ifndef __clang__ + if (__builtin_constant_p(_size) && (_size > SSIZE_MAX)) + __readlink_size_toobig_error(); + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__readlink_real(_path, _buf, _size)); + + if (__builtin_constant_p(_size) && (_size > _bos)) + __readlink_dest_size_error(); + + if (__builtin_constant_p(_size) && (_size <= _bos)) + return (__readlink_real(_path, _buf, _size)); +#endif + + return (__readlink_chk(_path, _buf, _size, _bos)); +} +#endif /* __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE */ + + +#if __POSIX_VISIBLE >= 200809 +__FORTIFY_INLINE ssize_t +readlinkat(int _dirfd, const char *_path, char *_buf, size_t _size) +{ + size_t _bos = __bos(_buf); + +#ifndef __clang__ + if (__builtin_constant_p(_size) && (_size > SSIZE_MAX)) + (__readlinkat_size_toobig_error()); + + if (_bos == __FORTIFY_UNKNOWN_SIZE) + return (__readlinkat_real(_dirfd, _path, _buf, _size)); + + if (__builtin_constant_p(_size) && (_size > _bos)) + __readlinkat_dest_size_error(); + + if (__builtin_constant_p(_size) && (_size <= _bos)) + return (__readlinkat_real(_dirfd, _path, _buf, _size)); +#endif + + return (__readlinkat_chk(_dirfd, _path, _buf, _size, _bos)); +} +#endif /* __POSIX_VISIBLE >= 200809 */ + +#endif /* defined(__BSD_FORTIFY) */ + +__END_DECLS + +#endif /* !_SECURE_UNISTD_H_ */ Index: include/secure/security.h =================================================================== --- /dev/null +++ include/secure/security.h @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2015 Olivér Pintér + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SECURE_SECURITY_ +#define _SECURE_SECURITY_ + +#include +#include + +#ifndef __clang__ +#if __GNUC_PREREQ__(4, 3) +#define __errordecl(name, msg) extern void name(void) __error_attr(msg) +#else +#define __errordecl(name, msg) \ +static void name(void) __dead2; \ +static void name(void) \ +{ \ + \ + __fortify_chk_fail(msg); \ +} +#endif /* __GNUC_PREREQ(4, 3) */ +#else /* !__clang__ */ +#define __errordecl(name, msg) +#endif /* !__clang__ */ + +#define __RENAME(x) __asm__(#x) + +#if __GNUC_PREREQ__(5, 0) || __has_builtin(__builtin_umul_overflow) +#if __LP64__ +#define __size_mul_overflow(a, b, result) __builtin_umull_overflow(a, b, result) +#else +#define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result) +#endif +#else +static __inline __always_inline int +__size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) +{ + static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4); + + *result = a * b; + + return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b; +} +#endif + +static __inline __always_inline int +__fortify_chk_overlap(const char *a, const char *b, size_t len) +{ + + return ((uintptr_t)(a) < (uintptr_t)(b + len) && + (uintptr_t)(a + len) > (uintptr_t)(b)); +} + +__BEGIN_DECLS + +/* Common fail function. */ +void __secure_fail(const char *msg) __dead2 __nonnull(1); + +/* SSP related fail functions. */ +void __chk_fail(void) __dead2; +void __stack_chk_fail(void) __dead2; + +/* FORTIFY_SOURCE related fail function. */ +void __fortify_chk_fail(const char* msg) __dead2 __nonnull(1); + +__END_DECLS + +#endif /* !_SECURE_SECURITY_ */ Index: include/stdio.h =================================================================== --- include/stdio.h +++ include/stdio.h @@ -521,4 +521,9 @@ #endif /* __cplusplus */ __END_DECLS + +#if defined(__BSD_FORTIFY) +#include +#endif + #endif /* !_STDIO_H_ */ Index: include/string.h =================================================================== --- include/string.h +++ include/string.h @@ -141,4 +141,8 @@ #endif __END_DECLS +#if defined(__BSD_FORTIFY) +#include +#endif + #endif /* _STRING_H_ */ Index: include/strings.h =================================================================== --- include/strings.h +++ include/strings.h @@ -68,4 +68,8 @@ #endif __END_DECLS +#if defined(__BSD_FORTIFY) +#include +#endif + #endif /* _STRINGS_H_ */ Index: include/unistd.h =================================================================== --- include/unistd.h +++ include/unistd.h @@ -589,4 +589,8 @@ #endif /* __BSD_VISIBLE */ __END_DECLS +#if defined(__BSD_FORTIFY) +#include +#endif + #endif /* !_UNISTD_H_ */ Index: lib/libc/secure/Makefile.inc =================================================================== --- lib/libc/secure/Makefile.inc +++ lib/libc/secure/Makefile.inc @@ -6,7 +6,47 @@ # Sources common to both syscall interfaces: SRCS+= \ + fortify_source.c \ + secure_common.c \ stack_protector.c \ stack_protector_compat.c +# Sources which contains FORTIFY_SOURCE functions: +SRCS+= \ + __fgets_chk.c \ + __fread_chk.c \ + __fwrite_chk.c \ + __getcwd_chk.c \ + __memccpy_chk.c \ + __memchr_chk.c \ + __memcpy_chk.c \ + __memmove_chk.c \ + __memrchr_chk.c \ + __memset_chk.c \ + __pread_chk.c \ + __read_chk.c \ + __readlink_chk.c \ + __readlinkat_chk.c \ + __stpcpy_chk.c \ + __stpncpy_chk.c \ + __strcat_chk.c \ + __strchr_chk.c \ + __strchrnul_chk.c \ + __strcpy_chk.c \ + __strlcat_chk.c \ + __strlcpy_chk.c \ + __strlen_chk.c \ + __strncat_chk.c \ + __strncpy_chk.c \ + __strrchr_chk.c \ + __vsnprintf_chk.c \ + __vsprintf_chk.c + +# Sources which contains FORTIFY_SOURCE functions, +# but live in .h files under sys/sys +SRCS+= \ + __poll_chk.c \ + __recvfrom_chk.c \ + __umask_chk.c + SYM_MAPS+= ${LIBC_SRCTOP}/secure/Symbol.map Index: lib/libc/secure/Symbol.map =================================================================== --- lib/libc/secure/Symbol.map +++ lib/libc/secure/Symbol.map @@ -7,3 +7,48 @@ __stack_chk_fail; __stack_chk_guard; }; + +FBSD_1.4 { + __fgets_chk; + __fortify_chk_fail; + __fread_chk; + __fwrite_chk; + __getcwd_chk; + __memccpy_chk; + __memchr_chk; + __memcpy_chk; + __memmove_chk; + __memrchr_chk; + __memset_chk; + __poll_chk; + __ppoll_chk; + __pread_chk; + __read_chk; + __readlink_chk; + __readlinkat_chk; + __recvfrom_chk; + __rindex_chk; + __snprintf_chk; + __sprintf_chk; + __stpcpy_chk; + __stpncpy_chk; + __stpncpy_chk2; + __strcat_chk; + __strchr_chk; + __strchrnul_chk; + __strcpy_chk; + __strlcat_chk; + __strlcpy_chk; + __strlen_chk; + __strncat_chk; + __strncpy_chk; + __strncpy_chk2; + __strrchr_chk; + __umask_chk; + __vsnprintf_chk; + __vsprintf_chk; + __secure_fail; +}; + +FBSDprivate_1.0 { +}; Index: lib/libc/secure/__fgets_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__fgets_chk.c @@ -0,0 +1,56 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * + * $FreeBSD$ + */ + + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_stdio.h" + +char * +__fgets_chk(char *buf, int n, FILE *stream, size_t bos) +{ + + if (bos == __FORTIFY_UNKNOWN_SIZE) + return (fgets(buf, n, stream)); + + if (n < 0) + __fortify_chk_fail("fgets: buffer size < 0"); + + if (((size_t)n) > bos) + __fortify_chk_fail("fgets: prevented write past end of buffer"); + + return (fgets(buf, n, stream)); +} Index: lib/libc/secure/__fread_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__fread_chk.c @@ -0,0 +1,56 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: fed2659869ec41a93f655be8058568ddab419e01 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_stdio.h" + +size_t +__fread_chk(void *__restrict ptr, size_t size, size_t nmemb, FILE * __restrict stream, size_t bos) +{ + size_t total; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (fread(ptr, size, nmemb, stream)); + + if (__predict_false(__size_mul_overflow(size, nmemb, &total))) { + //overflow: trigger the error path in fread + return (fread(ptr, size, nmemb, stream)); + } + if (__predict_false(total > bos)) + __fortify_chk_fail("fread: prevented write past end of buffer"); + + return (fread(ptr, size, nmemb, stream)); +} Index: lib/libc/secure/__fwrite_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__fwrite_chk.c @@ -0,0 +1,57 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: fed2659869ec41a93f655be8058568ddab419e01 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_stdio.h" + +size_t +__fwrite_chk(const void * __restrict ptr, size_t size, size_t nmemb, FILE * __restrict stream, size_t bos) +{ + size_t total; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (fwrite(ptr, size, nmemb, stream)); + + if (__predict_false(__size_mul_overflow(size, nmemb, &total))) { + // overflow: trigger the error path in fwrite + return (fwrite(ptr, size, nmemb, stream)); + } + + if (__predict_false(total > bos)) + __fortify_chk_fail("fwrite: prevented read past end of buffer"); + + return (fwrite(ptr, size, nmemb, stream)); +} Index: lib/libc/secure/__getcwd_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__getcwd_chk.c @@ -0,0 +1,51 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: 7e919daeaad62515ebbbf7b06badc77625a14d90 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_unistd.h" + +char * +__getcwd_chk(char* buf, size_t size, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (getcwd(buf, size)); + + if (__predict_false(size > bos)) + __fortify_chk_fail("getcwd: prevented write past end of buffer"); + + return (getcwd(buf, size)); +} Index: lib/libc/secure/__memccpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__memccpy_chk.c @@ -0,0 +1,75 @@ +/*- + * Copyright (C) 2015 Oliver Pinter + * 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. + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +void * +__memccpy_chk(void *dest, const void *src, int c, size_t n, size_t bos) +{ + void *ret; + size_t len; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (memccpy(dest, src, c, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("memccpy: prevented write past end of buffer"); + + /* + * If n was copied, then return NULL, otherwise + * a pointer to the byte after the copy of c in the string + * dest is returned. + * + * See the memccpy(3) manpage for more details. + */ + ret = memccpy(dest, src, c, n); + if (ret != NULL) + len = ret - dest; + else + len = n; + + /* + * The Open Group Base Specifications Issue 7 + * IEEE Std 1003.1, 2013 Edition: + * Overlapping is undefined, check, prevent and inform the + * users about them. + * http://pubs.opengroup.org/onlinepubs/9699919799//functions/memccpy.html + */ + if (__predict_false(__fortify_chk_overlap(dest, src, len))) + __fortify_chk_fail("memccpy: overlapping strings detected"); + + return (ret); +} Index: lib/libc/secure/__memchr_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__memchr_chk.c @@ -0,0 +1,52 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_string.h" + +void * +__memchr_chk(const void *s, int c, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (memchr(s, c, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail( + "memchr: prevented read past end of buffer"); + + return (memchr(s, c, n)); +} Index: lib/libc/secure/__memcpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__memcpy_chk.c @@ -0,0 +1,57 @@ +/*- + * Copyright (C) 2015 Oliver Pinter + * Copyright (C) 2012 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. + * + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +void * +__memcpy_chk(void *d, const void *s, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (memcpy(d, s, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("memcpy: prevented write past end of buffer"); + + /* See the memcpy(3) for more details. */ + if (__predict_false(__fortify_chk_overlap(d, s, n))) + __fortify_chk_fail("memcpy: prevented overlaping strings"); + + return (memcpy(d, s, n)); +} Index: lib/libc/secure/__memmove_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__memmove_chk.c @@ -0,0 +1,56 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +void * +__memmove_chk(void *d, const void *s, size_t n, size_t bos) +{ + + /* + * Compiler doesn 't know dination size. + * Fallback to the original function. + */ + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (memmove(d, s, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("memmove: prevented write past end of buffer"); + + return (memmove(d, s, n)); +} Index: lib/libc/secure/__memrchr_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__memrchr_chk.c @@ -0,0 +1,51 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_string.h" + +void * +__memrchr_chk(const void *s, int c, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (memrchr(s, c, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("memrchr: prevented read past end of buffer"); + + return (memrchr(s, c, n)); +} Index: lib/libc/secure/__memset_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__memset_chk.c @@ -0,0 +1,52 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: 6cc98af72b0c48c58b2ab5fdb5f7abb842175299 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +void * +__memset_chk(void *d, int c, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return memset(d, c, n); + + if (__predict_false(n > bos)) + __fortify_chk_fail("memset: prevented write past end of buffer"); + + return memset(d, c, n); +} Index: lib/libc/secure/__poll_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__poll_chk.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 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. + * + * bionic rev: eeb9f5e41662828989f3913d81ec23229a668434 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_poll.h" + +int +__poll_chk(struct pollfd *fds, nfds_t fd_count, int timeout, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (poll(fds, fd_count, timeout)); + + if (__predict_false(bos / sizeof(*fds) < fd_count)) + __fortify_chk_fail("poll: pollfd array smaller than fd count"); + + return (poll(fds, fd_count, timeout)); +} + +int +__ppoll_chk(struct pollfd *fds, nfds_t fd_count, const struct timespec *timeout, const sigset_t *mask, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (ppoll(fds, fd_count, timeout, mask)); + + if (__predict_false(bos / sizeof(*fds) < fd_count)) + __fortify_chk_fail("ppoll: pollfd array smaller than fd count"); + + return (ppoll(fds, fd_count, timeout, mask)); +} Index: lib/libc/secure/__pread_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__pread_chk.c @@ -0,0 +1,55 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: a8993c994e45ec2dc00dcef15910560e22d67be9 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_unistd.h" + +ssize_t +__pread_chk(int fd, void *buf, size_t count, off_t offset, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (pread(fd, buf, count, offset)); + + if (__predict_false(count > bos)) + __fortify_chk_fail("pread: prevented write past end of buffer"); + + if (__predict_false(count > SSIZE_MAX)) + __fortify_chk_fail("pread: count > SSIZE_MAX"); + + return (pread(fd, buf, count, offset)); +} Index: lib/libc/secure/__read_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__read_chk.c @@ -0,0 +1,55 @@ +/*- + * Copyright (C) 2013 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. + * + * rev: a8993c994e45ec2dc00dcef15910560e22d67be9 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_unistd.h" + +ssize_t +__read_chk(int fd, void *buf, size_t count, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (read(fd, buf, count)); + + if (__predict_false(count > bos)) + __fortify_chk_fail("read: prevented write past end of buffer"); + + if (__predict_false(count > SSIZE_MAX)) + __fortify_chk_fail("read: count > SSIZE_MAX"); + + return (read(fd, buf, count)); +} Index: lib/libc/secure/__readlink_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__readlink_chk.c @@ -0,0 +1,55 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: a8993c994e45ec2dc00dcef15910560e22d67be9 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_unistd.h" + +ssize_t +__readlink_chk(const char *path, char *buf, size_t size, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (readlink(path, buf, size)); + + if (__predict_false(size > bos)) + __fortify_chk_fail("readlink: prevented write past end of buffer"); + + if (__predict_false(size > SSIZE_MAX)) + __fortify_chk_fail("readlink: size > SSIZE_MAX"); + + return (readlink(path, buf, size)); +} Index: lib/libc/secure/__readlinkat_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__readlinkat_chk.c @@ -0,0 +1,55 @@ +/*- + * Copyright (C) 2015 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. + * + * bionic rev: a8993c994e45ec2dc00dcef15910560e22d67be9 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_unistd.h" + +ssize_t +__readlinkat_chk(int dirfd, const char *path, char *buf, size_t size, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (readlinkat(dirfd, path, buf, size)); + + if (__predict_false(size > bos)) + __fortify_chk_fail("readlinkat: prevented write past end of buffer"); + + if (__predict_false(size > SSIZE_MAX)) + __fortify_chk_fail("readlinkat: size > SSIZE_MAX"); + + return (readlinkat(dirfd, path, buf, size)); +} Index: lib/libc/secure/__recvfrom_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__recvfrom_chk.c @@ -0,0 +1,53 @@ +/*- + * Copyright (C) 2013 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. + * + * bionic rev: a8993c994e45ec2dc00dcef15910560e22d67be9 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_socket.h" + +ssize_t +__recvfrom_chk(int s, void *buf, size_t len, size_t bos, + int flags, struct sockaddr * __restrict from, + socklen_t * __restrict fromlen) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (recvfrom(s, buf, len, flags, from, fromlen)); + + if (__predict_false(len > bos)) + __fortify_chk_fail("recvfrom: prevented write past end of buffer"); + + return (recvfrom(s, buf, len, flags, from, fromlen)); +} Index: lib/libc/secure/__stpcpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__stpcpy_chk.c @@ -0,0 +1,59 @@ +/*- + * Copyright (C) 2014 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +char * +__stpcpy_chk(char *dest, const char *src, size_t bos) +{ + /* TODO:optimize so we don't scan src twice. */ + size_t src_len; + + /* + * Compiler doesn 't know destination size. + * Fallback to the original function. + */ + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (stpcpy(dest, src)); + + src_len = strlen(src) + 1; + if (__predict_false(src_len > bos)) + __fortify_chk_fail("stpcpy: prevented write past end of buffer"); + + return (stpcpy(dest, src)); +} Index: lib/libc/secure/__stpncpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__stpncpy_chk.c @@ -0,0 +1,97 @@ +/*- + * Copyright (C) 2014 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +char * +__stpncpy_chk(char *__restrict d, const char *__restrict s, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (stpncpy(d, s, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("stpncpy: prevented write past end of buffer"); + + return stpncpy(d, s, n); +} + +/* + * __stpncpy_chk2 + * + * This is a variant of __stpncpy_chk, but it also checks to make + * sure we don't read beyond the end of "s". The code for this is + * based on the original version of stpncpy, but modified to check + * how much we read from "s" at the end of the copy operation. + */ +char * +__stpncpy_chk2(char *__restrict d, const char *__restrict s, size_t n, size_t d_bos, size_t s_bos) +{ + char *_d; + const char *_s = s; + size_t s_copy_len ; + + if (__predict_false(d_bos == __FORTIFY_UNKNOWN_SIZE)) + return (stpncpy(d, s, n)); + + if (__predict_false(s_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__stpncpy_chk(d, s, n, d_bos)); + + if (__predict_false(n > d_bos)) + __fortify_chk_fail("stpncpy: prevented write past end of buffer"); + + if (n != 0) { + _d = d; + + do { + if ((*_d++ = *_s++) == 0) { + /* NUL pad the remaining n-1 bytes */ + while (--n != 0) + *_d++ = 0; + break; + } + } while (--n != 0); + + s_copy_len = (size_t)(_s - s); + + if (__predict_false(s_copy_len > s_bos)) + __fortify_chk_fail("stpncpy: prevented read past end of buffer"); + } + + return (d); +} Index: lib/libc/secure/__strcat_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strcat_chk.c @@ -0,0 +1,66 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +char * +__strcat_chk(char *__restrict d, const char *__restrict s, size_t bos) +{ + char *save = d; + size_t d_len; + + /* + * Compiler doesn 't know destination size. + * Fallback to the original function. + */ + if (bos == __FORTIFY_UNKNOWN_SIZE) + return (strcat(d, s)); + + d_len = __strlen_chk(d, bos); + + d += d_len; + bos -= d_len; + + while ((*d++ = *s++) != '\0') { + bos--; + if (__predict_false(bos == 0)) + __fortify_chk_fail("strcat: prevented write past end of buffer"); + } + + return (save); +} Index: lib/libc/secure/__strchr_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strchr_chk.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 1990 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_string.h" + +char * +__strchr_chk(const char *p, int ch, size_t bos) +{ + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strchr(p, ch)); + + for (;; ++p, bos--) { + if (__predict_false(bos == 0)) + __fortify_chk_fail("strchr: prevented read past end of buffer"); + if (*p == (char)(ch)) + return ((char *)(p)); + if (*p == '\0') + return (NULL); + } + /* NOTREACHED */ +} Index: lib/libc/secure/__strchrnul_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strchrnul_chk.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2015 Pinter Oliver + * Copyright (c) 1990 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_string.h" + +char * +__strchrnul_chk(const char *p, int ch, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strchrnul(p, ch)); + + for (;; ++p, bos--) { + if (__predict_false(bos == 0)) + __fortify_chk_fail( + "strchrnul: prevented read past end of buffer"); + if (*p == (char)(ch)) + return ((char *)(p)); + if (*p == '\0') + return ((char *)(p)); + } + /* NOTREACHED */ +} Index: lib/libc/secure/__strcpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strcpy_chk.c @@ -0,0 +1,59 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +char * +__strcpy_chk(char *d, const char *s, size_t bos) +{ + /* TODO: optimize so we don't scan s twice. */ + size_t s_len; + + /* + * Compiler doesn 't know destination size. + * Fallback to the original function. + */ + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strcpy(d, s)); + + s_len = strlen(s) + 1; + if (__predict_false(s_len > bos)) + __fortify_chk_fail("strcpy: prevented write past end of buffer"); + + return (strcpy(d, s)); +} Index: lib/libc/secure/__strlcat_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strlcat_chk.c @@ -0,0 +1,52 @@ +/*- + * Copyright (C) 2012 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. + * + * rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +size_t +__strlcat_chk(char *d, const char *s, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strlcat(d, s, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("strlcat: prevented write past end of buffer"); + + return (strlcat(d, s, n)); +} Index: lib/libc/secure/__strlcpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strlcpy_chk.c @@ -0,0 +1,52 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +size_t +__strlcpy_chk(char *d, const char *s, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strlcpy(d, s, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail("strlcpy: prevented write past end of buffer"); + + return (strlcpy(d, s, n)); +} Index: lib/libc/secure/__strlen_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strlen_chk.c @@ -0,0 +1,67 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +/* + * This test is designed to detect code such as: + * + * int main() { + * char buf[10]; + * memcpy(buf, "1234567890", sizeof(buf)); + * size_t len = strlen(buf); // segfault here with _FORTIFY_SOURCE + * printf("%d\n", len); + * return 0; + * } + * + * or anytime strlen reads beyond an object boundary. + */ +size_t +__strlen_chk(const char *s, size_t bos) +{ + size_t ret; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strlen(s)); + + ret = strlen(s); + if (__predict_false(ret >= bos)) + __fortify_chk_fail("strlen: detected read past end of buffer"); + + return (ret); +} Index: lib/libc/secure/__strncat_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strncat_chk.c @@ -0,0 +1,70 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +char * +__strncat_chk(char *__restrict d, const char *__restrict s, size_t n, size_t bos) +{ + size_t d_len; + char *_d; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strncat(d, s, n)); + + if (n == 0) + return (d); + + d_len = __strlen_chk(d, bos); + _d = d + d_len; + bos -= d_len; + + while (*s != '\0') { + *_d++ = *s++; + n--; + bos--; + + if (__predict_false(bos == 0)) + __fortify_chk_fail("strncat: prevented write past end of buffer"); + if (n == 0) + break; + } + *_d = '\0'; + + return (d); +} Index: lib/libc/secure/__strncpy_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strncpy_chk.c @@ -0,0 +1,97 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include "secure/_string.h" + +char * +__strncpy_chk(char *__restrict d, const char *__restrict s, size_t n, size_t bos) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strncpy(d, s, n)); + + if (__predict_false(n > bos)) + __fortify_chk_fail( + "strncpy: prevented write past end of buffer"); + + return (strncpy(d, s, n)); +} + +/* + * __strncpy_chk2 + * + * This is a variant of __strncpy_chk, but it also checks to make + * sure we don't read beyond the end of "src". The code for this is + * based on the original version of strncpy, but modified to check + * how much we read from "src" at the end of the copy operation. + */ +char * +__strncpy_chk2(char *__restrict d, const char *__restrict s, size_t n, size_t d_bos, size_t s_bos) +{ + size_t s_copy_len; + + if (__predict_false(d_bos == __FORTIFY_UNKNOWN_SIZE)) + return (strncpy(d, s, n)); + + if (__predict_false(s_bos == __FORTIFY_UNKNOWN_SIZE)) + return (__strncpy_chk(d, s, n, d_bos)); + + if (__predict_false(n > d_bos)) + __fortify_chk_fail("strncpy: prevented write past end of buffer"); + + if (n != 0) { + char *_d = d; + const char *_s = s; + + do { + if ((*_d++ = *_s++) == 0) { + /* NUL pad the remaining n-1 bytes */ + while (--n != 0) + *_d++ = 0; + break; + } + } while (--n != 0); + + s_copy_len = (size_t)(_s - s); + + if (__predict_false(s_copy_len > s_bos)) + __fortify_chk_fail("strncpy: prevented read past end of buffer"); + } + + return (d); +} Index: lib/libc/secure/__strrchr_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__strrchr_chk.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1988 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include "secure/_string.h" + +char * +__strrchr_chk(const char *p, int ch, size_t bos) +{ + char *save; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (strrchr(p, ch)); + + for (save = NULL;; ++p, bos--) { + if (bos == 0) + __fortify_chk_fail( + "strrchr: prevented read past end of buffer"); + if (*p == (char)ch) + save = (char *)p; + if (!*p) + return (save); + } + /* NOTREACHED */ +} + +__weak_reference(__strrchr_chk, __rindex_chk); + Index: lib/libc/secure/__umask_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__umask_chk.c @@ -0,0 +1,53 @@ +/*- + * Copyright (C) 2012 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. + * + * rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include +#include "secure/_stat.h" + +/* + * Validate that umask is called with sane mode. + */ +mode_t +__umask_chk(mode_t mode) +{ + + if (__predict_false((mode & 0777) != mode)) + __fortify_chk_fail("umask: called with invalid mask"); + + return (umask(mode)); +} Index: lib/libc/secure/__vsnprintf_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__vsnprintf_chk.c @@ -0,0 +1,76 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include +#include "secure/_stdio.h" + +int +__vsnprintf_chk(char *d, size_t n, int flags, size_t bos, const char *fmt, va_list va) +{ + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (vsnprintf(d, n, fmt, va)); + + if (__predict_false(n > bos)) + __fortify_chk_fail( + "vsnprintf: prevented write past end of buffer"); + + return (vsnprintf(d, n, fmt, va)); +} + + +int +__snprintf_chk(char *d, size_t n, int flags, size_t bos, const char *fmt, ...) +{ + va_list va; + int result; + + if (bos == __FORTIFY_UNKNOWN_SIZE) { + va_start(va, fmt); + result = vsnprintf(d, n, fmt, va); + va_end(va); + + return (result); + } + + va_start(va, fmt); + result = __vsnprintf_chk(d, n, flags, bos, fmt, va); + va_end(va); + + return (result); +} Index: lib/libc/secure/__vsprintf_chk.c =================================================================== --- /dev/null +++ lib/libc/secure/__vsprintf_chk.c @@ -0,0 +1,78 @@ +/*- + * Copyright (C) 2012 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. + * + * bionic rev: d807b9a12d3e49132b095df3d883618452033b51 + * + * $FreeBSD$ + */ + +#undef _FORTIFY_SOURCE + +#include +#include +#include +#include +#include +#include "secure/_stdio.h" + +int +__vsprintf_chk(char * __restrict d, int flags, size_t bos, const char * __restrict fmt, __va_list va) +{ + int result; + + if (__predict_false(bos == __FORTIFY_UNKNOWN_SIZE)) + return (vsprintf(d, fmt, va)); + + result = vsnprintf(d, bos, fmt, va); + if ((size_t)result >= bos) + __fortify_chk_fail( + "vsprintf: prevented write past end of buffer"); + + return (result); +} + + +int +__sprintf_chk(char * __restrict d, int flags, size_t bos, const char * __restrict fmt, ...) +{ + va_list va; + int result; + + if (bos == __FORTIFY_UNKNOWN_SIZE) { + va_start(va, fmt); + result = vsprintf(d, fmt, va); + va_end(va); + + return (result); + } + + va_start(va, fmt); + result = __vsprintf_chk(d, flags, bos, fmt, va); + va_end(va); + + return (result); +} Index: lib/libc/secure/fortify_source.c =================================================================== --- /dev/null +++ lib/libc/secure/fortify_source.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2015 Olivér Pintér + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include "secure/security.h" + +void +__fortify_chk_fail(const char* msg) +{ + + __secure_fail(msg); +} + Index: lib/libc/secure/secure_common.c =================================================================== --- /dev/null +++ lib/libc/secure/secure_common.c @@ -0,0 +1,80 @@ +/* $NetBSD: stack_protector.c,v 1.4 2006/11/22 17:23:25 christos Exp $ */ +/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */ +/* + * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. + * + */ + +#undef _FORTIFY_SOURCE + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" + +static void __fail(const char *) __dead2; + +/*ARGSUSED*/ +static void +__fail(const char *msg) +{ + struct sigaction sa; + sigset_t mask; + + /* Immediately block all signal handlers from running code */ + (void)sigfillset(&mask); + (void)sigdelset(&mask, SIGABRT); + (void)_sigprocmask(SIG_BLOCK, &mask, NULL); + + /* This may fail on a chroot jail... */ + syslog(LOG_CRIT, "%s", msg); + + (void)memset(&sa, 0, sizeof(sa)); + (void)sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + (void)sigaction(SIGABRT, &sa, NULL); + (void)kill(getpid(), SIGABRT); + _exit(127); +} + +void +__secure_fail(const char *msg) +{ + + __fail(msg); +} Index: lib/libc/secure/stack_protector.c =================================================================== --- lib/libc/secure/stack_protector.c +++ lib/libc/secure/stack_protector.c @@ -33,12 +33,8 @@ #include #include #include -#include +#include #include -#include -#include -#include -#include #include "libc_private.h" extern int __sysctl(const int *name, u_int namelen, void *oldp, @@ -46,9 +42,7 @@ long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; static void __guard_setup(void) __attribute__((__constructor__, __used__)); -static void __fail(const char *); -void __stack_chk_fail(void); -void __chk_fail(void); +void __stack_chk_fail(void) __dead2; /*LINTED used*/ static void @@ -76,40 +70,18 @@ } } -/*ARGSUSED*/ -static void -__fail(const char *msg) -{ - struct sigaction sa; - sigset_t mask; - - /* Immediately block all signal handlers from running code */ - (void)sigfillset(&mask); - (void)sigdelset(&mask, SIGABRT); - (void)sigprocmask(SIG_BLOCK, &mask, NULL); - - /* This may fail on a chroot jail... */ - syslog(LOG_CRIT, "%s", msg); - - (void)memset(&sa, 0, sizeof(sa)); - (void)sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - (void)sigaction(SIGABRT, &sa, NULL); - (void)kill(getpid(), SIGABRT); - _exit(127); -} - void __stack_chk_fail(void) { - __fail("stack overflow detected; terminated"); + + __secure_fail("stack overflow detected; terminated"); } void __chk_fail(void) { - __fail("buffer overflow detected; terminated"); + + __secure_fail("buffer overflow detected; terminated"); } #ifndef PIC Index: share/man/man7/Makefile =================================================================== --- share/man/man7/Makefile +++ share/man/man7/Makefile @@ -15,6 +15,7 @@ environ.7 \ ffs.7 \ firewall.7 \ + fortify_source.7 \ growfs.7 \ hier.7 \ hostname.7 \ @@ -39,6 +40,43 @@ MLINKS+= c99.7 c89.7 MLINKS+= c99.7 c90.7 +MLINKS+= fortify_source.7 __poll_chk.2 +MLINKS+= fortify_source.7 __ppoll_chk.2 +MLINKS+= fortify_source.7 __pread_chk.2 +MLINKS+= fortify_source.7 __read_chk.2 +MLINKS+= fortify_source.7 __readlink_chk.2 +MLINKS+= fortify_source.7 __readlinkat_chk.2 +MLINKS+= fortify_source.7 __recfrom_chk.2 +MLINKS+= fortify_source.7 __umask_chk.2 +MLINKS+= fortify_source.7 __bcopy_chk.3 +MLINKS+= fortify_source.7 __bzero_chk.3 +MLINKS+= fortify_source.7 __fgets_chk.3 +MLINKS+= fortify_source.7 __fread_chk.3 +MLINKS+= fortify_source.7 __fwrite_chk.3 +MLINKS+= fortify_source.7 __getcwd_chk.3 +MLINKS+= fortify_source.7 __memccpy_chk.3 +MLINKS+= fortify_source.7 __memcpy_chk.3 +MLINKS+= fortify_source.7 __memmove_chk.3 +MLINKS+= fortify_source.7 __memrchr_chk.3 +MLINKS+= fortify_source.7 __memset_chk.3 +MLINKS+= fortify_source.7 __rindex_chk.3 +MLINKS+= fortify_source.7 __snprintf_chk.3 +MLINKS+= fortify_source.7 __sprintf_chk.3 +MLINKS+= fortify_source.7 __stpcpy_chk.3 +MLINKS+= fortify_source.7 __stpncpy_chk.3 +MLINKS+= fortify_source.7 __strcat_chk.3 +MLINKS+= fortify_source.7 __strchr_chk.3 +MLINKS+= fortify_source.7 __strchrnul_chk.3 +MLINKS+= fortify_source.7 __strcpy_chk.3 +MLINKS+= fortify_source.7 __strlcat_chk.3 +MLINKS+= fortify_source.7 __strlcpy_chk.3 +MLINKS+= fortify_source.7 __strlen_chk.3 +MLINKS+= fortify_source.7 __strncat_chk.3 +MLINKS+= fortify_source.7 __strncpy_chk.3 +MLINKS+= fortify_source.7 __strrchr_chk.3 +MLINKS+= fortify_source.7 __vsnprintf_chk.3 +MLINKS+= fortify_source.7 __vsprintf_chk.3 + .if ${MK_TESTS} != "no" ATF= ${.CURDIR}/../../../contrib/atf .PATH: ${ATF}/doc Index: share/man/man7/fortify_source.7 =================================================================== --- /dev/null +++ share/man/man7/fortify_source.7 @@ -0,0 +1,138 @@ +.\" Copyright (C) 2015 Pedro Giffuni. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD$ +.\" +.Dd August 26, 2015 +.Dt FORTIFY_SOURCE 7 +.Os +.Sh NAME +.Nm FORTIFY_SOURCE +.Nd libc bounds-checking functionality +.Sh SYNOPSIS +.Pp +.Nm cc +.Fl D Ns _FORTIFY_SOURCE=level ... +.Pp +.Sh DESCRIPTION +Defining +.Li _FORTIFY_SOURCE +in the +.Xr cc 1 +compiler flags enables a set of replacement functions for common string and +memory manipulation routines capable of detecting simple buffer overflows. +The functionality is the result of deep integration between the main C library +and the compiler itself. +.Pp +The concept builds on the observation that there are many cases where the +compiler can determine the size of a buffer. +Buffer overflows detected at compile time are reported by the compiler. +Otherwise, the checks are performed at runtime and produce an error message. +.Pp +.Sh OPTIONS +.Ss Fortify Level +.Nm level +Setting the level to 0 disables FORTIFY_SOURCE. +Levels higher than 1 add more checks, depending on the implementation, but might +cause false positives. +.Pp +.Sh IMPLEMENTATION NOTES +The implementation uses the standard headers to provide inlined replacements. +Any standard function that is not declared in the code through the standard +headers will therefore remain unprotected. +Similarly, functions overflowing in a different compilation unit may remain +unprotected. +.Pp +Headers for the bounds-checking functions cannot be imported directly through any public header. +The replacement bounds-checking functions are meant to be transparent to the developer and were never meant to be called directly. +Checker functions are visible only when debugging or when reporting an +overflow and are easily identified as they end with a +.Em _chk +suffix. +.Pp +Object size information is usually available to the compiler only in +optimization mode. +Disabling optimizations also involves disabling FORTIFY_SOURCE. +.Pp +Support for +.Xr clang 1 +and other compilers that have only a partial implementation of +.Tn GNU +extensions is somewhat limited. +In particular, compile time checks may not work and level 2, or higher, +checks may fall back to level 1. +.Pp +.Sh SEE ALSO +.Xr cc 1 , +.Xr poll 2 , +.Xr ppoll 2 , +.Xr pread 2 , +.Xr read 2 , +.Xr readlink 2 , +.Xr readlinkat 2 , +.Xr recfrom 2 , +.Xr umask 2 , +.Xr bcopy 3 , +.Xr bzero 3 , +.Xr fgets 3 , +.Xr fread 3 , +.Xr fwrite 3 , +.Xr getcwd 3 , +.Xr memccpy 3 , +.Xr memcpy 3 , +.Xr memmove 3 , +.Xr memrchr 3 , +.Xr memset 3 , +.Xr rindex 3 , +.Xr snprintf 3 , +.Xr sprintf 3 , +.Xr stpcpy 3 , +.Xr stpncpy 3 , +.Xr strcat 3 , +.Xr strchr 3 , +.Xr strchrnul 3 , +.Xr strcpy 3 , +.Xr strlcat 3 , +.Xr strlcpy 3 , +.Xr strlen 3 , +.Xr strncat 3 , +.Xr strncpy 3 , +.Xr strrchr 3 , +.Xr vsnprintf 3 , +.Xr vsprintf 3 +.Sh HISTORY +Support for FORTIFY_SOURCE is a +.Tn GNU +C extension. +.Pp +The current implementation was developed by +.An Oliver Pinter +with help from +.An Pedro Giffuni +based on similar implementations from +.Nx +and Bionic libc. +.Pp +.Nm FORTIFY_SOURCE +was introduced in +.Fx 11.0. Index: share/man/man7/security.7 =================================================================== --- share/man/man7/security.7 +++ share/man/man7/security.7 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 25, 2013 +.Dd August 25, 2015 .Dt SECURITY 7 .Os .Sh NAME @@ -951,6 +951,7 @@ .Xr xdm 1 Pq Pa ports/x11/xorg-clients , .Xr group 5 , .Xr ttys 5 , +.Xr fortify_source 7, .Xr accton 8 , .Xr init 8 , .Xr sshd 8 , Index: sys/sys/cdefs.h =================================================================== --- sys/sys/cdefs.h +++ sys/sys/cdefs.h @@ -529,6 +529,30 @@ #endif /* + * Defining _FORTIFY_SOURCE will enable replacement bounds checking + * functions. This is heavily dependent on GCC extenions for + * object sizes and is only partially supported by clang. + */ +#if __GNUC_PREREQ__(4, 1) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && \ + defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(lint) +#define __BSD_FORTIFY 1 +#if _FORTIFY_SOURCE >= 2 +#define __bos(s) __builtin_object_size((s), 1) +#else +#define __bos(s) __builtin_object_size((s), 0) +#endif +#define __bos0(s) __builtin_object_size((s), 0) +#define __FORTIFY_INLINE extern __inline __always_inline __gnu_inline +#endif /* !_FORTIFY_SOURCE */ +#define __FORTIFY_UNKNOWN_SIZE ((size_t) -1) + +#if __GNUC_PREREQ__(4, 3) || __has_attribute(__error__) +#define __error_attr(msg) __attribute__((__error__(msg))) +#else +#define __error_attr(msg) +#endif + +/* * FORTIFY_SOURCE, and perhaps other compiler-specific features, require * the use of non-standard inlining. In general we should try to avoid * using these but GCC-compatible compilers tend to support the extensions Index: sys/sys/poll.h =================================================================== --- sys/sys/poll.h +++ sys/sys/poll.h @@ -117,6 +117,10 @@ #endif __END_DECLS +#ifdef __BSD_FORTIFY +#include +#endif + #endif /* !_KERNEL */ #endif /* !_SYS_POLL_H_ */ Index: sys/sys/socket.h =================================================================== --- sys/sys/socket.h +++ sys/sys/socket.h @@ -630,6 +630,10 @@ int socketpair(int, int, int, int *); __END_DECLS +#ifdef __BSD_FORTIFY +#include +#endif + #endif /* !_KERNEL */ #ifdef _KERNEL Index: sys/sys/stat.h =================================================================== --- sys/sys/stat.h +++ sys/sys/stat.h @@ -356,6 +356,11 @@ int mknodat(int, const char *, mode_t, dev_t); #endif __END_DECLS + +#ifdef __BSD_FORTIFY +#include +#endif + #endif /* !_KERNEL */ #endif /* !_SYS_STAT_H_ */