commit 2ccfced2116d00e6ddf3aa6f10cfacab5a863c76
parent 75b95fa25df74fcd0498bf59e3524f20f594755d
Author: jvoisin <julien.voisin@dustri.org>
Date: Wed, 27 Sep 2023 21:52:06 +0200
Add an option to make use of compiler-provided _chk builtins
Diffstat:
4 files changed, 87 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/testsuite.yaml b/.github/workflows/testsuite.yaml
@@ -11,6 +11,7 @@ jobs:
strategy:
matrix:
version: [9, 10, 11, 12]
+ use_native_chk: [true, false]
steps:
- name: Checking out the code
uses: actions/checkout@v3
@@ -30,18 +31,21 @@ jobs:
run: |
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${{ matrix.version }} 100
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ matrix.version }} 100
- - name: Build
+ - name: Build with native chk
+ if: ${{ matrix.use_native_chk == true }}
shell: bash
- run: make -C tests gcc
- - name: Running the testsuite
+ run: make CFLAGS=-DUSE_NATIVE_CHK -C tests gcc
+ - name: Build without native chk, and run the testsuite
+ if: ${{ matrix.use_native_chk == false }}
shell: bash
- run: make -C tests run
+ run: make -C tests gcc run
clang:
runs-on: ubuntu-latest
strategy:
matrix:
- version: [12, 13, 14, 15]
+ version: [13, 14, 15]
+ use_native_chk: [true, false]
steps:
- name: Checking out the code
uses: actions/checkout@v3
@@ -61,12 +65,11 @@ jobs:
run: |
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${{ matrix.version }} 100
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${{ matrix.version }} 100
- - name: Build
+ - name: Build with native chk
+ if: ${{ matrix.use_native_chk == true }}
shell: bash
- run: make -C tests clang
- - name: Running the compile-time testsuite
+ run: make CFLAGS=-DUSE_NATIVE_CHK -C tests clang
+ - name: Building and running without native chk
+ if: ${{ matrix.use_native_chk == false }}
shell: bash
- run: make -C tests clang
- - name: Running the run-time testsuite
- shell: bash
- run: make -C tests run
+ run: make -C tests clang run
diff --git a/README.md b/README.md
@@ -27,6 +27,9 @@ on Clang. It was initially intended to be used on
- It has a [comprehensive suite of tests](https://github.com/jvoisin/fortify-headers/tree/master/tests),
running both on Clang and on GCC for every commit, with
[significant coverage](https://jvoisin.github.io/fortify-headers/)
+- Defining `USE_NATIVE_CHK` will make use of compiler-provided builtin `_chk`
+ functions, which might be a bit better in term of diagnostics,
+ but won't necesarily provide the same amount of security checks.
# Sample usage
diff --git a/include/stdio.h b/include/stdio.h
@@ -145,11 +145,15 @@ __diagnose_as_builtin(__builtin_vsnprintf, 1, 2, 3, 4)
_FORTIFY_FN(vsnprintf) int vsnprintf(char * _FORTIFY_POS0 __s, size_t __n,
const char *__f, __builtin_va_list __v)
{
+#if __has_builtin(__builtin___vsnprintf_chk) && USE_NATIVE_CHK
+ return __builtin___vsnprintf_chk(__s, __n, _FORTIFY_SOURCE, __bos(__s, 0), __f, __v,);
+#else
size_t __b = __bos(__s, 0);
if (__n > __b)
__builtin_trap();
return __orig_vsnprintf(__s, __n, __f, __v);
+#endif
}
__format(printf, 2, 0)
@@ -161,6 +165,9 @@ __diagnose_as_builtin(__builtin_vsprintf, 1, 2, 3)
_FORTIFY_FN(vsprintf) int vsprintf(char * _FORTIFY_POS0 __s, const char *__f,
__builtin_va_list __v)
{
+#if __has_builtin(__builtin___vsnprintf_chk) && USE_NATIVE_CHK
+ return __builtin___vsprintf_chk(__s, _FORTIFY_SOURCE, __bos(__s, 0), __f, __v,);
+#else
size_t __b = __bos(__s, 0);
int __r;
@@ -172,8 +179,10 @@ _FORTIFY_FN(vsprintf) int vsprintf(char * _FORTIFY_POS0 __s, const char *__f,
__r = __orig_vsprintf(__s, __f, __v);
}
return __r;
+#endif
}
+
#if __has_builtin(__builtin_va_arg_pack)
/* clang is missing __builtin_va_arg_pack, so we cannot use these impls
diff --git a/include/string.h b/include/string.h
@@ -47,6 +47,9 @@ _FORTIFY_FN(memcpy) void *memcpy(void * _FORTIFY_POS0 __od,
const void * _FORTIFY_POS0 __os, size_t __n)
__error_if((__bos(__od, 0) < __n), "'memcpy' called with `n` bigger than the size of `d`.")
{
+#if __has_builtin(__builtin___memcpy_chk) && USE_NATIVE_CHK
+ return __builtin___memcpy_chk(__od, __os, __n, __bos(__od, 0));
+#else
size_t __bd = __bos(__od, 0);
size_t __bs = __bos(__os, 0);
char *__d = (char *)__od;
@@ -57,6 +60,7 @@ __error_if((__bos(__od, 0) < __n), "'memcpy' called with `n` bigger than the siz
if (__n > __bd || __n > __bs)
__builtin_trap();
return __builtin_memcpy(__od, __os, __n);
+#endif
}
__access(write_only, 1, 3)
@@ -67,12 +71,16 @@ __diagnose_as_builtin(__builtin_memmove, 1, 2, 3)
_FORTIFY_FN(memmove) void *memmove(void * _FORTIFY_POS0 __d,
const void * _FORTIFY_POS0 __s, size_t __n)
{
+#if __has_builtin(__builtin___memmove_chk) && USE_NATIVE_CHK
+ return __builtin___memcpy_chk(__d, __s, __n, __bos(__d, 0));
+#else
size_t __bd = __bos(__d, 0);
size_t __bs = __bos(__s, 0);
if (__n > __bd || __n > __bs)
__builtin_trap();
return __orig_memmove(__d, __s, __n);
+#endif
}
__access(write_only, 1, 3)
@@ -82,11 +90,15 @@ __diagnose_as_builtin(__builtin_memset, 1, 2, 3)
_FORTIFY_FN(memset) void *memset(void * _FORTIFY_POS0 __d, int __c, size_t __n)
__warning_if(__c != 0 && __n == 0, "'memset' will set `0` bytes; did you invert the arguments?")
{
+#if __has_builtin(__builtin___memset_chk) && USE_NATIVE_CHK
+ return __builtin___memset_chk(__d, __c, __n, __bos(__d, 0));
+#else
size_t __b = __bos(__d, 0);
if (__n > __b)
__builtin_trap();
return __builtin_memset(__d, __c, __n);
+#endif
}
__access(read_only, 1, 3)
@@ -95,33 +107,45 @@ __diagnose_as_builtin(__builtin_memchr, 1, 2, 3)
#endif
_FORTIFY_FN(memchr) void *memchr(const void * _FORTIFY_POS0 __d, int __c, size_t __n)
{
+#if __has_builtin(__builtin___memchr_chk) && USE_NATIVE_CHK
+ return __builtin___memchr_chk(__d, __c, __n, __bos(__d, 0));
+#else
size_t __b = __bos(__d, 0);
if (__n > __b)
__builtin_trap();
return __builtin_memchr(__d, __c, __n);
+#endif
}
__access(read_only, 1, 2)
_FORTIFY_FN(strchr) char *strchr(const char * _FORTIFY_POS0 __s, int __c)
{
+#if __has_builtin(__builtin___strchr_chk) && USE_NATIVE_CHK
+ return __builtin___strchr_chk(__s, __c, __bos(__s, 0));
+#else
size_t __b = __bos(__s, 0);
char* __r = __builtin_strchr(__s, __c);
if (__r - __s > __b)
__builtin_trap();
return __r;
+#endif
}
__access(read_only, 1, 2)
_FORTIFY_FN(strrchr) char *strrchr(const char * _FORTIFY_POS0 __s, int __c)
{
+#if __has_builtin(__builtin___strrchr_chk) && USE_NATIVE_CHK
+ return __builtin___strrchr_chk(__s, __c, __bos(__s, 0));
+#else
size_t __b = __bos(__s, 0);
char* __r = __builtin_strrchr(__s, __c);
if (__r - __s > __b)
__builtin_trap();
return __r;
+#endif
}
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
@@ -135,6 +159,9 @@ __diagnose_as_builtin(__builtin_stpcpy, 1, 2)
#endif
_FORTIFY_FN(stpcpy) char *stpcpy(char * _FORTIFY_POS0 __d, const char *__s)
{
+#if __has_builtin(__builtin___stpcpy_chk) && USE_NATIVE_CHK
+ return __builtin___stpcpy_chk(__d, __s, __bos(__d, 0));
+#else
size_t __n = strlen(__s) + 1;
if (__fh_overlap(__d, __s, __n))
@@ -144,6 +171,7 @@ _FORTIFY_FN(stpcpy) char *stpcpy(char * _FORTIFY_POS0 __d, const char *__s)
if (__n > __b)
__builtin_trap();
return __orig_stpcpy(__d, __s);
+#endif
}
#undef stpncpy
@@ -155,6 +183,9 @@ __diagnose_as_builtin(__builtin_stpncpy, 1, 2, 3)
_FORTIFY_FN(stpncpy) char *stpncpy(char * _FORTIFY_POS0 __d, const char *__s,
size_t __n)
{
+#if __has_builtin(__builtin___stpncpy_chk) && USE_NATIVE_CHK
+ return __builtin___stpncpy_chk(__d, __s, __n, __bos(__d, 0));
+#else
if (__fh_overlap(__d, __s, __n))
__builtin_trap();
@@ -162,6 +193,7 @@ _FORTIFY_FN(stpncpy) char *stpncpy(char * _FORTIFY_POS0 __d, const char *__s,
if (__n > __b && strlen(__s) + 1 > __b)
__builtin_trap();
return __orig_stpncpy(__d, __s, __n);
+#endif
}
#endif
@@ -172,11 +204,15 @@ __diagnose_as_builtin(__builtin_strcat, 1, 2)
#endif
_FORTIFY_FN(strcat) char *strcat(char * _FORTIFY_POS0 __d, const char *__s)
{
+#if __has_builtin(__builtin___strcat_chk) && USE_NATIVE_CHK
+ return __builtin___strcat_chk(__d, __s, __bos(__d, 0));
+#else
size_t __b = __bos(__d, 0);
if (strlen(__s) + strlen(__d) + 1 > __b)
__builtin_trap();
return __orig_strcat(__d, __s);
+#endif
}
__access (write_only, 1)
@@ -186,6 +222,9 @@ __diagnose_as_builtin(__builtin_strcpy, 1, 2)
#endif
_FORTIFY_FN(strcpy) char *strcpy(char * _FORTIFY_POS0 __d, const char *__s)
{
+#if __has_builtin(__builtin___strcpy_chk) && USE_NATIVE_CHK
+ return __builtin___strcpy_chk(__d, __s, __bos(__d, 0));
+#else
size_t __n = strlen(__s) + 1;
if (__fh_overlap(__d, __s, __n))
@@ -195,6 +234,7 @@ _FORTIFY_FN(strcpy) char *strcpy(char * _FORTIFY_POS0 __d, const char *__s)
if (__n > __b)
__builtin_trap();
return __orig_strcpy(__d, __s);
+#endif
}
__access (read_write, 1)
@@ -205,6 +245,9 @@ __diagnose_as_builtin(__builtin_strncat, 1, 2, 3)
_FORTIFY_FN(strncat) char *strncat(char * _FORTIFY_POS0 __d, const char *__s,
size_t __n)
{
+#if __has_builtin(__builtin___strncat_chk) && USE_NATIVE_CHK
+ return __builtin___strncat_chk(__d, __s, __n, __bos(__d, 0));
+#else
size_t __b = __bos(__d, 0);
if (__n > __b) {
@@ -214,6 +257,7 @@ _FORTIFY_FN(strncat) char *strncat(char * _FORTIFY_POS0 __d, const char *__s,
__builtin_trap();
}
return __orig_strncat(__d, __s, __n);
+#endif
}
__access (write_only, 1)
@@ -224,6 +268,9 @@ __diagnose_as_builtin(__builtin_strncpy, 1, 2, 3)
_FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d,
const char *__s, size_t __n)
{
+#if __has_builtin(__builtin___strncpy_chk) && USE_NATIVE_CHK
+ return __builtin___strncpy_chk(__d, __s, __n, __bos(__d, 0));
+#else
if (__fh_overlap(__d, __s, __n))
__builtin_trap();
@@ -231,6 +278,7 @@ _FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d,
if (__n > __b)
__builtin_trap();
return __orig_strncpy(__d, __s, __n);
+#endif
}
#ifdef _GNU_SOURCE
@@ -243,12 +291,16 @@ __diagnose_as_builtin(__builtin_mempcpy, 1, 2, 3)
_FORTIFY_FN(mempcpy) void *mempcpy(void * _FORTIFY_POS0 __d,
const void * _FORTIFY_POS0 __s, size_t __n)
{
+#if __has_builtin(__builtin___mempcpy_chk) && USE_NATIVE_CHK
+ return __builtin___mempcpy_chk(__d, __s, __n, __bos(__d, 0));
+#else
size_t __bd = __bos(__d, 0);
size_t __bs = __bos(__s, 0);
if (__n > __bd || __n > __bs)
__builtin_trap();
return __orig_mempcpy(__d, __s, __n);
+#endif
}
#endif
@@ -263,11 +315,15 @@ __diagnose_as_builtin(__builtin_strlcat, 1, 2, 3)
_FORTIFY_FN(strlcat) size_t strlcat(char * _FORTIFY_POS0 __d,
const char *__s, size_t __n)
{
+#if __has_builtin(__builtin___strlcat_chk) && USE_NATIVE_CHK
+ return __builtin___strlcat_chk(__d, __s, __n, __bos(__d, 0));
+#else
size_t __b = __bos(__d, 0);
if (__n > __b)
__builtin_trap();
return __orig_strlcat(__d, __s, __n);
+#endif
}
__access (write_only, 1)
@@ -278,11 +334,15 @@ __diagnose_as_builtin(__builtin_strlcpy, 1, 2, 3)
_FORTIFY_FN(strlcpy) size_t strlcpy(char * _FORTIFY_POS0 __d,
const char *__s, size_t __n)
{
+#if __has_builtin(__builtin___strlcpy_chk) && USE_NATIVE_CHK
+ return __builtin___strlcpy_chk(__d, __s, __n, __bos(__d, 0));
+#else
size_t __b = __bos(__d, 0);
if (__n > __b)
__builtin_trap();
return __orig_strlcpy(__d, __s, __n);
+#endif
}
#endif