Compare commits

...

40 Commits
0.3 ... master

Author SHA1 Message Date
sin
e3fee64643 Bump to 1.1 2019-04-14 09:25:54 +01:00
info@mobile-stream.com
9e65ae387c getgroups: do not trap on non-positive gidsetsize
First, we should never check the size of __s if __l == 0 since the
array is not going to be modified in that case.

Second, negative __l is a well-defined error case (EINVAL) and we
should never trap on a conforming code like this:

r = getgroups(-1, NULL);
if (r == -1)
  ...

An example of non-desired behaviour for negative __l is the gnulib
configure script which checks for getgroups(-1, ...) to catch some
ancient FreeBSD kernel bug. The conftest binary traps even on good
system (e.g. linux/musl) and the unnecessary getgroups wrapper is
enforced for any project that uses gnulib.

This patch also changes the size_t cast to avoid the explicit zero
extension on systems where size_t differs from unsigned int.
2019-03-13 17:47:50 +00:00
info@mobile-stream.com
9b796691eb wctomb, wcrtomb: guard slow/trap path with MB_LEN_MAX
This allows the compiler to optimize out the slow/trap path at all
for the typical correct code:

char buf[MB_LEN_MAX];
r = wctomb(buf, c);

The change tries to keep the "unknown object size" case handling in
wcrtomb() as is even if it seems redundant and not helping (we copy
__buf to possibly undersized __s in any case) and inconsistent with
wctomb() (where we let the original library method itself overwrite
the possibly undersized __s).
2019-03-07 00:05:34 +00:00
info@mobile-stream.com
ff82ffbc74 realpath: guard slow/trap path with PATH_MAX
This allows the compiler to optimize out the slow/trap path at all
for the typical correct code:

char buf[PATH_MAX];
r = realpath(path, buf);

The change keeps the "unknown object size" case handling intact.
2019-03-07 00:05:30 +00:00
sin
1435d8186b Bump copyright 2019-02-25 13:22:33 +00:00
sin
5aabc7e6aa Make use of builtins whenever possible 2019-02-25 13:17:08 +00:00
sin
ad9a6d93b7 Bump to 1.0 2018-07-24 11:01:30 +01:00
A. Wilcox
a9ffac8596 Don't use __extension__ in C++ code
A few important notes:

*  __extension__ is a GNU C "alternate" keyword, not a C++ keyword.[1]

*  __extension__ is designed to work on "expressions"; it does work on
   #include_next in C mode, but it has no effect in C++ mode; the
   warning will still appear, if enabled, even with __extension__
   preceding #include_next.  This is because #include_next is not
   considered an expression in C++, so the compiler attaches
   __extension__ to the first expression of the header.

All of this leads us to a build failure while building at least all
Mozilla software.  Moz has an alternate -isystem dir searched before
/usr/include that overrides some headers, including <features.h>.  The
first statement in each of these headers is a #pragma, and since
__extension__ is looking for an expression, and #pragma is a "null"
expression, we end up with the following error:

dist/system_wrappers/features.h:1:9: error: '#pragma' is not allowed here

Since __extension__ has no effect on #include_next in C++ mode anyway,
and since it can cause breakage, this commit omits __extension__ in C++
mode.

[1]: https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/Alternate-Keywords.html
2018-07-24 11:00:30 +01:00
sin
6e7e43ff99 Bump to 0.9 2017-08-22 11:38:57 +01:00
sin
9730e9d297 Don't trap if an encoding error occurs in wcrtomb()
The POSIX definition of wcrtomb
(http://pubs.opengroup.org/onlinepubs/9699919799/functions/wcrtomb.html)
states:

"When wc is not a valid wide character, an encoding error shall occur.
In this case, the function shall store the value of the macro [EILSEQ]
in errno and shall return (size_t)-1; the conversion state shall be
undefined."

The fortify-headers implementation of wcrtomb interprets the result -1
as 18446744073709551615 bytes. Since this is the highest 64-bit number
possible, it is pretty safe to say this will always be larger than any
buffer provided to wcrtomb. Therefore, it traps.

Fixes bug https://bugs.alpinelinux.org/issues/7681.

Patch by A. Wilcox <AWilcox@Wilcox-Tech.com>
2017-08-22 11:38:36 +01:00
sin
2bc423c355 Bump copyright year 2016-09-10 12:54:17 +01:00
sin
ee2b986235 Bump to 0.8 2016-07-14 16:09:32 +01:00
Natanael Copa
9880d5864b Only include limits.h when actually used
The __extension__ seems to trigger a bug in gcc when there are no
identifier specified afterwards.

Testcase:
  echo "#include <stdlib.h>" > try.c && cc -O0 -c try.c
  try.c:2:0: error: expected identifier or '(' at end of input

With -O2 it does not happen.

We work around this by only pulling in limits.h when we actually need the
PATH_MAX.

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
2016-07-14 16:09:13 +01:00
sin
578b693300 Bump to 0.7 2015-07-24 14:29:06 +01:00
sin
60dcebb6b8 Only crash on overflow for realpath() 2015-07-16 11:45:19 +01:00
sin
edb2ded3af Fix stpncpy() check
Do not crash unless the overflow would happen.
2015-07-15 17:02:27 +01:00
sin
a51406af12 Fix confstr() check
Do not crash unless the overflow would actually happen.
2015-07-15 16:05:52 +01:00
sin
a255506ca4 Fix wcrtomb() check
This was breaking valid code, example:
char c;
wcrtomb(&c, L'0', st);
2015-07-15 15:55:56 +01:00
Steven Barth
7fd984fcb5 Add __extension__ mark to include_next to silence -pedantic
Signed-off-by: Steven Barth <steven@midlink.org>
2015-06-25 10:18:26 +01:00
Steven Barth
0825063aa6 unistd: fix signed / unsigned comparison in getgroups
Signed-off-by: Steven Barth <steven@midlink.org>
2015-06-22 19:05:54 +01:00
sin
8ff214efe6 Bump to 0.6 2015-06-17 16:37:56 +01:00
Trutz Behn
4cdac9cbda Use the __inline__ keyword instead of __inline to avoid breakage
Newer compilers default to GNU11, a C11 dialect. Some software however
is unprepared for this or has wrong compatibility checks. What happens
is that some software will for compatibility with C89

  #define inline

before inclusion of a standard header, which is undefined behaviour in
C99 and above (C99/C11 7.1.2/4), as inline is a keyword.

If any libc headers that are then included via #include_next provide an
__inline macro definition (current musl does this if C++ or C99 and
above is detected) like the following

  #define __inline inline

this results in any __inline token to be preprocessed away.

This breaks use of __builtin_va_arg_pack() in our stdio.h at
compile-time as it can only be used in always inlined functions. The
function attributes __always_inline__ and __gnu_inline__ themselves
require an inline specifier on the function to be applied.
2015-06-04 18:52:50 +01:00
Trutz Behn
1cd5461a53 Use namespace-safe macro, param and variable names 2015-06-03 18:55:35 +01:00
Trutz Behn
a9ee1d2743 Fix usage of __USER_LABEL_PREFIX__
The predefined __USER_LABEL_PREFIX__ macro if it is non-empty contains
an identifier, not a string literal, thus it needs to be stringified.
2015-06-03 08:33:32 +01:00
sin
ec970ecb88 Bump to 0.5 2015-05-29 12:38:17 +01:00
Trutz Behn
720c4f7414 Fix return-type of fortified FD_CLR and FD_SET
POSIX specifies them to have return-type void, not int.
2015-05-21 10:10:17 +01:00
sin
a81e053a1c Be less verbose in README 2015-05-19 10:22:59 +01:00
sin
50e37c7f76 Wrap some overly long lines 2015-05-13 12:18:35 +01:00
sin
07adb50914 Add LICENSE header 2015-05-13 12:15:36 +01:00
sin
158782b3bb Add fortify_fn() helper in fortify-headers.h 2015-05-13 12:05:29 +01:00
sin
316a486533 Minor style fix 2015-05-07 18:04:01 +01:00
Natanael Copa
c2bb9e106a fix realpath when stdlib.h is included before limits.h
If program includes stdlib.h before limits.h without _XOPEN_SOURCE,
_GNU_SOURCE or _BSD_SOURCE explicitly set, then will it always trigger
the trap with musl libc.

This is becase stdlib.h will pull in features.h which will set
_GNU_SOURCE. This means that the fortify stdlib.h will not include
limits.h but it will still trigger the fortified realpath(), but without
PATH_MAX set.

We fix this by including system stdlib.h before testing if limits.h
should be included.

Since PATH_MAX is known at compile time we can also error at compile
time, instead of compiling a broken realpath().
2015-05-07 15:02:11 +01:00
sin
c7e82d4863 Add read checks for bcopy() 2015-04-08 15:25:47 +01:00
sin
2bd3091b36 Check for out of bound reads for memcpy, memmove and mempcpy() 2015-04-08 15:18:49 +01:00
sin
91a579a42c Bump to 0.4 2015-04-06 10:06:01 +01:00
sin
534ef92103 Update README again 2015-04-01 17:49:31 +01:00
sin
e359fc6ace Update README 2015-04-01 17:46:57 +01:00
sin
73839e34a6 Add feature-test guards for mbsnrtowcs() and wcsnrtombs() 2015-04-01 12:41:08 +01:00
sin
739ec00a02 Update README 2015-03-24 12:25:13 +00:00
sin
d6510c1594 Add url to alpine linux fortify integration 2015-03-24 12:24:17 +00:00
13 changed files with 544 additions and 419 deletions

@ -1,4 +1,4 @@
Copyright (C) 2015 Dimitris Papastamos <sin@2f30.org>
Copyright (C) 2015-2019 Dimitris Papastamos <sin@2f30.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

@ -1,4 +1,4 @@
VERSION = 0.3
VERSION = 1.1
PREFIX = /usr/local
install:

9
README

@ -1,9 +1,10 @@
What is it?
===========
This is a standalone implementation of fortify source[0]. It is libc-agnostic
and simply overlays the system headers by using the #include_next extension found
in GCC. It was initially intended to be used on musl[1] based Linux distributions.
This is a standalone implementation of fortify source[0]. It provides
compile time buffer checks. It is libc-agnostic and simply overlays the
system headers by using the #include_next extension found in GCC. It was
initially intended to be used on musl[1] based Linux distributions[2].
Features
@ -23,7 +24,6 @@ Features
Sample usage
============
A plan for integrating fortify into a system is still under discussion.
If you want to quickly test it, you can try something like the following:
cat > fgets.c <<EOF
@ -107,3 +107,4 @@ write
[0] http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
[1] http://www.musl-libc.org/
[2] http://git.alpinelinux.org/cgit/aports/commit/?id=067a4f28825478911bb62be3b8da758d9722753e

24
include/fortify-headers.h Normal file

@ -0,0 +1,24 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_HEADERS_H
#define _FORTIFY_HEADERS_H
#define _FORTIFY_STR(s) #s
#define _FORTIFY_ORIG(p,fn) __typeof__(fn) __orig_##fn __asm__(_FORTIFY_STR(p) #fn)
#define _FORTIFY_FN(fn) _FORTIFY_ORIG(__USER_LABEL_PREFIX__,fn); \
extern __inline__ __attribute__((__always_inline__,__gnu_inline__,__artificial__))
#endif

@ -1,9 +1,28 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_POLL_H
#define _FORTIFY_POLL_H
#ifndef __cplusplus
__extension__
#endif
#include_next <poll.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -11,28 +30,25 @@ extern "C" {
#undef poll
__typeof__(poll) __poll_orig __asm__(__USER_LABEL_PREFIX__ "poll");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
_FORTIFY_FN(poll) int poll(struct pollfd *__f, nfds_t __n, int __s)
{
__typeof__(sizeof 0) bos = __builtin_object_size(fds, 0);
__typeof__(sizeof 0) __b = __builtin_object_size(__f, 0);
if (nfds > bos / sizeof(struct pollfd))
if (__n > __b / sizeof(struct pollfd))
__builtin_trap();
return __poll_orig(fds, nfds, timeout);
return __orig_poll(__f, __n, __s);
}
#ifdef _GNU_SOURCE
#undef ppoll
__typeof__(ppoll) __ppoll_orig __asm__(__USER_LABEL_PREFIX__ "ppoll");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *mask)
_FORTIFY_FN(ppoll) int ppoll(struct pollfd *__f, nfds_t __n, const struct timespec *__s,
const sigset_t *__m)
{
__typeof__(sizeof 0) bos = __builtin_object_size(fds, 0);
__typeof__(sizeof 0) __b = __builtin_object_size(__f, 0);
if (nfds > bos / sizeof(struct pollfd))
if (__n > __b / sizeof(struct pollfd))
__builtin_trap();
return __ppoll_orig(fds, nfds, timeout, mask);
return __orig_ppoll(__f, __n, __s, __m);
}
#endif

@ -1,9 +1,28 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_STDIO_H
#define _FORTIFY_STDIO_H
#ifndef __cplusplus
__extension__
#endif
#include_next <stdio.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -17,97 +36,84 @@ extern "C" {
#undef snprintf
#undef sprintf
__typeof__(fgets) __fgets_orig __asm__(__USER_LABEL_PREFIX__ "fgets");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *fgets(char *s, int n, FILE *fp)
_FORTIFY_FN(fgets) char *fgets(char *__s, int __n, FILE *__f)
{
size_t bos = __builtin_object_size(s, 0);
size_t __b = __builtin_object_size(__s, 0);
if ((size_t)n > bos)
if ((size_t)__n > __b)
__builtin_trap();
return __fgets_orig(s, n, fp);
return __orig_fgets(__s, __n, __f);
}
__typeof__(fread) __fread_orig __asm__(__USER_LABEL_PREFIX__ "fread");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t fread(void *dst, size_t n, size_t nmemb, FILE *fp)
_FORTIFY_FN(fread) size_t fread(void *__d, size_t __n, size_t __m, FILE *__f)
{
size_t bos = __builtin_object_size(dst, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n != 0 && (n * nmemb) / n != nmemb)
if (__n != 0 && (__n * __m) / __n != __m)
__builtin_trap();
if (n * nmemb > bos)
if (__n * __m > __b)
__builtin_trap();
return __fread_orig(dst, n, nmemb, fp);
return __orig_fread(__d, __n, __m, __f);
}
__typeof__(fwrite) __fwrite_orig __asm__(__USER_LABEL_PREFIX__ "fwrite");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t fwrite(const void *dst, size_t n, size_t nmemb, FILE *fp)
_FORTIFY_FN(fwrite) size_t fwrite(const void *__d, size_t __n, size_t __m, FILE *__f)
{
size_t bos = __builtin_object_size(dst, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n != 0 && (n * nmemb) / n != nmemb)
if (__n != 0 && (__n * __m) / __n != __m)
__builtin_trap();
if (n * nmemb > bos)
if (__n * __m > __b)
__builtin_trap();
return __fwrite_orig(dst, n, nmemb, fp);
return __orig_fwrite(__d, __n, __m, __f);
}
__typeof__(vsnprintf) __vsnprintf_orig __asm__(__USER_LABEL_PREFIX__ "vsnprintf");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int vsnprintf(char *s, size_t n, const char *fmt, __builtin_va_list ap)
_FORTIFY_FN(vsnprintf) int vsnprintf(char *__s, size_t __n, const char *__f,
__builtin_va_list __v)
{
size_t bos = __builtin_object_size(s, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __vsnprintf_orig(s, n, fmt, ap);
return __orig_vsnprintf(__s, __n, __f, __v);
}
__typeof__(vsprintf) __vsprintf_orig __asm__(__USER_LABEL_PREFIX__ "vsprintf");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int vsprintf(char *s, const char *fmt, __builtin_va_list ap)
_FORTIFY_FN(vsprintf) int vsprintf(char *__s, const char *__f, __builtin_va_list __v)
{
size_t bos = __builtin_object_size(s, 0);
int r;
size_t __b = __builtin_object_size(__s, 0);
int __r;
if (bos != (size_t)-1) {
r = __vsnprintf_orig(s, bos, fmt, ap);
if (r != -1 && (size_t)r >= bos)
if (__b != (size_t)-1) {
__r = __orig_vsnprintf(__s, __b, __f, __v);
if (__r != -1 && (size_t)__r >= __b)
__builtin_trap();
} else {
r = __vsprintf_orig(s, fmt, ap);
__r = __orig_vsprintf(__s, __f, __v);
}
return r;
return __r;
}
__typeof__(snprintf) __snprintf_orig __asm__(__USER_LABEL_PREFIX__ "snprintf");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int snprintf(char *s, size_t n, const char *fmt, ...)
_FORTIFY_FN(snprintf) int snprintf(char *__s, size_t __n, const char *__f, ...)
{
size_t bos = __builtin_object_size(s, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __snprintf_orig(s, n, fmt, __builtin_va_arg_pack());
return __orig_snprintf(__s, __n, __f, __builtin_va_arg_pack());
}
__typeof__(sprintf) __sprintf_orig __asm__(__USER_LABEL_PREFIX__ "sprintf");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int sprintf(char *s, const char *fmt, ...)
_FORTIFY_FN(sprintf) int sprintf(char *__s, const char *__f, ...)
{
size_t bos = __builtin_object_size(s, 0);
int r;
size_t __b = __builtin_object_size(__s, 0);
int __r;
if (bos != (size_t)-1) {
r = __snprintf_orig(s, bos, fmt, __builtin_va_arg_pack());
if (r != -1 && (size_t)r >= bos)
if (__b != (size_t)-1) {
__r = __orig_snprintf(__s, __b, __f, __builtin_va_arg_pack());
if (__r != -1 && (size_t)__r >= __b)
__builtin_trap();
} else {
r = __sprintf_orig(s, fmt, __builtin_va_arg_pack());
__r = __orig_sprintf(__s, __f, __builtin_va_arg_pack());
}
return r;
return __r;
}
#ifdef __cplusplus

@ -1,13 +1,35 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_STDLIB_H
#define _FORTIFY_STDLIB_H
#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#include_next <limits.h>
#ifndef __cplusplus
__extension__
#endif
#include_next <stdlib.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#ifndef __cplusplus
__extension__
#endif
#include_next <limits.h>
#endif
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -15,22 +37,26 @@ extern "C" {
#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#undef realpath
__typeof__(realpath) __realpath_orig __asm__(__USER_LABEL_PREFIX__ "realpath");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *realpath(const char *path, char *resolved)
_FORTIFY_FN(realpath) char *realpath(const char *__p, char *__r)
{
size_t bos;
if (resolved) {
#ifndef PATH_MAX
__builtin_trap();
#error PATH_MAX unset. A fortified realpath will not work.
#else
bos = __builtin_object_size(resolved, 0);
if (PATH_MAX > bos)
if (__r && PATH_MAX > __builtin_object_size(__r, 2)) {
char __buf[PATH_MAX], *__ret;
size_t __l;
__ret = __orig_realpath(__p, __buf);
if (!__ret)
return NULL;
__l = __builtin_strlen(__ret) + 1;
if (__l > __builtin_object_size(__r, 0))
__builtin_trap();
#endif
__builtin_memcpy(__r, __ret, __l);
return __r;
}
return __realpath_orig(path, resolved);
return __orig_realpath(__p, __r);
#endif
}
#endif

@ -1,9 +1,28 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_STRING_H
#define _FORTIFY_STRING_H
#ifndef __cplusplus
__extension__
#endif
#include_next <string.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -17,162 +36,141 @@ extern "C" {
#undef strncat
#undef strncpy
__typeof__(memcpy) __memcpy_orig __asm__(__USER_LABEL_PREFIX__ "memcpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void *memcpy(void *dest, const void *src, size_t n)
_FORTIFY_FN(memcpy) void *memcpy(void *__od, const void *__os, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
char *d = (char *)dest;
const char *s = (const char *)src;
size_t __bd = __builtin_object_size(__od, 0);
size_t __bs = __builtin_object_size(__os, 0);
char *__d = (char *)__od;
const char *__s = (const char *)__os;
/* trap if pointers are overlapping but not if dest == src.
* gcc seems to like to generate code that relies on dest == src */
if ((d < s && d + n > s) ||
(s < d && s + n > d))
/* trap if pointers are overlapping but not if dst == src.
* gcc seems to like to generate code that relies on dst == src */
if ((__d < __s && __d + __n > __s) ||
(__s < __d && __s + __n > __d))
__builtin_trap();
if (n > bos)
if (__n > __bd || __n > __bs)
__builtin_trap();
return __memcpy_orig(dest, src, n);
return __builtin_memcpy(__od, __os, __n);
}
__typeof__(memmove) __memmove_orig __asm__(__USER_LABEL_PREFIX__ "memmove");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void *memmove(void *dest, const void *src, size_t n)
_FORTIFY_FN(memmove) void *memmove(void *__d, const void *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __bd = __builtin_object_size(__d, 0);
size_t __bs = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __bd || __n > __bs)
__builtin_trap();
return __memmove_orig(dest, src, n);
return __orig_memmove(__d, __s, __n);
}
__typeof__(memset) __memset_orig __asm__(__USER_LABEL_PREFIX__ "memset");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void *memset(void *dest, int c, size_t n)
_FORTIFY_FN(memset) void *memset(void *__d, int __c, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __memset_orig(dest, c, n);
return __builtin_memset(__d, __c, __n);
}
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|| defined(_BSD_SOURCE)
#undef stpcpy
__typeof__(stpcpy) __stpcpy_orig __asm__(__USER_LABEL_PREFIX__ "stpcpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *stpcpy(char *dest, const char *src)
_FORTIFY_FN(stpcpy) char *stpcpy(char *__d, const char *__s)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (strlen(src) + 1 > bos)
if (strlen(__s) + 1 > __b)
__builtin_trap();
return __stpcpy_orig(dest, src);
return __orig_stpcpy(__d, __s);
}
#undef stpncpy
__typeof__(stpncpy) __stpncpy_orig __asm__(__USER_LABEL_PREFIX__ "stpncpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *stpncpy(char *dest, const char *src, size_t n)
_FORTIFY_FN(stpncpy) char *stpncpy(char *__d, const char *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos)
if (__n > __b && strlen(__s) + 1 > __b)
__builtin_trap();
return __stpncpy_orig(dest, src, n);
return __orig_stpncpy(__d, __s, __n);
}
#endif
__typeof__(strcat) __strcat_orig __asm__(__USER_LABEL_PREFIX__ "strcat");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *strcat(char *dest, const char *src)
_FORTIFY_FN(strcat) char *strcat(char *__d, const char *__s)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (strlen(src) + strlen(dest) + 1 > bos)
if (strlen(__s) + strlen(__d) + 1 > __b)
__builtin_trap();
return __strcat_orig(dest, src);
return __orig_strcat(__d, __s);
}
__typeof__(strcpy) __strcpy_orig __asm__(__USER_LABEL_PREFIX__ "strcpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *strcpy(char *dest, const char *src)
_FORTIFY_FN(strcpy) char *strcpy(char *__d, const char *__s)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (strlen(src) + 1 > bos)
if (strlen(__s) + 1 > __b)
__builtin_trap();
return __strcpy_orig(dest, src);
return __orig_strcpy(__d, __s);
}
__typeof__(strncat) __strncat_orig __asm__(__USER_LABEL_PREFIX__ "strncat");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *strncat(char *dest, const char *src, size_t n)
_FORTIFY_FN(strncat) char *strncat(char *__d, const char *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t slen, dlen;
size_t __b = __builtin_object_size(__d, 0);
size_t __sl, __dl;
if (n > bos) {
slen = strlen(src);
dlen = strlen(dest);
if (slen > n)
slen = n;
if (slen + dlen + 1 > bos)
if (__n > __b) {
__sl = strlen(__s);
__dl = strlen(__d);
if (__sl > __n)
__sl = __n;
if (__sl + __dl + 1 > __b)
__builtin_trap();
}
return __strncat_orig(dest, src, n);
return __orig_strncat(__d, __s, __n);
}
__typeof__(strncpy) __strncpy_orig __asm__(__USER_LABEL_PREFIX__ "strncpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *strncpy(char *dest, const char *src, size_t n)
_FORTIFY_FN(strncpy) char *strncpy(char *__d, const char *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __strncpy_orig(dest, src, n);
return __orig_strncpy(__d, __s, __n);
}
#ifdef _GNU_SOURCE
#undef mempcpy
__typeof__(mempcpy) __mempcpy_orig __asm__(__USER_LABEL_PREFIX__ "mempcpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void *mempcpy(void *dest, const void *src, size_t n)
_FORTIFY_FN(mempcpy) void *mempcpy(void *__d, const void *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __bd = __builtin_object_size(__d, 0);
size_t __bs = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __bd || __n > __bs)
__builtin_trap();
return __mempcpy_orig(dest, src, n);
return __orig_mempcpy(__d, __s, __n);
}
#endif
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#undef strlcat
#undef strlcpy
__typeof__(strlcat) __strlcat_orig __asm__(__USER_LABEL_PREFIX__ "strlcat");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t strlcat(char *dest, const char *src, size_t n)
_FORTIFY_FN(strlcat) size_t strlcat(char *__d, const char *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __strlcat_orig(dest, src, n);
return __orig_strlcat(__d, __s, __n);
}
__typeof__(strlcpy) __strlcpy_orig __asm__(__USER_LABEL_PREFIX__ "strlcpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t strlcpy(char *dest, const char *src, size_t n)
_FORTIFY_FN(strlcpy) size_t strlcpy(char *__d, const char *__s, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __strlcpy_orig(dest, src, n);
return __orig_strlcpy(__d, __s, __n);
}
#endif

@ -1,9 +1,25 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_STRINGS_H
#define _FORTIFY_STRINGS_H
#include_next <strings.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -14,26 +30,23 @@ extern "C" {
|| (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
#undef bcopy
#undef bzero
__typeof__(bcopy) __bcopy_orig __asm__(__USER_LABEL_PREFIX__ "bcopy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void bcopy(const void *src, void *dest, size_t n)
_FORTIFY_FN(bcopy) void bcopy(const void *__s, void *__d, size_t __n)
{
size_t bos = __builtin_object_size(dest, 0);
size_t __bd = __builtin_object_size(__d, 0);
size_t __bs = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __bd || __n > __bs)
__builtin_trap();
return __bcopy_orig(src, dest, n);
return __orig_bcopy(__s, __d, __n);
}
__typeof__(bzero) __bzero_orig __asm__(__USER_LABEL_PREFIX__ "bzero");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void bzero(void *src, size_t n)
_FORTIFY_FN(bzero) void bzero(void *__s, size_t __n)
{
size_t bos = __builtin_object_size(src, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __bzero_orig(src, n);
return __orig_bzero(__s, __n);
}
#endif

@ -1,6 +1,24 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_SYS_SELECT_H
#define _FORTIFY_SYS_SELECT_H
#ifndef __cplusplus
__extension__
#endif
#include_next <sys/select.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
@ -9,24 +27,24 @@
extern "C" {
#endif
static __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int __fortify_FD_CLR(int fd, fd_set *set)
static __inline__ __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void __fortify_FD_CLR(int __f, fd_set *__s)
{
size_t bos = __builtin_object_size(set, 0);
size_t __b = __builtin_object_size(__s, 0);
if (fd < 0 || fd >= FD_SETSIZE || bos < sizeof(fd_set))
if (__f < 0 || __f >= FD_SETSIZE || __b < sizeof(fd_set))
__builtin_trap();
return FD_CLR(fd, set);
FD_CLR(__f, __s);
}
static __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int __fortify_FD_SET(int fd, fd_set *set)
static __inline__ __attribute__((__always_inline__,__gnu_inline__,__artificial__))
void __fortify_FD_SET(int __f, fd_set *__s)
{
size_t bos = __builtin_object_size(set, 0);
size_t __b = __builtin_object_size(__s, 0);
if (fd < 0 || fd >= FD_SETSIZE || bos < sizeof(fd_set))
if (__f < 0 || __f >= FD_SETSIZE || __b < sizeof(fd_set))
__builtin_trap();
return FD_SET(fd, set);
FD_SET(__f, __s);
}
#undef FD_CLR

@ -1,9 +1,28 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_SYS_SOCKET_H
#define _FORTIFY_SYS_SOCKET_H
#ifndef __cplusplus
__extension__
#endif
#include_next <sys/socket.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "../fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -14,50 +33,42 @@ extern "C" {
#undef send
#undef sendto
__typeof__(recv) __recv_orig __asm__(__USER_LABEL_PREFIX__ "recv");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t recv(int sockfd, void *buf, size_t n, int flags)
_FORTIFY_FN(recv) ssize_t recv(int __f, void *__s, size_t __n, int __fl)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __recv_orig(sockfd, buf, n, flags);
return __orig_recv(__f, __s, __n, __fl);
}
__typeof__(recvfrom) __recvfrom_orig __asm__(__USER_LABEL_PREFIX__ "recvfrom");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t recvfrom(int sockfd, void *buf, size_t n, int flags,
struct sockaddr *sa, socklen_t *salen)
_FORTIFY_FN(recvfrom) ssize_t recvfrom(int __f, void *__s, size_t __n, int __fl,
struct sockaddr *__a, socklen_t *__l)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __recvfrom_orig(sockfd, buf, n, flags, sa, salen);
return __orig_recvfrom(__f, __s, __n, __fl, __a, __l);
}
__typeof__(send) __send_orig __asm__(__USER_LABEL_PREFIX__ "send");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t send(int sockfd, const void *buf, size_t n, int flags)
_FORTIFY_FN(send) ssize_t send(int __f, const void *__s, size_t __n, int __fl)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __send_orig(sockfd, buf, n, flags);
return __orig_send(__f, __s, __n, __fl);
}
__typeof__(sendto) __sendto_orig __asm__(__USER_LABEL_PREFIX__ "sendto");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t sendto(int sockfd, const void *buf, size_t n, int flags,
const struct sockaddr *sa, socklen_t salen)
_FORTIFY_FN(sendto) ssize_t sendto(int __f, const void *__s, size_t __n, int __fl,
const struct sockaddr *__a, socklen_t __l)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __sendto_orig(sockfd, buf, n, flags, sa, salen);
return __orig_sendto(__f, __s, __n, __fl, __a, __l);
}
#ifdef __cplusplus

@ -1,9 +1,28 @@
/*
* Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_UNISTD_H
#define _FORTIFY_UNISTD_H
#ifndef __cplusplus
__extension__
#endif
#include_next <unistd.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
@ -21,139 +40,116 @@ extern "C" {
#undef ttyname_r
#undef write
__typeof__(confstr) __confstr_orig __asm__(__USER_LABEL_PREFIX__ "confstr");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t confstr(int name, char *buf, size_t len)
_FORTIFY_FN(confstr) size_t confstr(int __n, char *__s, size_t __l)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
size_t __r = __orig_confstr(__n, __s, __b > __l ? __l : __b);
if (len > bos)
if (__l > __b && __r > __b)
__builtin_trap();
return __confstr_orig(name, buf, len);
return __r;
}
__typeof__(getcwd) __getcwd_orig __asm__(__USER_LABEL_PREFIX__ "getcwd");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
char *getcwd(char *buf, size_t len)
_FORTIFY_FN(getcwd) char *getcwd(char *__s, size_t __l)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (len > bos)
if (__l > __b)
__builtin_trap();
return __getcwd_orig(buf, len);
return __orig_getcwd(__s, __l);
}
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#undef getdomainname
__typeof__(getdomainname) __getdomainname_orig __asm__(__USER_LABEL_PREFIX__ "getdomainname");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int getdomainname(char *name, size_t len)
_FORTIFY_FN(getdomainname) int getdomainname(char *__s, size_t __l)
{
size_t bos = __builtin_object_size(name, 0);
size_t __b = __builtin_object_size(__s, 0);
if (len > bos)
if (__l > __b)
__builtin_trap();
return __getdomainname_orig(name, len);
return __orig_getdomainname(__s, __l);
}
#endif
__typeof__(getgroups) __getgroups_orig __asm__(__USER_LABEL_PREFIX__ "getgroups");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int getgroups(int len, gid_t *set)
_FORTIFY_FN(getgroups) int getgroups(int __l, gid_t *__s)
{
size_t bos = __builtin_object_size(set, 0);
size_t __b = __builtin_object_size(__s, 0);
if (len > bos / sizeof(gid_t))
if (__l > 0 && (unsigned)__l > __b / sizeof(gid_t))
__builtin_trap();
return __getgroups_orig(len, set);
return __orig_getgroups(__l, __s);
}
__typeof__(gethostname) __gethostname_orig __asm__(__USER_LABEL_PREFIX__ "gethostname");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int gethostname(char *name, size_t len)
_FORTIFY_FN(gethostname) int gethostname(char *__s, size_t __l)
{
size_t bos = __builtin_object_size(name, 0);
size_t __b = __builtin_object_size(__s, 0);
if (len > bos)
if (__l > __b)
__builtin_trap();
return __gethostname_orig(name, len);
return __orig_gethostname(__s, __l);
}
__typeof__(getlogin_r) __getlogin_r_orig __asm__(__USER_LABEL_PREFIX__ "getlogin_r");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int getlogin_r(char *name, size_t len)
_FORTIFY_FN(getlogin_r) int getlogin_r(char *__s, size_t __l)
{
size_t bos = __builtin_object_size(name, 0);
size_t __b = __builtin_object_size(__s, 0);
if (len > bos)
if (__l > __b)
__builtin_trap();
return __getlogin_r_orig(name, len);
return __orig_getlogin_r(__s, __l);
}
__typeof__(pread) __pread_orig __asm__(__USER_LABEL_PREFIX__ "pread");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t pread(int fd, void *buf, size_t n, off_t offset)
_FORTIFY_FN(pread) ssize_t pread(int __f, void *__s, size_t __n, off_t __o)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __pread_orig(fd, buf, n, offset);
return __orig_pread(__f, __s, __n, __o);
}
__typeof__(read) __read_orig __asm__(__USER_LABEL_PREFIX__ "read");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t read(int fd, void *buf, size_t n)
_FORTIFY_FN(read) ssize_t read(int __f, void *__s, size_t __n)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __read_orig(fd, buf, n);
return __orig_read(__f, __s, __n);
}
__typeof__(readlink) __readlink_orig __asm__(__USER_LABEL_PREFIX__ "readlink");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t readlink(const char *path, char *buf, size_t n)
_FORTIFY_FN(readlink) ssize_t readlink(const char *__p, char *__s, size_t __n)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __readlink_orig(path, buf, n);
return __orig_readlink(__p, __s, __n);
}
__typeof__(readlinkat) __readlinkat_orig __asm__(__USER_LABEL_PREFIX__ "readlinkat");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t readlinkat(int fd, const char *path, char *buf, size_t n)
_FORTIFY_FN(readlinkat) ssize_t readlinkat(int __f, const char *__p, char *__s, size_t __n)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __readlinkat_orig(fd, path, buf, n);
return __orig_readlinkat(__f, __p, __s, __n);
}
__typeof__(ttyname_r) __ttyname_r_orig __asm__(__USER_LABEL_PREFIX__ "ttyname_r");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int ttyname_r(int fd, char *name, size_t n)
_FORTIFY_FN(ttyname_r) int ttyname_r(int __f, char *__s, size_t __n)
{
size_t bos = __builtin_object_size(name, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __ttyname_r_orig(fd, name, n);
return __orig_ttyname_r(__f, __s, __n);
}
__typeof__(write) __write_orig __asm__(__USER_LABEL_PREFIX__ "write");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
ssize_t write(int fd, const void *buf, size_t n)
_FORTIFY_FN(write) ssize_t write(int __f, const void *__s, size_t __n)
{
size_t bos = __builtin_object_size(buf, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos)
if (__n > __b)
__builtin_trap();
return __write_orig(fd, buf, n);
return __orig_write(__f, __s, __n);
}
#ifdef __cplusplus

@ -1,17 +1,46 @@
/*
* Copyright (C) 2015-2017 Dimitris Papastamos <sin@2f30.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FORTIFY_WCHAR_H
#define _FORTIFY_WCHAR_H
#ifndef __cplusplus
__extension__
#endif
#include_next <limits.h>
#ifndef __cplusplus
__extension__
#endif
#include_next <stdlib.h>
#ifndef __cplusplus
__extension__
#endif
#include_next <string.h>
#ifndef __cplusplus
__extension__
#endif
#include_next <wchar.h>
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
#include "fortify-headers.h"
#ifdef __cplusplus
extern "C" {
#endif
#undef fgetws
#undef mbsnrtowcs
#undef mbsrtowcs
#undef mbstowcs
#undef wcrtomb
@ -19,7 +48,6 @@ extern "C" {
#undef wcscpy
#undef wcsncat
#undef wcsncpy
#undef wcsnrtombs
#undef wcsrtombs
#undef wcstombs
#undef wctomb
@ -27,210 +55,198 @@ extern "C" {
#undef wmemmove
#undef wmemset
__typeof__(fgetws) __fgetws_orig __asm__(__USER_LABEL_PREFIX__ "fgetws");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *fgetws(wchar_t *s, int n, FILE *fp)
_FORTIFY_FN(fgetws) wchar_t *fgetws(wchar_t *__s, int __n, FILE *__f)
{
size_t bos = __builtin_object_size(s, 0);
size_t __b = __builtin_object_size(__s, 0);
if ((size_t)n > bos / sizeof(wchar_t))
if ((size_t)__n > __b / sizeof(wchar_t))
__builtin_trap();
return __fgetws_orig(s, n, fp);
return __orig_fgetws(__s, __n, __f);
}
__typeof__(mbsnrtowcs) __mbsnrtowcs_orig __asm__(__USER_LABEL_PREFIX__ "mbsnrtowcs");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t mbsnrtowcs(wchar_t *d, const char **s, size_t n, size_t wn, mbstate_t *st)
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#undef mbsnrtowcs
_FORTIFY_FN(mbsnrtowcs) size_t mbsnrtowcs(wchar_t *__d, const char **__s, size_t __n,
size_t __wn, mbstate_t *__st)
{
size_t bos = __builtin_object_size(d, 0);
size_t r;
size_t __b = __builtin_object_size(__d, 0);
size_t __r;
if (wn > n / sizeof(wchar_t)) {
bos /= sizeof(wchar_t);
r = __mbsnrtowcs_orig(d, s, n, wn > bos ? bos : wn, st);
if (bos < wn && d && *s && r != (size_t)-1)
if (__wn > __n / sizeof(wchar_t)) {
__b /= sizeof(wchar_t);
__r = __orig_mbsnrtowcs(__d, __s, __n, __wn > __b ? __b : __wn, __st);
if (__b < __wn && __d && *__s && __r != (size_t)-1)
__builtin_trap();
} else {
r = __mbsnrtowcs_orig(d, s, n > bos ? bos : n, wn, st);
if (bos < n && d && *s && r != (size_t)-1)
__r = __orig_mbsnrtowcs(__d, __s, __n > __b ? __b : __n, __wn, __st);
if (__b < __n && __d && *__s && __r != (size_t)-1)
__builtin_trap();
}
return r;
return __r;
}
#endif
__typeof__(mbsrtowcs) __mbsrtowcs_orig __asm__(__USER_LABEL_PREFIX__ "mbsrtowcs");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t mbsrtowcs(wchar_t *d, const char **s, size_t wn, mbstate_t *st)
_FORTIFY_FN(mbsrtowcs) size_t mbsrtowcs(wchar_t *__d, const char **__s, size_t __wn,
mbstate_t *__st)
{
size_t bos = __builtin_object_size(d, 0);
size_t r;
size_t __b = __builtin_object_size(__d, 0);
size_t __r;
bos /= sizeof(wchar_t);
r = __mbsrtowcs_orig(d, s, wn > bos ? bos : wn, st);
if (bos < wn && d && *s && r != (size_t)-1)
__b /= sizeof(wchar_t);
__r = __orig_mbsrtowcs(__d, __s, __wn > __b ? __b : __wn, __st);
if (__b < __wn && __d && *__s && __r != (size_t)-1)
__builtin_trap();
return r;
return __r;
}
__typeof__(mbstowcs) __mbstowcs_orig __asm__(__USER_LABEL_PREFIX__ "mbstowcs");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t mbstowcs(wchar_t *ws, const char *s, size_t wn)
_FORTIFY_FN(mbstowcs) size_t mbstowcs(wchar_t *__ws, const char *__s, size_t __wn)
{
size_t bos = __builtin_object_size(ws, 0);
size_t __b = __builtin_object_size(__ws, 0);
if (ws && wn > bos / sizeof(wchar_t))
if (__ws && __wn > __b / sizeof(wchar_t))
__builtin_trap();
return __mbstowcs_orig(ws, s, wn);
return __orig_mbstowcs(__ws, __s, __wn);
}
__typeof__(wcrtomb) __wcrtomb_orig __asm__(__USER_LABEL_PREFIX__ "wcrtomb");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t wcrtomb(char *s, wchar_t wc, mbstate_t *st)
_FORTIFY_FN(wcrtomb) size_t wcrtomb(char *__s, wchar_t __w, mbstate_t *__st)
{
size_t bos = __builtin_object_size(s, 0);
if (__s && MB_LEN_MAX > __builtin_object_size(__s, 2)) {
char __buf[MB_LEN_MAX];
size_t __r;
if (s && MB_CUR_MAX > bos)
__r = __orig_wcrtomb(__buf, __w, __st);
if (__r == (size_t)-1)
return __r;
if (__r > __builtin_object_size(__s, 0))
__builtin_trap();
__builtin_memcpy(__s, __buf, __r);
return __r;
}
return __orig_wcrtomb(__s, __w, __st);
}
_FORTIFY_FN(wcscat) wchar_t *wcscat(wchar_t *__d, const wchar_t *__s)
{
size_t __b = __builtin_object_size(__d, 0);
if (wcslen(__s) + wcslen(__d) + 1 > __b / sizeof(wchar_t))
__builtin_trap();
return __wcrtomb_orig(s, wc, st);
return __orig_wcscat(__d, __s);
}
__typeof__(wcscat) __wcscat_orig __asm__(__USER_LABEL_PREFIX__ "wcscat");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wcscat(wchar_t *d, const wchar_t *s)
_FORTIFY_FN(wcscpy) wchar_t *wcscpy(wchar_t *__d, const wchar_t *__s)
{
size_t bos = __builtin_object_size(d, 0);
size_t __b = __builtin_object_size(__d, 0);
if (wcslen(s) + wcslen(d) + 1 > bos / sizeof(wchar_t))
if (wcslen(__s) + 1 > __b / sizeof(wchar_t))
__builtin_trap();
return __wcscat_orig(d, s);
return __orig_wcscpy(__d, __s);
}
__typeof__(wcscpy) __wcscpy_orig __asm__(__USER_LABEL_PREFIX__ "wcscpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wcscpy(wchar_t *d, const wchar_t *s)
_FORTIFY_FN(wcsncat) wchar_t *wcsncat(wchar_t *__d, const wchar_t *__s, size_t __n)
{
size_t bos = __builtin_object_size(d, 0);
size_t __b = __builtin_object_size(__d, 0);
size_t __sl, __dl;
if (wcslen(s) + 1 > bos / sizeof(wchar_t))
__builtin_trap();
return __wcscpy_orig(d, s);
}
__typeof__(wcsncat) __wcsncat_orig __asm__(__USER_LABEL_PREFIX__ "wcsncat");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wcsncat(wchar_t *d, const wchar_t *s, size_t n)
{
size_t bos = __builtin_object_size(d, 0);
size_t slen, dlen;
if (n > bos / sizeof(wchar_t)) {
slen = wcslen(s);
dlen = wcslen(d);
if (slen > n)
slen = n;
if (slen + dlen + 1 > bos / sizeof(wchar_t))
if (__n > __b / sizeof(wchar_t)) {
__sl = wcslen(__s);
__dl = wcslen(__d);
if (__sl > __n)
__sl = __n;
if (__sl + __dl + 1 > __b / sizeof(wchar_t))
__builtin_trap();
}
return __wcsncat_orig(d, s, n);
return __orig_wcsncat(__d, __s, __n);
}
__typeof__(wcsncpy) __wcsncpy_orig __asm__(__USER_LABEL_PREFIX__ "wcsncpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wcsncpy(wchar_t *d, const wchar_t *s, size_t n)
_FORTIFY_FN(wcsncpy) wchar_t *wcsncpy(wchar_t *__d, const wchar_t *__s, size_t __n)
{
size_t bos = __builtin_object_size(d, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos / sizeof(wchar_t))
if (__n > __b / sizeof(wchar_t))
__builtin_trap();
return __wcsncpy_orig(d, s, n);
return __orig_wcsncpy(__d, __s, __n);
}
__typeof__(wcsnrtombs) __wcsnrtombs_orig __asm__(__USER_LABEL_PREFIX__ "wcsnrtombs");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t wcsnrtombs(char *d, const wchar_t **s, size_t wn, size_t n, mbstate_t *st)
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#undef wcsnrtombs
_FORTIFY_FN(wcsnrtombs) size_t wcsnrtombs(char *__d, const wchar_t **__s, size_t __wn,
size_t __n, mbstate_t *__st)
{
size_t bos = __builtin_object_size(d, 0);
size_t r;
size_t __b = __builtin_object_size(__d, 0);
size_t __r;
if (wn > n / sizeof(wchar_t)) {
bos /= sizeof(wchar_t);
r = __wcsnrtombs_orig(d, s, wn > bos ? bos : wn, n, st);
if (bos < wn && d && *s && r != (size_t)-1)
if (__wn > __n / sizeof(wchar_t)) {
__b /= sizeof(wchar_t);
__r = __orig_wcsnrtombs(__d, __s, __wn > __b ? __b : __wn, __n, __st);
if (__b < __wn && __d && *__s && __r != (size_t)-1)
__builtin_trap();
} else {
r = __wcsnrtombs_orig(d, s, wn, n > bos ? bos : n, st);
if (bos < n && d && *s && r != (size_t)-1)
__r = __orig_wcsnrtombs(__d, __s, __wn, __n > __b ? __b : __n, __st);
if (__b < __n && __d && *__s && __r != (size_t)-1)
__builtin_trap();
}
return r;
return __r;
}
#endif
_FORTIFY_FN(wcsrtombs) size_t wcsrtombs(char *__d, const wchar_t **__s, size_t __n,
mbstate_t *__st)
{
size_t __b = __builtin_object_size(__d, 0);
size_t __r;
__r = __orig_wcsrtombs(__d, __s, __n > __b ? __b : __n, __st);
if (__b < __n && __d && *__s && __r != (size_t)-1)
__builtin_trap();
return __r;
}
__typeof__(wcsrtombs) __wcsrtombs_orig __asm__(__USER_LABEL_PREFIX__ "wcsrtombs");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t wcsrtombs(char *d, const wchar_t **s, size_t n, mbstate_t *st)
_FORTIFY_FN(wcstombs) size_t wcstombs(char *__s, const wchar_t *__ws, size_t __n)
{
size_t bos = __builtin_object_size(d, 0);
size_t r;
size_t __b = __builtin_object_size(__s, 0);
r = __wcsrtombs_orig(d, s, n > bos ? bos : n, st);
if (bos < n && d && *s && r != (size_t)-1)
if (__s && __n > __b)
__builtin_trap();
return r;
return __orig_wcstombs(__s, __ws, __n);
}
__typeof__(wcstombs) __wcstombs_orig __asm__(__USER_LABEL_PREFIX__ "wcstombs");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
size_t wcstombs(char *s, const wchar_t *ws, size_t n)
_FORTIFY_FN(wctomb) int wctomb(char *__s, wchar_t __w)
{
size_t bos = __builtin_object_size(s, 0);
size_t __b = __builtin_object_size(__s, 0);
if (s && n > bos)
if (__s && MB_LEN_MAX > __b && MB_CUR_MAX > __b)
__builtin_trap();
return __wcstombs_orig(s, ws, n);
return __orig_wctomb(__s, __w);
}
__typeof__(wctomb) __wctomb_orig __asm__(__USER_LABEL_PREFIX__ "wctomb");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
int wctomb(char *s, wchar_t wc)
_FORTIFY_FN(wmemcpy) wchar_t *wmemcpy(wchar_t *__d, const wchar_t *__s, size_t __n)
{
size_t bos = __builtin_object_size(s, 0);
size_t __b = __builtin_object_size(__d, 0);
if (s && MB_CUR_MAX > bos)
if (__n > __b / sizeof(wchar_t))
__builtin_trap();
return __wctomb_orig(s, wc);
return __orig_wmemcpy(__d, __s, __n);
}
__typeof__(wmemcpy) __wmemcpy_orig __asm__(__USER_LABEL_PREFIX__ "wmemcpy");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wmemcpy(wchar_t *d, const wchar_t *s, size_t n)
_FORTIFY_FN(wmemmove) wchar_t *wmemmove(wchar_t *__d, const wchar_t *__s, size_t __n)
{
size_t bos = __builtin_object_size(d, 0);
size_t __b = __builtin_object_size(__d, 0);
if (n > bos / sizeof(wchar_t))
if (__n > __b / sizeof(wchar_t))
__builtin_trap();
return __wmemcpy_orig(d, s, n);
return __orig_wmemmove(__d, __s, __n);
}
__typeof__(wmemmove) __wmemmove_orig __asm__(__USER_LABEL_PREFIX__ "wmemmove");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
_FORTIFY_FN(wmemset) wchar_t *wmemset(wchar_t *__s, wchar_t __c, size_t __n)
{
size_t bos = __builtin_object_size(d, 0);
size_t __b = __builtin_object_size(__s, 0);
if (n > bos / sizeof(wchar_t))
if (__n > __b / sizeof(wchar_t))
__builtin_trap();
return __wmemmove_orig(d, s, n);
}
__typeof__(wmemset) __wmemset_orig __asm__(__USER_LABEL_PREFIX__ "wmemset");
extern __inline __attribute__((__always_inline__,__gnu_inline__,__artificial__))
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n)
{
size_t bos = __builtin_object_size(s, 0);
if (n > bos / sizeof(wchar_t))
__builtin_trap();
return __wmemset_orig(s, c, n);
return __orig_wmemset(__s, __c, __n);
}
#ifdef __cplusplus