test: Add a test for fortification of string functions
We currently only run the testcase where it doesn't trigger the failed checks though.
This commit is contained in:
1 parent
2013c9c165
commit
4c29469eac
3 files changed
+134
-1
No files matched your search
@@ -160,6 +160,9 @@ RUN cd test && \
|
|||||||
for test in stacksmash; do \
|
for test in stacksmash; do \
|
||||||
$arch-w64-mingw32-clang $test.c -o $arch/$test.exe -fstack-protector-strong || exit 1; \
|
$arch-w64-mingw32-clang $test.c -o $arch/$test.exe -fstack-protector-strong || exit 1; \
|
||||||
done; \
|
done; \
|
||||||
|
for test in bufferoverflow; do \
|
||||||
|
$arch-w64-mingw32-clang $test.c -o $arch/$test.exe -lssp -D_FORTIFY_SOURCE=2 -O2 || exit 1; \
|
||||||
|
done; \
|
||||||
done
|
done
|
||||||
|
|
||||||
# Build OpenMP
|
# Build OpenMP
|
||||||
|
|||||||
+5
-1
@@ -76,6 +76,7 @@ TESTS_CPP_DLL="tlstest-lib throwcatch-lib"
|
|||||||
TESTS_CPP_LINK_DLL="throwcatch-main"
|
TESTS_CPP_LINK_DLL="throwcatch-main"
|
||||||
TESTS_SSP="stacksmash"
|
TESTS_SSP="stacksmash"
|
||||||
TESTS_ASAN="stacksmash"
|
TESTS_ASAN="stacksmash"
|
||||||
|
TESTS_FORTIFY="bufferoverflow"
|
||||||
TESTS_UBSAN="ubsan"
|
TESTS_UBSAN="ubsan"
|
||||||
TESTS_OMP="hello-omp"
|
TESTS_OMP="hello-omp"
|
||||||
TESTS_UWP="uwp-error"
|
TESTS_UWP="uwp-error"
|
||||||
@@ -162,6 +163,9 @@ for arch in $ARCHS; do
|
|||||||
for test in $TESTS_SSP; do
|
for test in $TESTS_SSP; do
|
||||||
$arch-w64-mingw32-clang $test.c -o $TEST_DIR/$test.exe -fstack-protector-strong
|
$arch-w64-mingw32-clang $test.c -o $TEST_DIR/$test.exe -fstack-protector-strong
|
||||||
done
|
done
|
||||||
|
for test in $TESTS_FORTIFY; do
|
||||||
|
$arch-w64-mingw32-clang $test.c -o $TEST_DIR/$test.exe -O2 -D_FORTIFY_SOURCE=2 -lssp
|
||||||
|
done
|
||||||
for test in $TESTS_IDL; do
|
for test in $TESTS_IDL; do
|
||||||
# This is primary a build-only test, so no need to execute it.
|
# This is primary a build-only test, so no need to execute it.
|
||||||
# The IDL output isn't arch specific, but we want to test the
|
# The IDL output isn't arch specific, but we want to test the
|
||||||
@@ -236,7 +240,7 @@ for arch in $ARCHS; do
|
|||||||
DLL="$DLL $i"
|
DLL="$DLL $i"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
RUN_TESTS="$TESTS_C $TESTS_C_LINK_DLL $TESTS_CPP $TESTS_CPP_LINK_DLL $TESTS_EXTRA $TESTS_SSP"
|
RUN_TESTS="$TESTS_C $TESTS_C_LINK_DLL $TESTS_CPP $TESTS_CPP_LINK_DLL $TESTS_EXTRA $TESTS_SSP $TESTS_FORTIFY"
|
||||||
cd $TEST_DIR
|
cd $TEST_DIR
|
||||||
if [ -n "$COPY" ]; then
|
if [ -n "$COPY" ]; then
|
||||||
COPYFILES=""
|
COPYFILES=""
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Martin Storsjo
|
||||||
|
*
|
||||||
|
* This file is part of llvm-mingw.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__MINGW32__)
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char buf[10];
|
||||||
|
char padding[10];
|
||||||
|
|
||||||
|
const char *ten_chars = "1234567890";
|
||||||
|
int ten = 10;
|
||||||
|
const char *eleven_chars = "1234567890!";
|
||||||
|
int eleven = 11;
|
||||||
|
|
||||||
|
const char *foo = "foo";
|
||||||
|
const char *barbar = "barbar";
|
||||||
|
const char *barbarr = "barbarr";
|
||||||
|
const char *barbarrr = "barbarrr";
|
||||||
|
int six = 6;
|
||||||
|
int seven = 7;
|
||||||
|
int eight = 8;
|
||||||
|
|
||||||
|
char hash = '#';
|
||||||
|
|
||||||
|
#if !defined(__GLIBC__) && !defined(__MINGW32__)
|
||||||
|
#define mempcpy memcpy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void acceptable_use(void) {
|
||||||
|
memcpy(buf, ten_chars, ten);
|
||||||
|
memmove(buf, ten_chars, ten);
|
||||||
|
mempcpy(buf, ten_chars, ten);
|
||||||
|
memset(buf, hash, ten);
|
||||||
|
|
||||||
|
// Test writing a full buffer without null termination.
|
||||||
|
strncpy(buf, eleven_chars, ten);
|
||||||
|
|
||||||
|
strcpy(buf, foo);
|
||||||
|
strcat(buf, barbar);
|
||||||
|
|
||||||
|
strcpy(buf, foo);
|
||||||
|
// We copy a truncated amount from the source, and fit exactly in the
|
||||||
|
// buffer.
|
||||||
|
strncat(buf, barbarrr, six);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
#ifndef _FORTIFY_SOURCE
|
||||||
|
fprintf(stderr, "NOTE, this is built without _FORTIFY_SOURCE; the "
|
||||||
|
"checks will fail!\n");
|
||||||
|
#endif
|
||||||
|
if (argc < 2) {
|
||||||
|
acceptable_use();
|
||||||
|
fprintf(stderr, "%s: A test tool for detecting buffer overflows.\n"
|
||||||
|
"Run this with an integer between 1 and 10 to test "
|
||||||
|
"various overflows that should be caught.\n", argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
switch (atoi(argv[1])) {
|
||||||
|
default:
|
||||||
|
case 1:
|
||||||
|
memcpy(buf, eleven_chars, eleven);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
memmove(buf, eleven_chars, eleven);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mempcpy(buf, eleven_chars, eleven);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
memset(buf, hash, eleven);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// The contents of the string fits in the buffer, but the null
|
||||||
|
// terminator doesn't.
|
||||||
|
strcpy(buf, ten_chars);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
// The contents of the string doesn't fit in the buffer.
|
||||||
|
strncpy(buf, eleven_chars, eleven);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
strcpy(buf, foo);
|
||||||
|
// The contents of the string fits in the buffer, but the null
|
||||||
|
// terminator doesn't.
|
||||||
|
strcat(buf, barbarr);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
strcpy(buf, foo);
|
||||||
|
// The contents of the string doesn't fit in the buffer.
|
||||||
|
strcat(buf, barbarrr);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
strcpy(buf, foo);
|
||||||
|
// We copy a truncated amount from the source, but the null terminator
|
||||||
|
// doesn't fit in the buffer.
|
||||||
|
strncat(buf, barbarrr, seven);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
strcpy(buf, foo);
|
||||||
|
// The contents of the string doesn't fit in the buffer.
|
||||||
|
strncat(buf, barbarrr, eight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user