mirror of
https://github.com/hohn/codeql-workshop-dataflow-c.git
synced 2025-12-16 10:33:04 +01:00
Initial commit
This commit is contained in:
103
tests-common/test_part1.c
Normal file
103
tests-common/test_part1.c
Normal file
@@ -0,0 +1,103 @@
|
||||
typedef unsigned long size_t;
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
int printf(const char *format, ...);
|
||||
|
||||
#define DYN_INPUT_TYPE_NONE 0x0
|
||||
#define DYN_INPUT_TYPE_MEM 0x1
|
||||
#define DYN_INPUT_TYPE_VAL 0x2
|
||||
|
||||
typedef union dyn_input {
|
||||
int val;
|
||||
struct {
|
||||
void *buf;
|
||||
size_t size;
|
||||
} ptr;
|
||||
} dyn_input_t;
|
||||
|
||||
/**
|
||||
* A helper function which returns a packed unsigned integer value representing
|
||||
* a dynamic input type, where `p0` is the type of the first input and `p1` is
|
||||
* the type of the second input.
|
||||
*/
|
||||
unsigned int DYN_INPUT_TYPE(unsigned int p0, unsigned int p1) {
|
||||
return ((p0) | ((p1) << 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions called from entrypoints that receive and process dynamic inputs.
|
||||
*/
|
||||
void copy_mem_nested(dyn_input_t *input) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // path-dependent
|
||||
}
|
||||
|
||||
int copy_mem(unsigned int unused, dyn_input_t *input,
|
||||
unsigned int input_types) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - type not checked
|
||||
copy_mem_nested(input); // NON_COMPLIANT - type not checked
|
||||
|
||||
if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
|
||||
}
|
||||
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - guard doesn't control all paths
|
||||
copy_mem_nested(input); // NON_COMPLIANT - guard doesn't control all paths
|
||||
|
||||
if (DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM) == 100) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - useless type check
|
||||
}
|
||||
|
||||
if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // COMPLIANT - type checked
|
||||
copy_mem_nested(input); // COMPLIANT - type checked
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_val(dyn_input_t *input, unsigned int input_types) {
|
||||
if (input_types == DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_NONE)) {
|
||||
printf("%d", input[0].val++); // COMPLIANT - type checked
|
||||
printf("%d", input[0].val++); // COMPLIANT - type checked
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%d", input[0].val++); // NON_COMPLIANT - type not checked
|
||||
printf("%d", input[0].val++); // NON_COMPLIANT - type not checked
|
||||
return 1;
|
||||
}
|
||||
|
||||
int write_val_to_mem(dyn_input_t *input, unsigned int input_types) {
|
||||
if (input_types == DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_MEM)) {
|
||||
memcpy(input[1].ptr.buf, &input[0].val,
|
||||
sizeof(input[0].val)); // COMPLIANT - type checked
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(input[1].ptr.buf, &input[0].val,
|
||||
sizeof(input[0].val)); // NON_COMPLIANT - type not checked
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entrypoints that have the following parameters:
|
||||
* 1. An array, `input`, of two dyn_input_t dynamic inputs
|
||||
* 2. An unsigned int, `input_types`, describing the type of each input to be
|
||||
* compared against `DYN_INPUT_TYPE`.
|
||||
*/
|
||||
int EP_copy_mem(dyn_input_t input[2], unsigned int input_types) {
|
||||
return copy_mem(0, input, input_types);
|
||||
}
|
||||
|
||||
int EP_print_val(dyn_input_t input[2], unsigned int input_types) {
|
||||
return print_val(input, input_types);
|
||||
}
|
||||
|
||||
int EP_write_val_to_mem(dyn_input_t input[2], unsigned int input_types) {
|
||||
return write_val_to_mem(input, input_types);
|
||||
}
|
||||
114
tests-common/test_part2.c
Normal file
114
tests-common/test_part2.c
Normal file
@@ -0,0 +1,114 @@
|
||||
typedef unsigned long size_t;
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
int printf(const char *format, ...);
|
||||
|
||||
#define DYN_INPUT_TYPE_NONE 0x0
|
||||
#define DYN_INPUT_TYPE_MEM 0x1
|
||||
#define DYN_INPUT_TYPE_VAL 0x2
|
||||
|
||||
typedef union dyn_input {
|
||||
int val;
|
||||
struct {
|
||||
void *buf;
|
||||
size_t size;
|
||||
} ptr;
|
||||
} dyn_input_t;
|
||||
|
||||
dyn_input_t *lock_input(const dyn_input_t *input);
|
||||
|
||||
/**
|
||||
* A helper function which returns a packed unsigned integer value representing
|
||||
* a dynamic input type, where `p0` is the type of the first input and `p1` is
|
||||
* the type of the second input.
|
||||
*/
|
||||
unsigned int DYN_INPUT_TYPE(unsigned int p0, unsigned int p1) {
|
||||
return ((p0) | ((p1) << 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions called from entrypoints that receive and process dynamic inputs.
|
||||
*/
|
||||
void copy_mem_nested(dyn_input_t *input) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // path-dependent
|
||||
}
|
||||
|
||||
int copy_mem(unsigned int unused, dyn_input_t *input,
|
||||
unsigned int input_types) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - type not checked
|
||||
copy_mem_nested(input); // NON_COMPLIANT - type not checked
|
||||
|
||||
if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
|
||||
}
|
||||
|
||||
input = lock_input(input);
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - guard doesn't control all paths
|
||||
copy_mem_nested(input); // NON_COMPLIANT - guard doesn't control all paths
|
||||
|
||||
if (DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM) == 100) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - invalid type check
|
||||
} else if (DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_MEM) ==
|
||||
input_types) {
|
||||
copy_mem_nested(input); // NON_COMPLIANT - mismatched type for input[0]
|
||||
}
|
||||
|
||||
if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
|
||||
// valid fail-fast type check
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // COMPLIANT - type checked
|
||||
copy_mem_nested(input); // COMPLIANT - type checked
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_val(dyn_input_t *input, unsigned int input_types) {
|
||||
if (input_types == DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_NONE)) {
|
||||
printf("%d", input[0].val++); // COMPLIANT - type checked
|
||||
printf("%d", input[0].val++); // COMPLIANT - type checked
|
||||
printf("%zu", input[0].ptr.size); // NON_COMPLIANT - mismatched type
|
||||
copy_mem_nested(input); // NON_COMPLIANT - mismatched type
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%d", input[0].val++); // NON_COMPLIANT - type not checked
|
||||
printf("%d", input[0].val++); // NON_COMPLIANT - type not checked
|
||||
return 1;
|
||||
}
|
||||
|
||||
int write_val_to_mem(dyn_input_t *input, unsigned int input_types) {
|
||||
if (input_types == DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_MEM)) {
|
||||
memcpy(input[1].ptr.buf, &input[0].val,
|
||||
sizeof(input[0].val)); // COMPLIANT - type checked
|
||||
(void)(*(
|
||||
unsigned char *)(input[0].ptr.buf)); // NON_COMPLIANT - mismatched type
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(input[1].ptr.buf, &input[0].val,
|
||||
sizeof(input[0].val)); // NON_COMPLIANT - type not checked
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entrypoints that have the following parameters:
|
||||
* 1. An array, `input`, of two dyn_input_t dynamic inputs
|
||||
* 2. An unsigned int, `input_types`, describing the type of each input to be
|
||||
* compared against `DYN_INPUT_TYPE`.
|
||||
*/
|
||||
int EP_copy_mem(dyn_input_t input[2], unsigned int input_types) {
|
||||
return copy_mem(0, input, input_types);
|
||||
}
|
||||
|
||||
int EP_print_val(dyn_input_t input[2], unsigned int input_types) {
|
||||
return print_val(input, input_types);
|
||||
}
|
||||
|
||||
int EP_write_val_to_mem(dyn_input_t input[2], unsigned int input_types) {
|
||||
return write_val_to_mem(input, input_types);
|
||||
}
|
||||
114
tests-common/test_part3.c
Normal file
114
tests-common/test_part3.c
Normal file
@@ -0,0 +1,114 @@
|
||||
typedef unsigned long size_t;
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
int printf(const char *format, ...);
|
||||
|
||||
#define DYN_INPUT_TYPE_NONE 0x0
|
||||
#define DYN_INPUT_TYPE_MEM 0x1
|
||||
#define DYN_INPUT_TYPE_VAL 0x2
|
||||
|
||||
typedef union dyn_input {
|
||||
int val;
|
||||
struct {
|
||||
void *buf;
|
||||
size_t size;
|
||||
} ptr;
|
||||
} dyn_input_t;
|
||||
|
||||
dyn_input_t *lock_input(const dyn_input_t *input);
|
||||
|
||||
/**
|
||||
* A helper function which returns a packed unsigned integer value representing
|
||||
* a dynamic input type, where `p0` is the type of the first input and `p1` is
|
||||
* the type of the second input.
|
||||
*/
|
||||
unsigned int DYN_INPUT_TYPE(unsigned int p0, unsigned int p1) {
|
||||
return ((p0) | ((p1) << 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions called from entrypoints that receive and process dynamic inputs.
|
||||
*/
|
||||
void copy_mem_nested(dyn_input_t *input) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // path-dependent
|
||||
}
|
||||
|
||||
int copy_mem(unsigned int unused, dyn_input_t *input,
|
||||
unsigned int input_types) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - type not checked
|
||||
copy_mem_nested(input); // NON_COMPLIANT - type not checked
|
||||
|
||||
if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
|
||||
}
|
||||
|
||||
input = lock_input(input);
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - guard doesn't control all paths
|
||||
copy_mem_nested(input); // NON_COMPLIANT - guard doesn't control all paths
|
||||
|
||||
if (DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM) == 100) {
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // NON_COMPLIANT - invalid type check
|
||||
} else if (DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_MEM) ==
|
||||
input_types) {
|
||||
copy_mem_nested(input); // NON_COMPLIANT - mismatched type for input[0]
|
||||
}
|
||||
|
||||
if (input_types != DYN_INPUT_TYPE(DYN_INPUT_TYPE_MEM, DYN_INPUT_TYPE_MEM)) {
|
||||
// valid fail-fast type check
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(input[0].ptr.buf, input[1].ptr.buf,
|
||||
input[1].ptr.size); // COMPLIANT - type checked
|
||||
copy_mem_nested(input); // COMPLIANT - type checked
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_val(dyn_input_t *input, unsigned int input_types) {
|
||||
if (input_types == DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_NONE)) {
|
||||
printf("%d", input[0].val++); // COMPLIANT - type checked
|
||||
printf("%d", input[0].val++); // COMPLIANT - type checked
|
||||
printf("%zu", input[0].ptr.size); // NON_COMPLIANT - mismatched type
|
||||
copy_mem_nested(input); // NON_COMPLIANT - mismatched type
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("%d", input[0].val++); // NON_COMPLIANT - type not checked
|
||||
printf("%d", input[0].val++); // NON_COMPLIANT - type not checked
|
||||
return 1;
|
||||
}
|
||||
|
||||
int write_val_to_mem(dyn_input_t *input, unsigned int input_types) {
|
||||
if (input_types == DYN_INPUT_TYPE(DYN_INPUT_TYPE_VAL, DYN_INPUT_TYPE_MEM)) {
|
||||
memcpy(input[1].ptr.buf, &input[0].val,
|
||||
sizeof(input[0].val)); // COMPLIANT - type checked
|
||||
(void)(*(
|
||||
unsigned char *)(input[0].ptr.buf)); // NON_COMPLIANT - mismatched type
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(input[1].ptr.buf, &input[0].val,
|
||||
sizeof(input[0].val)); // NON_COMPLIANT - type not checked
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entrypoints that have the following parameters:
|
||||
* 1. An array, `input`, of two dyn_input_t dynamic inputs
|
||||
* 2. An unsigned int, `input_types`, describing the type of each input to be
|
||||
* compared against `DYN_INPUT_TYPE`.
|
||||
*/
|
||||
int EP_copy_mem(dyn_input_t input[2], unsigned int input_types) {
|
||||
return copy_mem(0, input, input_types);
|
||||
}
|
||||
|
||||
int EP_print_val(dyn_input_t input[2], unsigned int input_types) {
|
||||
return print_val(input, input_types);
|
||||
}
|
||||
|
||||
int EP_write_val_to_mem(dyn_input_t input[2], unsigned int input_types) {
|
||||
return write_val_to_mem(input, input_types);
|
||||
}
|
||||
Reference in New Issue
Block a user