Skip to content

Instantly share code, notes, and snippets.

@DavidKorczynski
Created May 23, 2024 19:40
Show Gist options
  • Save DavidKorczynski/bc386b88eab43931338971cff4d4655b to your computer and use it in GitHub Desktop.
Save DavidKorczynski/bc386b88eab43931338971cff4d4655b to your computer and use it in GitHub Desktop.
OSS-Fuzz-gen prompts
The following are examples of prompts and harness pairs as generated by OSS-Fuzz-gen
(https://github.com/google/oss-fuzz-gen) and in particular the experimental feature:
- https://github.com/google/oss-fuzz-gen/tree/main/experimental/c-cpp
###################################
############# nanovsg #############
###################################
### Target: https://github.com/memononen/nanosvg
### Prompt begin
Hi, please write a fuzz harness for me.
The target project is https://github.com/memononen/nanosvg which is a open source project written in C. The harness you write should be in pure C as well.
I would like for you to write the harness targeting the function `NSVGimage * nsvgParse(char *, const char *, float).`
The source code for the function is: ```NSVGimage* nsvgParse(char* input, const char* units, float dpi)
{
NSVGparser* p;
NSVGimage* ret = 0;
p = nsvg__createParser();
if (p == NULL) {
return NULL;
}
p->dpi = dpi;
nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p);
// Create gradients after all definitions have been parsed
nsvg__createGradients(p);
// Scale to viewBox
nsvg__scaleToViewbox(p, units);
ret = p->image;
p->image = NULL;
nsvg__deleteParser(p);
return ret;
}```
The harness should be in libFuzzer style, with the code wrapped in `int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)`. Specifically, do not include `extern "C"` in the fuzzer code.
Please wrap all code in <code> tags and you should include nothing else but the code in your reply. Do not include any other text.
Make sure the ensure strings passed to the target are null-terminated.
There is one rule that your harness must satisfy: all of the header files in this library is {'stb_image_write.h', 'nanosvgrast.h', 'nanosvg.h'}. Make sure to not include any header files not in this list.
Finally, the types of types function are:
- Argument 1 is of type "char *"
- Argument 2 is of type "const char *"
- Argument 3 is of type "float"
You must make sure the arguments passed to the function match the types of the function. Do this by casting appropriately.
The most important part of the harness is that it will build and compile correctly against the target code. Please focus on making the code as simple as possible in order to secure it can be build.
The target function is used by several other functions in the module. Use these as reference on how to call the target function correctly:
Example cross reference from function NSVGimage * nsvgParseFromFile(const char *, const char *, float) and the source code of the function that calls into our target function is:
```c
NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
{
FILE* fp = NULL;
size_t size;
char* data = NULL;
NSVGimage* image = NULL;
fp = fopen(filename, "rb");
if (!fp) goto error;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
data = (char*)malloc(size+1);
if (data == NULL) goto error;
if (fread(data, 1, size, fp) != size) goto error;
data[size] = '\0'; // Must be null terminated.
fclose(fp);
image = nsvgParse(data, units, dpi);
free(data);
return image;
error:
if (fp) fclose(fp);
if (data) free(data);
if (image) nsvgDelete(image);
return NULL;
}
```
### Prompt end
### Harness generated
// Heuristic: FuzzerGenHeuristic6 :: Target: nsvgParse
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "stb_image_write.h"
#include "nanosvgrast.h"
#include "nanosvg.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Prepare input data
char* input = (char*)malloc(size + 1);
memcpy(input, data, size);
input[size] = '\0'; // Must be null terminated
const char* units = "px";
float dpi = 96.0f;
// Call target function
NSVGimage* image = nsvgParse(input, units, dpi);
// Cleanup
if (input) free(input);
if (image) nsvgDelete(image);
return 0;
}
### Harness end
####################################
############# Tinyexpr #############
####################################
### Target: https://github.com/codeplea/tinyexpr
### Prompt begin
Hi, please write a fuzz harness for me.
The target project is https://github.com/codeplea/tinyexpr which is a open source project written in C. The harness you write should be in pure C as well.
I would like for you to write the harness targeting the function `double te_interp(const char *, int *).`
The source code for the function is: ```double te_interp(const char *expression, int *error) {
te_expr *n = te_compile(expression, 0, 0, error);
double ret;
if (n) {
ret = te_eval(n);
te_free(n);
} else {
ret = NAN;
}
return ret;```
The harness should be in libFuzzer style, with the code wrapped in `int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)`. Specifically, do not include `extern "C"` in the fuzzer code.
Please wrap all code in <code> tags and you should include nothing else but the code in your reply. Do not include any other text.
Make sure the ensure strings passed to the target are null-terminated.
There is one rule that your harness must satisfy: all of the header files in this library is {'minctest.h', 'tinyexpr.h'}. Make sure to not include any header files not in this list.
Finally, the types of types function are:
- Argument 1 is of type "const char *"
- Argument 2 is of type "int *"
You must make sure the arguments passed to the function match the types of the function. Do this by casting appropriately.
The most important part of the harness is that it will build and compile correctly against the target code. Please focus on making the code as simple as possible in order to secure it can be build.
The target function is used by several other functions in the module. Use these as reference on how to call the target function correctly:
Example cross reference from function int eval(const char *) and the source code of the function that calls into our target function is:
```c
static int eval(const char *str) {
int err = 0;
double r = te_interp(str, &err);
if (err != 0) {
printf("Error at position %i\n", err);
return -1;
} else {
printf("%g\n", r);
return 0;
}
}
```
Example cross reference from function void test_combinatorics() and the source code of the function that calls into our target function is:
```c
void test_combinatorics() {
test_case cases[] = {
{"fac(0)", 1},
{"fac(0.2)", 1},
{"fac(1)", 1},
{"fac(2)", 2},
{"fac(3)", 6},
{"fac(4.8)", 24},
{"fac(10)", 3628800},
{"ncr(0,0)", 1},
{"ncr(10,1)", 10},
{"ncr(10,0)", 1},
{"ncr(10,10)", 1},
{"ncr(16,7)", 11440},
{"ncr(16,9)", 11440},
{"ncr(100,95)", 75287520},
{"npr(0,0)", 1},
{"npr(10,1)", 10},
{"npr(10,0)", 1},
{"npr(10,10)", 3628800},
{"npr(20,5)", 1860480},
{"npr(100,4)", 94109400},
};
int i;
for (i = 0; i < sizeof(cases) / sizeof(test_case); ++i) {
const char *expr = cases[i].expr;
const double answer = cases[i].answer;
int err;
const double ev = te_interp(expr, &err);
lok(!err);
lfequal(ev, answer);
if (err) {
printf("FAILED: %s (%d)\n", expr, err);
}
}
}
```
Example cross reference from function void test_infs() and the source code of the function that calls into our target function is:
```c
void test_infs() {
const char *infs[] = {
"1/0",
"log(0)",
"pow(2,10000000)",
"fac(300)",
"ncr(300,100)",
"ncr(300000,100)",
"ncr(300000,100)*8",
"npr(3,2)*ncr(300000,100)",
"npr(100,90)",
"npr(30,25)",
};
int i;
for (i = 0; i < sizeof(infs) / sizeof(const char *); ++i) {
const char *expr = infs[i];
int err;
const double r = te_interp(expr, &err);
lequal(err, 0);
lok(r == r + 1);
te_expr *n = te_compile(expr, 0, 0, &err);
lok(n);
lequal(err, 0);
const double c = te_eval(n);
lok(c == c + 1);
te_free(n);
}
}
```
Example cross reference from function void test_nans() and the source code of the function that calls into our target function is:
```c
void test_nans() {
const char *nans[] = {
"0/0",
"1%0",
"1%(1%0)",
"(1%0)%1",
"fac(-1)",
"ncr(2, 4)",
"ncr(-2, 4)",
"ncr(2, -4)",
"npr(2, 4)",
"npr(-2, 4)",
"npr(2, -4)",
};
int i;
for (i = 0; i < sizeof(nans) / sizeof(const char *); ++i) {
const char *expr = nans[i];
int err;
const double r = te_interp(expr, &err);
lequal(err, 0);
lok(r != r);
te_expr *n = te_compile(expr, 0, 0, &err);
lok(n);
lequal(err, 0);
const double c = te_eval(n);
lok(c != c);
te_free(n);
}
}
```
### Prompt end
### Harness generated
// Heuristic: FuzzerGenHeuristic6 :: Target: te_interp
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "minctest.h"
#include "tinyexpr.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size == 0) {
return 0;
}
char *expression = (char *)malloc(size + 1);
if (!expression) {
return 0;
}
memcpy(expression, data, size);
expression[size] = '\0'; // Ensure null-terminated string
int error;
double result = te_interp(expression, &error);
free(expression);
return 0;
}
##########################################
############# Lorawan-parser #############
##########################################
### Target: https://github.com/JiapengLi/lorawan-parser
### Prompt begin
Hi, please write a fuzz harness for me.
The target project is https://github.com/JiapengLi/lorawan-parser which is a open source project written in C. The harness you write should be in pure C as well.
I would like for you to write the harness targeting the function `bool json_validate(const char *).`
The source code for the function is: ```bool json_validate(const char *json)
{
const char *s = json;
skip_space(&s);
if (!parse_value(&s, NULL))
return false;
skip_space(&s);
if (*s != 0)
return false;
return true;
}```
The harness should be in libFuzzer style, with the code wrapped in `int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)`. Specifically, do not include `extern "C"` in the fuzzer code.
Please wrap all code in <code> tags and you should include nothing else but the code in your reply. Do not include any other text.
Make sure the ensure strings passed to the target are null-terminated.
There is one rule that your harness must satisfy: all of the header files in this library is {'app.h', 'base64.h', 'config.h', 'conf.h', 'json.h', 'parson.h', 'aes.h', 'loragw_radio.h', 'str2hex.h', 'version.h', 'pktfwd.h', 'cmac.h', 'log.h', 'loragw_lbt.h', 'loragw_sx125x.h', 'loragw_aux.h', 'lw-macro.h', 'netutil.h', 'loragw_spi.h', 'loragw_sx1272_lora.h', 'lw.h', 'loragw_gps.h', 'lw-log.h', 'loragw_sx1276_lora.h', 'loragw_fpga.h', 'loragw_hal.h', 'loragw_sx1272_fsk.h', 'loragw_reg.h', 'loragw_sx1276_fsk.h'}. Make sure to not include any header files not in this list.
Finally, the types of types function are:
- Argument 1 is of type "const char *"
You must make sure the arguments passed to the function match the types of the function. Do this by casting appropriately.
The most important part of the harness is that it will build and compile correctly against the target code. Please focus on making the code as simple as possible in order to secure it can be build.
### Prompt end
### Harness generated
// Heuristic: FuzzerGenHeuristic6 :: Target: json_validate
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include "json.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size == 0) {
return 0;
}
// Null-terminated input string
char* input = (char*)malloc(size + 1);
if (input == NULL) {
return 0;
}
memcpy(input, data, size);
input[size] = '\0';
// Fuzzing the json_validate function
json_validate((const char *)input);
free(input);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment