Merge branch 'spa_encoding_fuzzing'
This commit is contained in:
@@ -135,6 +135,20 @@ if test "x$want_profile_coverage" = "xyes"; then
|
||||
FKO_CHECK_COMPILER_ARG_LDFLAGS_ONLY([-lgcov])
|
||||
fi
|
||||
|
||||
dnl Decide whether or not to compile in certain features that enable fuzzing
|
||||
dnl of fwknop code - this is for testing purposes only.
|
||||
dnl
|
||||
want_fuzzing_interfaces=no
|
||||
AC_ARG_ENABLE([fuzzing-interfaces],
|
||||
[AS_HELP_STRING([--enable-fuzzing-interfaces],
|
||||
[Build fwknop binaries with support for fuzzing interfaces @<:@default is to disable@:>@])],
|
||||
[want_fuzzing_interfaces=$enableval],
|
||||
[])
|
||||
|
||||
if test "x$want_fuzzing_interfaces" = "xyes"; then
|
||||
AC_DEFINE([FUZZING_INTERFACES], [1], [Define for fuzzing interfaces support])
|
||||
fi
|
||||
|
||||
dnl Decide whether or not to enable all warnings with -Wall
|
||||
dnl
|
||||
use_wall=yes
|
||||
|
||||
@@ -381,6 +381,10 @@ DLL_API int fko_set_spa_hmac(fko_ctx_t ctx, const char * const hmac_key,
|
||||
DLL_API int fko_get_spa_hmac(fko_ctx_t ctx, char **enc_data);
|
||||
|
||||
DLL_API int fko_get_encoded_data(fko_ctx_t ctx, char **enc_data);
|
||||
#if FUZZING_INTERFACES
|
||||
DLL_API int fko_set_encoded_data(fko_ctx_t ctx, const char * const encoded_msg,
|
||||
const int msg_len, const int do_digest, const int digest_type);
|
||||
#endif
|
||||
|
||||
/* Get context data functions
|
||||
*/
|
||||
|
||||
@@ -241,4 +241,76 @@ fko_get_encoded_data(fko_ctx_t ctx, char **enc_msg)
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
/* Set the fko SPA encoded data (this is a convenience
|
||||
* function mostly used for tests that involve fuzzing).
|
||||
*/
|
||||
#if FUZZING_INTERFACES
|
||||
int
|
||||
fko_set_encoded_data(fko_ctx_t ctx,
|
||||
const char * const encoded_msg, const int msg_len,
|
||||
const int require_digest, const int digest_type)
|
||||
{
|
||||
char *tbuf = NULL;
|
||||
int res = FKO_SUCCESS, mlen;
|
||||
|
||||
/* Must be initialized
|
||||
*/
|
||||
if(!CTX_INITIALIZED(ctx))
|
||||
return(FKO_ERROR_CTX_NOT_INITIALIZED);
|
||||
|
||||
if(encoded_msg == NULL)
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
ctx->encoded_msg = strdup(encoded_msg);
|
||||
|
||||
ctx->state |= FKO_DATA_MODIFIED;
|
||||
|
||||
if(ctx->encoded_msg == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
/* allow arbitrary length (i.e. let the decode routines validate
|
||||
* SPA message length).
|
||||
*/
|
||||
ctx->encoded_msg_len = msg_len;
|
||||
|
||||
if(require_digest)
|
||||
{
|
||||
fko_set_spa_digest_type(ctx, digest_type);
|
||||
if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
/* append the digest to the encoded message buffer
|
||||
*/
|
||||
mlen = ctx->encoded_msg_len + ctx->digest_len + 2;
|
||||
tbuf = calloc(1, mlen);
|
||||
if(tbuf == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
/* memcpy since the provided encoded buffer might
|
||||
* have an embedded NULL?
|
||||
*/
|
||||
mlen = snprintf(tbuf, mlen, "%s:%s", ctx->encoded_msg, ctx->digest);
|
||||
|
||||
if(ctx->encoded_msg != NULL)
|
||||
free(ctx->encoded_msg);
|
||||
|
||||
ctx->encoded_msg = strdup(tbuf);
|
||||
if(ctx->encoded_msg == NULL)
|
||||
{
|
||||
free(tbuf);
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
}
|
||||
|
||||
ctx->encoded_msg_len = mlen;
|
||||
free(tbuf);
|
||||
}
|
||||
|
||||
FKO_CLEAR_SPA_DATA_MODIFIED(ctx);
|
||||
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***EOF***/
|
||||
|
||||
Binary file not shown.
@@ -2,5 +2,8 @@
|
||||
all : fko_wrapper.c
|
||||
gcc -Wall -g -I../../lib fko_wrapper.c -o fko_wrapper -L../../lib/.libs -lfko
|
||||
|
||||
fuzzing: fko_wrapper.c
|
||||
gcc -Wall -g -DFUZZING_INTERFACES -I../../lib fko_wrapper.c -o fko_wrapper -L../../lib/.libs -lfko
|
||||
|
||||
clean:
|
||||
rm -f fko_wrapper
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "fko.h"
|
||||
|
||||
#define ENABLE_GPG_TESTS 0
|
||||
@@ -23,12 +24,20 @@
|
||||
#define NO_DIGEST 0
|
||||
#define DO_DIGEST 1
|
||||
#define RAW_DIGEST 2
|
||||
#define MAX_LINE_LEN 3000 /* really long for fuzzing tests */
|
||||
#define ENC_KEY "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /* 32 bytes */
|
||||
#define HMAC_KEY "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" /* 32 bytes */
|
||||
|
||||
#define IS_EMPTY_LINE(x) ( \
|
||||
x == '#' || x == '\n' || x == '\r' || x == ';' || x == '\0' \
|
||||
)
|
||||
|
||||
static void display_ctx(fko_ctx_t ctx);
|
||||
static void test_loop(int new_ctx_flag, int destroy_ctx_flag);
|
||||
static void test_loop_compounded(void);
|
||||
#if FUZZING_INTERFACES
|
||||
static void spa_encoded_msg_fuzzing(void);
|
||||
#endif
|
||||
static void ctx_update(fko_ctx_t *ctx, int new_ctx_flag,
|
||||
int destroy_ctx_flag, int print_flag);
|
||||
static void spa_default_ctx(fko_ctx_t *ctx);
|
||||
@@ -67,9 +76,90 @@ int main(void) {
|
||||
printf("[+] Total libfko function calls (after compounded tests): %d\n\n",
|
||||
spa_calls);
|
||||
|
||||
#if FUZZING_INTERFACES
|
||||
printf("[+] libfko fuzzing by setting SPA buffer manually...\n");
|
||||
spa_encoded_msg_fuzzing();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if FUZZING_INTERFACES
|
||||
static void
|
||||
spa_encoded_msg_fuzzing(void)
|
||||
{
|
||||
fko_ctx_t decode_ctx = NULL;
|
||||
int res = 0, pkt_id, require_success, require_digest, digest_type, msg_len;
|
||||
int line_ctr = 0, spa_payload_ctr = 0;
|
||||
FILE *fz = NULL;
|
||||
char line[MAX_LINE_LEN] = {0};
|
||||
char b64_encoded_msg[MAX_LINE_LEN] = {0};
|
||||
unsigned char b64_decoded_msg[MAX_LINE_LEN] = {0};
|
||||
|
||||
/* fuzzing file contents (or from stdin) are formatted like this:
|
||||
*
|
||||
* <pkt_ID> <status: success|fail> <digest: yes|no> <digest type> <base64_SPA_payload>
|
||||
*/
|
||||
|
||||
if ((fz = fopen("fuzz_spa_payloads", "r")) == NULL)
|
||||
return;
|
||||
|
||||
while ((fgets(line, MAX_LINE_LEN, fz)) != NULL)
|
||||
{
|
||||
line_ctr++;
|
||||
line[MAX_LINE_LEN-1] = '\0';
|
||||
|
||||
if (line[strlen(line)-1] == '\n')
|
||||
line[strlen(line)-1] = '\0';
|
||||
|
||||
if(IS_EMPTY_LINE(line[0]))
|
||||
continue;
|
||||
|
||||
if(sscanf(line, "%d %d %d %d %s", &pkt_id, &require_success,
|
||||
&require_digest, &digest_type, b64_encoded_msg) != 5)
|
||||
{
|
||||
printf("[+] fuzzing parsing error at line: %d\n", line_ctr);
|
||||
continue;
|
||||
}
|
||||
|
||||
msg_len = fko_base64_decode(b64_encoded_msg, b64_decoded_msg);
|
||||
|
||||
spa_payload_ctr++;
|
||||
|
||||
fko_new(&decode_ctx);
|
||||
|
||||
if ((res = fko_set_encoded_data(decode_ctx, (char *) b64_decoded_msg,
|
||||
msg_len, require_digest, digest_type)) != FKO_SUCCESS) {
|
||||
printf("[-] pkt_id: %d, fko_set_encoded_data(): %s\n", pkt_id, fko_errstr(res));
|
||||
}
|
||||
|
||||
res = fko_decode_spa_data(decode_ctx);
|
||||
if (require_success) {
|
||||
if (res != FKO_SUCCESS) {
|
||||
printf("[-] pkt_id: %d, expected decode success but: fko_decode_spa_data(): %s\n",
|
||||
pkt_id, fko_errstr(res));
|
||||
}
|
||||
} else {
|
||||
if (res == FKO_SUCCESS) {
|
||||
printf("[-] pkt_id: %d, expected decode failure but: fko_decode_spa_data(): %s\n",
|
||||
pkt_id, fko_errstr(res));
|
||||
}
|
||||
}
|
||||
|
||||
fko_destroy(decode_ctx);
|
||||
|
||||
memset(line, 0x0, MAX_LINE_LEN);
|
||||
memset(b64_encoded_msg, 0x0, MAX_LINE_LEN);
|
||||
}
|
||||
|
||||
fclose(fz);
|
||||
|
||||
printf("[+] Sent %d SPA payloads through libfko encode/decode cycle...\n",
|
||||
spa_payload_ctr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_loop_compounded(void)
|
||||
{
|
||||
|
||||
Executable
+253
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Purpose: This script generates SPA packet payloads that are designed to
|
||||
# act as fuzzer against libfko SPA decoding routines.
|
||||
#
|
||||
# Fuzzing file format:
|
||||
#
|
||||
# <pkt_ID> <status: success|fail> <digest: yes|no> <digest type> <base64_SPA_payload>
|
||||
#
|
||||
# SPA payload format (before:
|
||||
#
|
||||
# <rand_num>:<user>:<timestamp>:<version>:<spa_msg_type>:<access_request
|
||||
#
|
||||
# Example SPA payload (after inner base64 encoding):
|
||||
#
|
||||
# 1716411011200157:cm9vdA:1397329899:2.0.1:1:MTI3LjAuMC4yLHRjcC8yMw
|
||||
#
|
||||
|
||||
import base64
|
||||
import argparse
|
||||
|
||||
### a few constants
|
||||
spa_success = 1
|
||||
spa_failure = 0
|
||||
spa_sha256 = 3
|
||||
do_digest = 1
|
||||
no_digest = 0
|
||||
|
||||
def main():
|
||||
|
||||
args = parse_cmdline()
|
||||
|
||||
print_hdr()
|
||||
|
||||
spa_payloads = [
|
||||
"1716411011200157:cm9vdA:1397329899:2.0.1:1:MTI3LjAuMC4yLHRjcC8yMw",
|
||||
"1716411011200157:cm9vdA:1397329899:2.0.1:1:MTI3LjAuMC4yLHRjcC8yMw:cGFzc3dk",
|
||||
"3145808919615481:cm9vdA:1397329998:2.0.1:0:MTI3LjAuMC4yLGVjaG8gZndrbm9wdGVzdCA+IC90bXAvZndrbm9wdGVzdA",
|
||||
"1642197848921959:cm9vdA:1397329740:2.0.1:2:MTI3LjAuMC4yLHRjcC8yMg:MTkyLjE2OC4xLjIsMjI",
|
||||
"1548062350109656:cm9vdA:1397330450:2.0.1:3:MTI3LjAuMC4yLHRjcC8yMg:2",
|
||||
"1414212790438062:cm9vdA:1397329054:2.0.1:4:MTI3LjAuMC4yLHRjcC8yMg:MTkyLjE2OC4xMC4xLDEyMzQ1:1234",
|
||||
"3184260168681452:c29tZXVzZXI:1397330288:2.0.1:4:MS4xLjEuMSx0Y3AvMjI:MS4yLjMuNCwxMjM0:10:GboVlHuyiwjxmHbH16vGvlKF",
|
||||
"8148229791462660:cm9vdA:1397331007:2.0.1:5:MTI3LjAuMC4yLHRjcC8zNzE3Mg:MTI3LjAuMC4xLDIy",
|
||||
"1918702109191551:cm9vdA:1397329052:2.0.1:6:MTI3LjAuMC4yLHRjcC8yMg:MTI3LjAuMC4xLDIy:1234"
|
||||
]
|
||||
|
||||
pkt_id = 1
|
||||
payload_num = 0
|
||||
|
||||
for spa_payload in spa_payloads:
|
||||
|
||||
payload_num += 1
|
||||
|
||||
print "# start tests with payload: ", spa_payload + "\n" \
|
||||
"# base64 encoded original payload:", base64.b64encode(spa_payload)
|
||||
|
||||
### fuzz individual payload fields
|
||||
pkt_id = field_fuzzing(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### valid payload tests - all digest types
|
||||
pkt_id = valid_payloads(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### invalid digest types
|
||||
pkt_id = invalid_digest_types(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### truncated lengths
|
||||
pkt_id = truncated_lengths(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### remove chunks of chars out of the original SPA payload
|
||||
pkt_id = rm_chunks(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### SPA payloads that are too long
|
||||
pkt_id = append_data_to_end(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### additional embedded ':' chars
|
||||
pkt_id = embedded_separators(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
### non-ascii char tests
|
||||
pkt_id = embedded_chars(args, spa_payload, payload_num, pkt_id)
|
||||
|
||||
return
|
||||
|
||||
def field_fuzzing(args, spa_payload, payload_num, pkt_id):
|
||||
repl_start = 0
|
||||
repl_end = 0
|
||||
field_num = 0
|
||||
for idx in range(0, len(spa_payload)):
|
||||
if spa_payload[idx] == ':' or idx == len(spa_payload)-1:
|
||||
field_num += 1
|
||||
if repl_end > 0:
|
||||
orig_field = spa_payload[repl_end+1:idx]
|
||||
else:
|
||||
orig_field = spa_payload[repl_end:idx]
|
||||
|
||||
repl_start = repl_end
|
||||
repl_end = idx
|
||||
|
||||
### now generate fuzzing data for this field
|
||||
for c in range(0, 3) + range(33, 47) + range(65, 67) + range(127, 130) + range(252, 256):
|
||||
for l in [1, 2, 3, 4, 5, 6, 10, 14, 15, 16, 17, 24, 31, 32, 33, \
|
||||
63, 64, 127, 128, 129, 150, 220, 230, 254, 255, 256, 257, 258]:
|
||||
|
||||
fuzzing_field = ''
|
||||
require_b64 = orig_field.isdigit()
|
||||
|
||||
for n in range(0, l):
|
||||
fuzzing_field += chr(c)
|
||||
|
||||
new_payloads = [
|
||||
spa_payload[:repl_start], ### for payloads without original field
|
||||
spa_payload[:repl_start], ### prepend fuzzing field with original
|
||||
spa_payload[:repl_start] ### append fuzzing field to original
|
||||
]
|
||||
|
||||
if field_num > 1:
|
||||
for i in range(0, len(new_payloads)):
|
||||
new_payloads[i] += ':'
|
||||
|
||||
if idx == len(spa_payload)-1:
|
||||
field_variants(new_payloads, fuzzing_field, orig_field, require_b64)
|
||||
else:
|
||||
if field_num == 1 or field_num in range(3, 6):
|
||||
### fields: rand val, time stamp, version, and SPA type
|
||||
field_variants(new_payloads, fuzzing_field, orig_field, False)
|
||||
elif field_num == 2: ### user field
|
||||
field_variants(new_payloads, fuzzing_field, orig_field, True)
|
||||
else:
|
||||
field_variants(new_payloads, fuzzing_field, orig_field, require_b64)
|
||||
|
||||
for i in range(0, len(new_payloads)):
|
||||
new_payloads[i] += spa_payload[repl_end:]
|
||||
|
||||
for s in new_payloads:
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(s)
|
||||
pkt_id += 1
|
||||
|
||||
return pkt_id
|
||||
|
||||
def field_variants(new_payloads, fuzzing_field, orig_field, require_b64):
|
||||
if require_b64:
|
||||
decoded_orig_field = spa_base64_decode(orig_field)
|
||||
new_payloads[0] += base64.b64encode(fuzzing_field)
|
||||
new_payloads[1] += base64.b64encode(fuzzing_field+decoded_orig_field)
|
||||
new_payloads[2] += base64.b64encode(decoded_orig_field+fuzzing_field)
|
||||
else:
|
||||
new_payloads[0] += fuzzing_field
|
||||
new_payloads[1] += fuzzing_field+orig_field
|
||||
new_payloads[2] += orig_field+fuzzing_field
|
||||
return
|
||||
|
||||
def spa_base64_decode(b64str):
|
||||
### account for how fwknop strips '=' chars
|
||||
remainder = len(b64str) % 4
|
||||
if remainder != 0:
|
||||
for i in range(0, remainder):
|
||||
b64str += '='
|
||||
|
||||
return base64.b64decode(b64str)
|
||||
|
||||
def valid_payloads(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " valid payload + valid digest types..."
|
||||
for digest_type in range(0, 6):
|
||||
print str(pkt_id), str(spa_success), str(do_digest), \
|
||||
str(digest_type), base64.b64encode(spa_payload)
|
||||
pkt_id += 1
|
||||
return pkt_id
|
||||
|
||||
def invalid_digest_types(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " invalid digest types..."
|
||||
for digest_type in [-1, 6, 7]:
|
||||
print str(pkt_id), str(spa_success), str(do_digest), \
|
||||
str(digest_type), base64.b64encode(spa_payload)
|
||||
pkt_id += 1
|
||||
return pkt_id
|
||||
|
||||
def truncated_lengths(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " truncated lengths..."
|
||||
for l in range(1, len(spa_payload)):
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(spa_payload[:l])
|
||||
pkt_id += 1
|
||||
for l in range(1, len(spa_payload)):
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(spa_payload[l:])
|
||||
pkt_id += 1
|
||||
|
||||
return pkt_id
|
||||
|
||||
def rm_chunks(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " splice blocks of chars..."
|
||||
for bl in range(1, 20):
|
||||
for l in range(0, len(spa_payload)):
|
||||
new_payload = spa_payload[:l] + spa_payload[l+bl:]
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(new_payload)
|
||||
pkt_id += 1
|
||||
return pkt_id
|
||||
|
||||
def append_data_to_end(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " payloads too long..."
|
||||
for l in [1, 10, 50, 127, 128, 129, 200, 399, \
|
||||
400, 401, 500, 800, 1000, 1023, 1024, 1025, \
|
||||
1200, 1499, 1500, 1501, 2000]:
|
||||
for non_ascii in range(0, 5) + range(127, 130) + range(252, 256):
|
||||
new_payload = spa_payload
|
||||
for p in range(0, l):
|
||||
new_payload += chr(non_ascii)
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(new_payload)
|
||||
pkt_id += 1
|
||||
return pkt_id
|
||||
|
||||
def embedded_separators(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " additional embedded : chars..."
|
||||
for pos in range(0, len(spa_payload)):
|
||||
if spa_payload[pos] == ':':
|
||||
continue
|
||||
new_payload = list(spa_payload)
|
||||
new_payload[pos] = ':'
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(''.join(new_payload))
|
||||
pkt_id += 1
|
||||
return pkt_id
|
||||
|
||||
def embedded_chars(args, spa_payload, payload_num, pkt_id):
|
||||
print "# payload " + str(payload_num) + " non-ascii char tests..."
|
||||
for pos in range(0, len(spa_payload)):
|
||||
for non_ascii in range(0, 31) + range(44, 48) + range(127, 131) + range(253, 255):
|
||||
new_payload = list(spa_payload)
|
||||
new_payload[pos] = chr(non_ascii)
|
||||
### write out the fuzzing line
|
||||
print str(pkt_id), str(spa_failure), str(do_digest), \
|
||||
str(spa_sha256), base64.b64encode(''.join(new_payload))
|
||||
pkt_id += 1
|
||||
return pkt_id
|
||||
|
||||
def print_hdr():
|
||||
print "# <pkt_ID> <status: success|fail> <digest: yes|no> <digest type> <base64_SPA_payload>"
|
||||
return
|
||||
|
||||
def parse_cmdline():
|
||||
|
||||
### parse command line args
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument("-c", "--max-packet-count", type=int, help="packet count", default=1000000)
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+62
-86
@@ -28,6 +28,7 @@ my $data_tmp = 'data.tmp';
|
||||
my $key_tmp = 'key.tmp';
|
||||
my $enc_save_tmp = 'openssl_save.enc';
|
||||
my $test_suite_path = 'test-fwknop.pl';
|
||||
my $username = '';
|
||||
my $gpg_dir_orig_tar = 'gpg_dirs_orig.tar.gz';
|
||||
our $gpg_client_home_dir = "$conf_dir/client-gpg";
|
||||
our $gpg_client_home_dir_no_pw = "$conf_dir/client-gpg-no-pw";
|
||||
@@ -322,6 +323,7 @@ my $perl_libfko_constants_file = '../perl/FKO/lib/FKO_Constants.pl';
|
||||
my $python_libfko_constants_file = '../python/fko.py';
|
||||
my $fko_wrapper_dir = 'fko-wrapper';
|
||||
my $python_spa_packet = '';
|
||||
my $enable_fuzzing_interfaces_tests = 0;
|
||||
my $enable_client_ip_resolve_test = 0;
|
||||
my $enable_all = 0;
|
||||
my $saved_last_results = 0;
|
||||
@@ -431,6 +433,7 @@ exit 1 unless GetOptions(
|
||||
'valgrind-disable-suppressions' => \$valgrind_disable_suppressions,
|
||||
'valgrind-disable-child-silent' => \$valgrind_disable_child_silent,
|
||||
'enable-all' => \$enable_all,
|
||||
'enable-fuzzing-interfaces-tests' => \$enable_fuzzing_interfaces_tests,
|
||||
'valgrind-path=s' => \$valgrind_path,
|
||||
'valgrind-suppression-file' => \$valgrind_suppressions_file,
|
||||
### can set the following to "output.last/valgrind-coverage" if
|
||||
@@ -789,13 +792,6 @@ if ($enable_profile_coverage_check) {
|
||||
}
|
||||
|
||||
if ($enable_valgrind) {
|
||||
&run_test({
|
||||
'category' => 'valgrind',
|
||||
'subcategory' => 'fko-wrapper',
|
||||
'detail' => 'multiple libfko calls',
|
||||
'function' => \&compile_execute_fko_wrapper}
|
||||
);
|
||||
|
||||
&run_test({
|
||||
'category' => 'valgrind output',
|
||||
'subcategory' => 'flagged functions',
|
||||
@@ -1123,6 +1119,15 @@ sub compile_warnings() {
|
||||
|
||||
my $curr_pwd = cwd() or die $!;
|
||||
|
||||
if ($enable_profile_coverage_check) {
|
||||
### we're recompiling, so remove any existing profile coverage
|
||||
### files since they will be invalidated by the recompile
|
||||
for my $extension ('*.gcno', '*.gcda', '*.gcov') {
|
||||
### remove profile output from any previous run
|
||||
system qq{find .. -name $extension | xargs rm 2> /dev/null};
|
||||
}
|
||||
}
|
||||
|
||||
chdir '..' or die $!;
|
||||
|
||||
### 'make clean' as root
|
||||
@@ -1133,10 +1138,6 @@ sub compile_warnings() {
|
||||
}
|
||||
|
||||
if ($sudo_path) {
|
||||
my $username = getpwuid((stat("test/$test_suite_path"))[4]);
|
||||
die "[*] Could not determine test/$test_suite_path owner"
|
||||
unless $username;
|
||||
|
||||
unless (&run_cmd("$sudo_path -u $username make",
|
||||
$cmd_out_tmp, "test/$curr_test_file")) {
|
||||
unless (&run_cmd('make', $cmd_out_tmp,
|
||||
@@ -1220,6 +1221,13 @@ sub profile_coverage() {
|
||||
$cmd_out_tmp, $curr_test_file);
|
||||
}
|
||||
|
||||
if ($username) {
|
||||
for my $extension ('*.gcno', '*.gcda', '*.gcov') {
|
||||
### remove profile output from any previous run
|
||||
system qq{find .. -name $extension | xargs chown $username};
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5993,6 +6001,12 @@ sub init() {
|
||||
$git_path = &find_command('git') unless $git_path;
|
||||
$perl_path = &find_command('perl') unless $perl_path;
|
||||
|
||||
if ($sudo_path) {
|
||||
$username = getpwuid((stat($test_suite_path))[4]);
|
||||
die "[*] Could not determine $test_suite_path owner"
|
||||
unless $username;
|
||||
}
|
||||
|
||||
### On Mac OS X look for otool instead of ldd
|
||||
unless ($lib_view_cmd) {
|
||||
$lib_view_cmd = &find_command('otool');
|
||||
@@ -6015,18 +6029,11 @@ sub init() {
|
||||
|
||||
if ($gcov_path) {
|
||||
if ($enable_profile_coverage_check
|
||||
and not $preserve_previous_coverage_files
|
||||
and not $list_mode) {
|
||||
if ($profile_coverage_init) {
|
||||
print "[+] --profile-coverage-init mode, ",
|
||||
"removing existing .gcda, .gcno, and .gcov files...\n";
|
||||
}
|
||||
for my $extension ('*.gcno', '*.gcda', '*.gcov') {
|
||||
### remove profile output from any previous run
|
||||
system qq{find .. -name $extension | xargs rm 2> /dev/null};
|
||||
}
|
||||
if ($profile_coverage_init) {
|
||||
print "[+] Recompiling fwknop...\n";
|
||||
print "[+] Recompiling fwknop and removing previous coverage files...\n";
|
||||
### if we recompile then remove the .gcno files (which are
|
||||
### generated at compile time)
|
||||
&compile_warnings();
|
||||
if (&file_find_regex([qr/profile\-arcs.*test\-coverage/],
|
||||
$MATCH_ALL, $APPEND_RESULTS, $curr_test_file)) {
|
||||
@@ -6250,8 +6257,7 @@ sub import_previous_valgrind_coverage_info() {
|
||||
return;
|
||||
}
|
||||
|
||||
sub compile_execute_fko_wrapper() {
|
||||
my $rv = 1;
|
||||
sub compile_wrapper() {
|
||||
|
||||
unless (-d $fko_wrapper_dir) {
|
||||
&write_test_file("[-] fko wrapper directory " .
|
||||
@@ -6268,14 +6274,13 @@ sub compile_execute_fko_wrapper() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($sudo_path) {
|
||||
my $username = getpwuid((stat("../$test_suite_path"))[4]);
|
||||
die "[*] Could not determine ../$test_suite_path owner"
|
||||
unless $username;
|
||||
my $make_str = 'make';
|
||||
$make_str .= ' fuzzing' if $enable_fuzzing_interfaces_tests;
|
||||
|
||||
unless (&run_cmd("$sudo_path -u $username make",
|
||||
if ($sudo_path) {
|
||||
unless (&run_cmd("$sudo_path -u $username $make_str",
|
||||
"../$cmd_out_tmp", "../$curr_test_file")) {
|
||||
unless (&run_cmd('make', "../$cmd_out_tmp",
|
||||
unless (&run_cmd($make_str, "../$cmd_out_tmp",
|
||||
"../$curr_test_file")) {
|
||||
chdir '..' or die $!;
|
||||
return 0;
|
||||
@@ -6284,7 +6289,7 @@ sub compile_execute_fko_wrapper() {
|
||||
|
||||
} else {
|
||||
|
||||
unless (&run_cmd('make', "../$cmd_out_tmp",
|
||||
unless (&run_cmd($make_str, "../$cmd_out_tmp",
|
||||
"../$curr_test_file")) {
|
||||
chdir '..' or die $!;
|
||||
return 0;
|
||||
@@ -6298,74 +6303,45 @@ sub compile_execute_fko_wrapper() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
&run_cmd('./run_valgrind.sh', "../$cmd_out_tmp", "../$curr_test_file");
|
||||
|
||||
$rv = 0 unless &file_find_regex([qr/no\sleaks\sare\spossible/],
|
||||
$MATCH_ALL, $APPEND_RESULTS, "../$curr_test_file");
|
||||
|
||||
chdir '..' or die $!;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub compile_execute_fko_wrapper() {
|
||||
|
||||
my $rv = &compile_wrapper();
|
||||
|
||||
if ($rv) {
|
||||
|
||||
chdir $fko_wrapper_dir or die $!;
|
||||
&run_cmd('./run_valgrind.sh', "../$cmd_out_tmp", "../$curr_test_file");
|
||||
|
||||
$rv = 0 unless &file_find_regex([qr/no\sleaks\sare\spossible/],
|
||||
$MATCH_ALL, $APPEND_RESULTS, "../$curr_test_file");
|
||||
|
||||
chdir '..' or die $!;
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
sub compile_execute_fko_wrapper_no_valgrind() {
|
||||
my $rv = 1;
|
||||
|
||||
unless (-d $fko_wrapper_dir) {
|
||||
&write_test_file("[-] fko wrapper directory " .
|
||||
"$fko_wrapper_dir does not exist.\n", $curr_test_file);
|
||||
return 0;
|
||||
}
|
||||
my $rv = &compile_wrapper();
|
||||
|
||||
chdir $fko_wrapper_dir or die $!;
|
||||
if ($rv) {
|
||||
|
||||
chdir $fko_wrapper_dir or die $!;
|
||||
&run_cmd('./run_no_valgrind.sh', "../$cmd_out_tmp", "../$curr_test_file");
|
||||
|
||||
### 'make clean' as root
|
||||
unless (&run_cmd('make clean', "../$cmd_out_tmp",
|
||||
"../$curr_test_file")) {
|
||||
chdir '..' or die $!;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($sudo_path) {
|
||||
my $username = getpwuid((stat("../$test_suite_path"))[4]);
|
||||
die "[*] Could not determine ../$test_suite_path owner"
|
||||
unless $username;
|
||||
|
||||
unless (&run_cmd("$sudo_path -u $username make",
|
||||
"../$cmd_out_tmp", "../$curr_test_file")) {
|
||||
unless (&run_cmd('make', "../$cmd_out_tmp",
|
||||
"../$curr_test_file")) {
|
||||
chdir '..' or die $!;
|
||||
return 0;
|
||||
}
|
||||
if (&file_find_regex([qr/segmentation\sfault/i, qr/core\sdumped/i],
|
||||
$MATCH_ANY, $NO_APPEND_RESULTS, $curr_test_file)) {
|
||||
&write_test_file("[-] crash message found in: $curr_test_file\n",
|
||||
$curr_test_file);
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
unless (&run_cmd('make', "../$cmd_out_tmp",
|
||||
"../$curr_test_file")) {
|
||||
chdir '..' or die $!;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unless (-e 'fko_wrapper' and -e 'run_no_valgrind.sh') {
|
||||
&write_test_file("[-] fko_wrapper or run_valgrind.sh does not exist.\n",
|
||||
"../$curr_test_file");
|
||||
chdir '..' or die $!;
|
||||
return 0;
|
||||
}
|
||||
|
||||
&run_cmd('./run_no_valgrind.sh',
|
||||
"../$cmd_out_tmp", "../$curr_test_file");
|
||||
|
||||
chdir '..' or die $!;
|
||||
|
||||
if (&file_find_regex([qr/segmentation\sfault/i, qr/core\sdumped/i],
|
||||
$MATCH_ANY, $NO_APPEND_RESULTS, $curr_test_file)) {
|
||||
&write_test_file("[-] crash message found in: $curr_test_file\n",
|
||||
$curr_test_file);
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
return $rv;
|
||||
|
||||
Reference in New Issue
Block a user