1
0
Fork 0
forked from fun/fun

Some small injection fixes. (0.42.2)

This commit is contained in:
Johannes Findeisen 2026-06-14 22:09:49 +02:00
commit 1b90493a7a
4 changed files with 42 additions and 7 deletions

View file

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10)
project(fun VERSION 0.42.1 LANGUAGES C)
project(fun VERSION 0.42.2 LANGUAGES C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
@ -521,7 +521,7 @@ install(DIRECTORY lib/
# Optionally install example scripts
option(FUN_INSTALL_EXAMPLES "Install example .fun scripts" ON)
if(FUN_INSTALL_EXAMPLES)
install(DIRECTORY examples/
install(DIRECTORY examples/
DESTINATION /usr/share/fun/examples
FILES_MATCHING PATTERN "*.fun"
)

View file

@ -142,11 +142,26 @@ int main(int argc, char **argv) {
}
char *joined = (char *)malloc(total);
if (joined) {
joined[0] = '\0';
size_t off = 0;
for (int i = 0; i < sargc; ++i) {
strcat(joined, argv[sargi + i]);
if (i + 1 < sargc) strcat(joined, " ");
int written = snprintf(joined + off, (off < total ? total - off : 0),
"%s%s",
argv[sargi + i],
(i + 1 < sargc) ? " " : "");
if (written < 0) { /* encoding error */
off = total; /* force stop */
break;
}
size_t w = (size_t)written;
if (off + w >= total) { /* ensure we don't advance beyond buffer */
off = total ? total - 1 : 0;
joined[off] = '\0';
break;
}
off += w;
}
/* Ensure NUL termination even if loop didn't run */
if (total > 0) joined[(off < total) ? off : (total - 1)] = '\0';
setenv("FUN_ARGS", joined, 1);
free(joined);
}

View file

@ -259,14 +259,16 @@ static int complete_load_path(char *buf, size_t *len_io) {
if (slash) {
size_t dlen = (size_t)(slash - expanded);
if (dlen == 0) {
strcpy(dirpart, "/");
/* use bounded copy to avoid potential overflow (even though "/" fits) */
snprintf(dirpart, sizeof(dirpart), "%s", "/");
} else {
memcpy(dirpart, expanded, dlen);
dirpart[dlen] = '\0';
}
snprintf(base, sizeof(base), "%s", slash + 1);
} else {
strcpy(dirpart, ".");
/* use bounded copy to avoid potential overflow (even though "." fits) */
snprintf(dirpart, sizeof(dirpart), "%s", ".");
snprintf(base, sizeof(base), "%s", expanded);
}

View file

@ -27,6 +27,24 @@ case OP_PROC_SYSTEM: {
push_value(vm, make_int(-1));
break;
}
/* Security hardening: reject commands containing shell metacharacters or control chars
to reduce risk of command injection when using system(3). This preserves simple
command execution like "ls -l" but blocks dangerous constructs like pipes, redirects,
command substitution, etc. */
const char *bad = "&;|$<>`\\\"'()*?[]{}~";
int unsafe = 0;
for (const unsigned char *p = (const unsigned char *)cmd; *p; ++p) {
if (*p < 0x20 || strchr(bad, (int)*p)) { /* control or meta */
unsafe = 1;
break;
}
}
if (unsafe) {
/* refuse to execute potentially unsafe shell command */
push_value(vm, make_int(-1));
free(cmd);
break;
}
int status = system(cmd);
int code = -1;
#ifdef __unix__