Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added context struct #43

Merged
merged 9 commits into from
Dec 18, 2024
Merged

Added context struct #43

merged 9 commits into from
Dec 18, 2024

Conversation

zevv
Copy link
Owner

@zevv zevv commented Dec 10, 2024

This change allows a program to create multiple instances of the zforth interpreter and virtual machine: moves all the globals from zforth.c to a new struct zf_ctx and adds the zf_ctx *ctx argument to all zforth functions.

This does result in a bit larger binary size.

interpreter to be exist at the same time.
@zevv zevv merged commit 4c23228 into master Dec 18, 2024
1 check passed
}


/* Include files from command line */

for(i=0; i<argc; i++) {
include(argv[i]);
include(ctx, argv[i]);

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This argument to a file access function is derived from
user input (a command-line argument)
and then passed to include(fname), which calls fopen(__filename).

Copilot Autofix AI 17 days ago

To fix the problem, we need to validate the user input before using it to construct a file path. Specifically, we should ensure that the file path provided by the user does not contain any path separators or ".." sequences, which could lead to path traversal vulnerabilities. We can achieve this by adding a validation function that checks for these invalid sequences and rejects the input if any are found.

Suggested changeset 1
src/linux/main.c

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/linux/main.c b/src/linux/main.c
--- a/src/linux/main.c
+++ b/src/linux/main.c
@@ -270,2 +270,6 @@
 	for(i=0; i<argc; i++) {
+		if (strstr(argv[i], "..") || strchr(argv[i], '/') || strchr(argv[i], '\\')) {
+			fprintf(stderr, "Invalid file path: %s\n", argv[i]);
+			continue;
+		}
 		include(ctx, argv[i]);
EOF
@@ -270,2 +270,6 @@
for(i=0; i<argc; i++) {
if (strstr(argv[i], "..") || strchr(argv[i], '/') || strchr(argv[i], '\\')) {
fprintf(stderr, "Invalid file path: %s\n", argv[i]);
continue;
}
include(ctx, argv[i]);
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
if(code <= PRIM_COUNT) {
do_prim((zf_prim)code, input);
if(code < PRIM_COUNT) {
do_prim(ctx, (zf_prim)code, input);

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This argument to a file access function is derived from
user input (string read by fgets)
and then passed to do_prim(input), which calls zf_host_sys(input), which calls include(fname), which calls fopen(__filename).

Copilot Autofix AI 17 days ago

To fix the problem, we need to validate the user input before it is used to construct a file path. Specifically, we should ensure that the input does not contain any path separators or ".." sequences that could lead to path traversal attacks. This can be done by adding a validation function that checks for these invalid sequences and rejects the input if any are found.

  1. Add a validation function to check for invalid sequences in the user input.
  2. Use this validation function in the include function in src/linux/main.c before calling fopen.
  3. Ensure that the input parameter in the run function in src/zforth/zforth.c is validated before it is used.
Suggested changeset 2
src/zforth/zforth.c

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/zforth/zforth.c b/src/zforth/zforth.c
--- a/src/zforth/zforth.c
+++ b/src/zforth/zforth.c
@@ -452,2 +452,8 @@
 {
+	// Validate the input
+	if (input && (strstr(input, "..") || strchr(input, '/') || strchr(input, '\\'))) {
+		fprintf(stderr, "Invalid input.\n");
+		return;
+	}
+
 	while(ctx->ip != 0) {
EOF
@@ -452,2 +452,8 @@
{
// Validate the input
if (input && (strstr(input, "..") || strchr(input, '/') || strchr(input, '\\'))) {
fprintf(stderr, "Invalid input.\n");
return;
}

while(ctx->ip != 0) {
src/linux/main.c
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/linux/main.c b/src/linux/main.c
--- a/src/linux/main.c
+++ b/src/linux/main.c
@@ -62,2 +62,8 @@
 
+	// Validate the filename
+	if (strstr(fname, "..") || strchr(fname, '/') || strchr(fname, '\\')) {
+		fprintf(stderr, "Invalid filename.\n");
+		return;
+	}
+
 	FILE *f = fopen(fname, "rb");
EOF
@@ -62,2 +62,8 @@

// Validate the filename
if (strstr(fname, "..") || strchr(fname, '/') || strchr(fname, '\\')) {
fprintf(stderr, "Invalid filename.\n");
return;
}

FILE *f = fopen(fname, "rb");
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
* definition as a literal. At run time, the value will be pushed
* on the stack. */
if(COMPILING(ctx)) dict_add_lit(ctx, zf_pop(ctx));
/* FIXME: else abort "!compiling"? */

Check notice

Code scanning / CodeQL

FIXME comment Note

FIXME comment: else abort "!compiling"?
break;

case PRIM_EXIT:
ip = zf_popr();
/* Return from word */
ctx->ip = zf_popr(ctx);

Check warning

Code scanning / CodeQL

Lossy function result cast Warning

Return value of type float is implicitly converted to unsigned int.
zf_push(peek(addr, &d1, len));
/* Get length of cell; consumes size encoding and address */
size = zf_pop(ctx);
addr = zf_pop(ctx);

Check warning

Code scanning / CodeQL

Lossy function result cast Warning

Return value of type float is implicitly converted to unsigned int.
zf_push(d1);
/* Peek at memory; consumes size encoding and address */
size = zf_pop(ctx);
addr = zf_pop(ctx);

Check warning

Code scanning / CodeQL

Lossy function result cast Warning

Return value of type float is implicitly converted to unsigned int.
d1 = zf_pop();
/* Poke memory; consumes size encoding, address, and value */
size = zf_pop(ctx);
addr = zf_pop(ctx);

Check warning

Code scanning / CodeQL

Lossy function result cast Warning

Return value of type float is implicitly converted to unsigned int.
addr = zf_pop();
zf_push(zf_pick(addr));
/* Pick n-th element from stack */
addr = zf_pop(ctx);

Check warning

Code scanning / CodeQL

Lossy function result cast Warning

Return value of type float is implicitly converted to unsigned int.
addr = zf_pop();
zf_push(zf_pickr(addr));
/* Pick n-th element from return stack */
addr = zf_pop(ctx);

Check warning

Code scanning / CodeQL

Lossy function result cast Warning

Return value of type float is implicitly converted to unsigned int.
break;

case PRIM_EQUAL:
zf_push(zf_pop() == zf_pop());
/* Push true if top two elements on stack are equal, else false */
zf_push(ctx, zf_pop(ctx) == zf_pop(ctx) ? ZF_TRUE : ZF_FALSE);

Check notice

Code scanning / CodeQL

Equality test on floating-point values Note

Equality checks on floating point values can yield unexpected results.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants