mirror of
https://github.com/hohn/codeql-workshop-dataflow-c.git
synced 2025-12-16 02:33:03 +01:00
114 lines
3.7 KiB
C
114 lines
3.7 KiB
C
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);
|
|
} |