Verified Commit dccd2929 authored by Camil Staps's avatar Camil Staps 🚀

Add runtime checks for usage of file I/O instructions

parent be4520fb
......@@ -29,8 +29,9 @@ from StdMaybe import :: Maybe
* expressions. You may also use {{`defaultDeserializationSettings`}}.
*/
:: DeserializationSettings =
{ heap_size :: !Int //* Heap size for the interpreter, in bytes (default: 2M)
, stack_size :: !Int //* Stack size for the interpreter, in bytes (default: 1M in total; 500k for A and 500k for BC stack)
{ heap_size :: !Int //* Heap size for the interpreter, in bytes (default: 2M)
, stack_size :: !Int //* Stack size for the interpreter, in bytes (default: 1M in total; 500k for A and 500k for BC stack)
, file_io :: !Bool //* Whether file I/O is allowed (default: False)
}
defaultDeserializationSettings :: DeserializationSettings
......@@ -94,6 +95,8 @@ deserialize :: !DeserializationSettings !SerializedGraph !String !*World -> *(!M
//* The ABC instruction `halt` was encountered.
| DV_IllegalInstruction
//* A forbidden (ccall, etc.) or unknown ABC instruction was encountered.
| DV_FileIOAttempted
//* File I/O was attempted while the interpreter was started with file_io=False.
| DV_HostHeapFull
//* The heap of the host application has not enough space to copy the result.
......
......@@ -20,6 +20,7 @@ defaultDeserializationSettings :: DeserializationSettings
defaultDeserializationSettings =
{ heap_size = 2 << 20
, stack_size = (512 << 10) * 2
, file_io = False
}
:: *SerializedGraph =
......@@ -104,7 +105,7 @@ deserialize` strict dsets {graph,descinfo,modules,bytecode} thisexe w
pgm
heap dsets.heap_size stack dsets.stack_size
asp bsp csp heap
strict
strict dsets.file_io
# graph = replace_desc_numbers_by_descs 0 graph int_syms 0 0
# graph_node = string_to_interpreter graph ie_settings
#! (ie,_) = make_finalizer ie_settings
......@@ -188,7 +189,7 @@ get_start_rule_as_expression dsets filename prog w
pgm
heap dsets.heap_size stack dsets.stack_size
asp bsp csp heap
False
False dsets.file_io
# start_node = build_start_node ie_settings
#! (ie,_) = make_finalizer ie_settings
# ie = {ie_finalizer=ie, ie_snode_ptr=0, ie_snodes=create_array_ 1}
......@@ -198,9 +199,9 @@ get_start_rule_as_expression dsets filename prog w
// it to the finalizer_list anyway. This is just to ensure that the first
// call to interpret gets the right argument.
build_interpretation_environment :: !Pointer !Pointer !Int !Pointer !Int !Pointer !Pointer !Pointer !Pointer !Bool -> Pointer
build_interpretation_environment pgm heap hsize stack ssize asp bsp csp hp strict = code {
ccall build_interpretation_environment "ppIpIppppI:p"
build_interpretation_environment :: !Pointer !Pointer !Int !Pointer !Int !Pointer !Pointer !Pointer !Pointer !Bool !Bool -> Pointer
build_interpretation_environment pgm heap hsize stack ssize asp bsp csp hp strict file_io = code {
ccall build_interpretation_environment "ppIpIppppII:p"
}
build_start_node :: !Pointer -> Pointer
......
......@@ -52,7 +52,7 @@ struct interpretation_environment *build_interpretation_environment(
struct program *program,
BC_WORD *heap, BC_WORD heap_size, BC_WORD *stack, BC_WORD stack_size,
BC_WORD *asp, BC_WORD *bsp, BC_WORD *csp, BC_WORD *hp,
int hyperstrict) {
int hyperstrict, int allow_file_io) {
struct interpretation_environment *ie = safe_malloc(sizeof(struct interpretation_environment));
ie->host = safe_malloc(sizeof(struct host_status));
ie->program = program;
......@@ -68,7 +68,8 @@ struct interpretation_environment *build_interpretation_environment(
ie->caf_list[0] = 0;
ie->caf_list[1] = &ie->caf_list[1];
ie->options.in_first_semispace=1;
ie->options.hyperstrict=hyperstrict != 0;
ie->options.hyperstrict=hyperstrict!=0;
ie->options.allow_file_io=allow_file_io!=0;
#if DEBUG_CLEAN_LINKS > 0
EPRINTF("Building interpretation_environment %p\n",ie);
#endif
......
......@@ -344,9 +344,11 @@ int ensure_interpreter_init(void) {
#ifdef COMPUTED_GOTOS
/* Fetch label addresses */
if (instruction_labels[0]==NULL) {
interpret(NULL,
# ifdef LINK_CLEAN_RUNTIME
0,
interpret(NULL, 0,
# else
struct interpretation_options options;
interpret(NULL, options,
# endif
NULL, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL);
......@@ -383,6 +385,7 @@ int interpret(
int create_restore_point,
#else
struct program *program,
struct interpretation_options options,
#endif
BC_WORD *stack, size_t stack_size,
BC_WORD *heap, size_t heap_size,
......@@ -414,8 +417,6 @@ int interpret(
int instr_arg; /* for jsr_eval_host_node_n */
#else
void *caf_list[2] = {0, &caf_list[1]};
struct interpretation_options options;
options.in_first_semispace=1;
#endif
BC_WORD *pc;
......@@ -565,9 +566,9 @@ eval_to_hnf_return_failure:
#ifndef LINK_CLEAN_RUNTIME
# if defined(DEBUG_CURSES) || defined(COMPUTED_GOTOS)
const char usage[] = "Usage: %s [-h SIZE] [-s SIZE] FILE\n";
const char usage[] = "Usage: %s [-io] [-h SIZE] [-s SIZE] FILE\n";
# else
const char usage[] = "Usage: %s [-l] [-R] [-h SIZE] [-s SIZE] FILE\n";
const char usage[] = "Usage: %s [-l] [-R] [-io] [-h SIZE] [-s SIZE] FILE\n";
# endif
int main(int argc, char **argv) {
......@@ -579,6 +580,10 @@ int main(int argc, char **argv) {
size_t stack_size = (512 << 10) * 2;
size_t heap_size = 2 << 20;
struct interpretation_options options;
options.in_first_semispace=1;
options.allow_file_io=0;
BC_WORD *stack;
BC_WORD *heap;
......@@ -607,6 +612,8 @@ int main(int argc, char **argv) {
EPRINTF(usage, argv[0]);
EXIT(NULL,-1);
}
} else if (!strcmp(argv[i],"-io")) {
options.allow_file_io=1;
} else if (input) {
EPRINTF(usage, argv[0]);
EXIT(NULL,-1);
......@@ -655,6 +662,7 @@ int main(int argc, char **argv) {
#endif
interpret(state.program,
options,
stack, stack_size,
heap, heap_size,
asp, bsp, csp,
......
......@@ -4,6 +4,7 @@
struct interpretation_options {
int in_first_semispace:1;
int allow_file_io:1;
#ifdef LINK_CLEAN_RUNTIME
int hyperstrict:1;
#endif
......@@ -49,6 +50,7 @@ extern void *e__ABC_PInterpreter__dDV__HeapFull;
extern void *e__ABC_PInterpreter__dDV__StackOverflow;
extern void *e__ABC_PInterpreter__dDV__Halt;
extern void *e__ABC_PInterpreter__dDV__IllegalInstruction;
extern void *e__ABC_PInterpreter__dDV__FileIOAttempted;
extern void *e__ABC_PInterpreter__dDV__SegmentationFault;
extern void *e__ABC_PInterpreter__dDV__HostHeapFull;
extern void *e__ABC_PInterpreter__kDV__Ok;
......@@ -112,6 +114,7 @@ int interpret(
int create_restore_point,
#else
struct program *program,
struct interpretation_options options,
#endif
BC_WORD *stack, size_t stack_size,
BC_WORD *heap, size_t heap_size,
......
......@@ -84,6 +84,7 @@ instr_RtoAC t = foldl (flip append) t
instr_closeF :: !Target -> Target
instr_closeF t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "pc++;"
, "struct file *f=(struct file*)bsp[1];"
, "bsp++;"
......@@ -104,6 +105,7 @@ instr_closeF t = foldl (flip append) t
instr_endF :: !Target -> Target
instr_endF t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "pc++;"
, "struct file *f=(struct file*)bsp[1];"
, "FILE *h;"
......@@ -126,6 +128,7 @@ instr_endF t = foldl (flip append) t
instr_errorF :: !Target -> Target
instr_errorF t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "pc++;"
, "struct file *f=(struct file*)bsp[1];"
, "if (f==&clean_stdinout)"
......@@ -140,6 +143,7 @@ instr_errorF t = foldl (flip append) t
instr_openF :: !Target -> Target
instr_openF t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "pc++;"
, "struct file *f=safe_malloc(sizeof(struct file));"
, "BC_WORD *clean_file_name=(BC_WORD*)asp[0];"
......@@ -169,6 +173,7 @@ instr_openF t = foldl (flip append) t
instr_readFC :: !Target -> Target
instr_readFC t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "pc++;"
, "struct file *f=(struct file*)bsp[1];"
, "bsp-=2;"
......@@ -187,6 +192,7 @@ instr_readFC t = foldl (flip append) t
instr_readLineF :: !Target -> Target
instr_readLineF t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "struct file *f=(struct file*)bsp[1];"
, "if (f==&clean_stdinout) {"
, "\thp[0]=(BC_WORD)&__STRING__+2;"
......@@ -224,7 +230,8 @@ instr_readLineF t = foldl (flip append) t
instr_stdioF :: !Target -> Target
instr_stdioF t = foldl (flip append) t
[ "if (stdio_open)"
[ "CHECK_FILE_IO;"
, "if (stdio_open)"
, "\tIO_error(\"stdio: already open\");"
, "pc+=1;"
, "stdio_open=1;"
......@@ -236,6 +243,7 @@ instr_stdioF t = foldl (flip append) t
instr_writeFC :: !Target -> Target
instr_writeFC t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "pc++;"
, "char c=*bsp++;"
, "struct file *f=(struct file*)bsp[1];"
......@@ -251,6 +259,7 @@ instr_writeFC t = foldl (flip append) t
instr_writeFS :: !Target -> Target
instr_writeFS t = foldl (flip append) t
[ "{"
, "CHECK_FILE_IO;"
, "struct file *f=(struct file*)bsp[1];"
, "BC_WORD *n=(BC_WORD*)asp[0];"
, "int len=n[1];"
......
......@@ -43,6 +43,22 @@ where
, "#endif"
, "#define NEED_HEAP(words) {if ((heap_free-=words)<0){ heap_free+=words; GARBAGE_COLLECT;}}"
, "#ifdef LINK_CLEAN_RUNTIME"
, "# define CHECK_FILE_IO do { \\"
, "\t\tif (!ie->options.allow_file_io) {\\"
, "\t\t\tinterpret_error=&e__ABC_PInterpreter__dDV__FileIOAttempted; \\"
, "\t\t\tEXIT(ie,-1); \\"
, "\t\t} \\"
, "\t} while (0)"
, "#else"
, "# define CHECK_FILE_IO do { \\"
, "\t\tif (!options.allow_file_io) {\\"
, "\t\t\tEPRINTF(\"File I/O attempted (%s) at %d\\n\", instruction_name(*pc), (int) (pc-program->code)); \\"
, "\t\t\tEXIT(ie,-1); \\"
, "\t\t} \\"
, "\t} while (0)"
, "#endif"
]
post :: [String]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment