security holes fixed

This commit is contained in:
Li Haokun 2021-08-19 17:54:36 +08:00 committed by GitHub
parent 80cc8e9db7
commit ef9b781961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 90 deletions

View File

@ -89,7 +89,7 @@ void execute(std::string& file,std::string& command)
codegen.main_progress(import.get_root(),import.get_file()); codegen.main_progress(import.get_root(),import.get_file());
if(codegen.get_error()) if(codegen.get_error())
{ {
die("codegen",file); die("code",file);
return; return;
} }
if(command=="--code" || command=="-c") if(command=="--code" || command=="-c")

View File

@ -268,7 +268,10 @@ void nasal_codegen::regist_number(double num)
{ {
int size=number_table.size(); int size=number_table.size();
if(!number_table.count(num)) if(!number_table.count(num))
{
number_table[num]=size; number_table[num]=size;
num_res_table.push_back(num);
}
return; return;
} }
@ -276,7 +279,10 @@ void nasal_codegen::regist_string(std::string& str)
{ {
int size=string_table.size(); int size=string_table.size();
if(!string_table.count(str)) if(!string_table.count(str))
{
string_table[str]=size; string_table[str]=size;
str_res_table.push_back(str);
}
return; return;
} }
@ -1170,6 +1176,8 @@ void nasal_codegen::main_progress(nasal_ast& ast,std::vector<std::string>& files
number_table.clear(); number_table.clear();
string_table.clear(); string_table.clear();
num_res_table.clear();
str_res_table.clear();
file_name=files; file_name=files;
exec_code.clear(); exec_code.clear();
@ -1237,13 +1245,9 @@ void nasal_codegen::main_progress(nasal_ast& ast,std::vector<std::string>& files
} }
} }
gen(op_nop,0,0); gen(op_nop,0,0);
if(global.size()>=STACK_MAX_DEPTH)
die("too many global variants: "+std::to_string(global.size())+".",0);
exec_code[0].num=global.size(); exec_code[0].num=global.size();
num_res_table.resize(number_table.size());
str_res_table.resize(string_table.size());
for(auto& i:number_table)
num_res_table[i.second]=i.first;
for(auto& i:string_table)
str_res_table[i.second]=i.first;
return; return;
} }

View File

@ -264,11 +264,11 @@ std::string nasal_val::to_string()
struct nasal_gc struct nasal_gc
{ {
#define STACK_MAX_DEPTH (4080) #define STACK_MAX_DEPTH (4095)
nasal_ref zero_addr; // reserved address of nasal_val,type vm_num, 0 nasal_ref zero_addr; // reserved address of nasal_val,type vm_num, 0
nasal_ref one_addr; // reserved address of nasal_val,type vm_num, 1 nasal_ref one_addr; // reserved address of nasal_val,type vm_num, 1
nasal_ref nil_addr; // reserved address of nasal_val,type vm_nil nasal_ref nil_addr; // reserved address of nasal_val,type vm_nil
nasal_ref val_stack[STACK_MAX_DEPTH+16];// 16 reserved to avoid stack overflow nasal_ref val_stack[STACK_MAX_DEPTH+1];// 1 reserved to avoid stack overflow, stack grows 1 each time
nasal_ref* stack_top; // stack top nasal_ref* stack_top; // stack top
std::vector<nasal_ref> num_addrs; // reserved address for const vm_num std::vector<nasal_ref> num_addrs; // reserved address for const vm_num
std::vector<nasal_ref> str_addrs; // reserved address for const vm_str std::vector<nasal_ref> str_addrs; // reserved address for const vm_str

View File

@ -149,7 +149,7 @@ void nasal_vm::bytecodeinfo(uint32_t p)
void nasal_vm::traceback() void nasal_vm::traceback()
{ {
printf("trace back:\n"); printf("trace back:\n");
uint32_t same_cnt=0,last_point=0; uint32_t same_cnt=0,last_point=0xffffffff;
for(uint32_t point=0;!ret.empty();last_point=point,ret.pop()) for(uint32_t point=0;!ret.empty();last_point=point,ret.pop())
{ {
point=ret.top(); point=ret.top();
@ -214,7 +214,7 @@ void nasal_vm::die(std::string str)
ret.push(pc); ret.push(pc);
traceback(); traceback();
stackinfo(10); stackinfo(10);
gc.val_stack[STACK_MAX_DEPTH-1]=(nasal_ref)0xffff; exit(1);
return; return;
} }
void nasal_vm::stackoverflow() void nasal_vm::stackoverflow()
@ -222,6 +222,7 @@ void nasal_vm::stackoverflow()
printf("[vm] stack overflow\n"); printf("[vm] stack overflow\n");
traceback(); traceback();
stackinfo(10); stackinfo(10);
exit(1);
return; return;
} }
inline bool nasal_vm::condition(nasal_ref val_addr) inline bool nasal_vm::condition(nasal_ref val_addr)
@ -931,7 +932,7 @@ void nasal_vm::run(std::vector<opcode>& exec,bool op_cnt)
goto *code[pc]; goto *code[pc];
nop: nop:
if(canary && canary!=(nasal_ref)0xffff) if(canary)
stackoverflow(); stackoverflow();
if(op_cnt) if(op_cnt)
{ {
@ -950,83 +951,85 @@ nop:
} }
} }
return; return;
// may cause stackoverflow
#define exec_operand(op,num) {op();++count[num];if(!canary)goto *code[++pc];goto nop;} #define exec_operand(op,num) {op();++count[num];if(!canary)goto *code[++pc];goto nop;}
// do not cause stackoverflow
#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];} #define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
intg: exec_opnodie(opr_intg ,op_intg ); intg: exec_opnodie(opr_intg ,op_intg ); // stack+=imm[pc] (detected at codegen)
intl: exec_opnodie(opr_intl ,op_intl ); intl: exec_opnodie(opr_intl ,op_intl ); // stack-=0
offset: exec_opnodie(opr_offset ,op_offset ); offset: exec_opnodie(opr_offset ,op_offset ); // stack-=0
loadg: exec_opnodie(opr_loadg ,op_loadg ); loadg: exec_opnodie(opr_loadg ,op_loadg ); // stack-=1
loadl: exec_opnodie(opr_loadl ,op_loadl ); loadl: exec_opnodie(opr_loadl ,op_loadl ); // stack-=1
pnum: exec_operand(opr_pnum ,op_pnum ); pnum: exec_operand(opr_pnum ,op_pnum ); // stack+=1
pone: exec_operand(opr_pone ,op_pone ); pone: exec_operand(opr_pone ,op_pone ); // stack+=1
pzero: exec_operand(opr_pzero ,op_pzero ); pzero: exec_operand(opr_pzero ,op_pzero ); // stack+=1
pnil: exec_operand(opr_pnil ,op_pnil ); pnil: exec_operand(opr_pnil ,op_pnil ); // stack+=1
pstr: exec_operand(opr_pstr ,op_pstr ); pstr: exec_operand(opr_pstr ,op_pstr ); // stack+=1
newv: exec_operand(opr_newv ,op_newv ); newv: exec_operand(opr_newv ,op_newv ); // stack+=1-imm[pc]
newh: exec_operand(opr_newh ,op_newh ); newh: exec_operand(opr_newh ,op_newh ); // stack+=1
newf: exec_operand(opr_newf ,op_newf ); newf: exec_operand(opr_newf ,op_newf ); // stack+=1
happ: exec_opnodie(opr_happ ,op_happ ); happ: exec_opnodie(opr_happ ,op_happ ); // stack-=1
para: exec_opnodie(opr_para ,op_para ); para: exec_opnodie(opr_para ,op_para ); // stack-=0
defpara: exec_opnodie(opr_defpara ,op_defpara ); defpara: exec_opnodie(opr_defpara ,op_defpara ); // stack-=1
dynpara: exec_opnodie(opr_dynpara ,op_dynpara ); dynpara: exec_opnodie(opr_dynpara ,op_dynpara ); // stack-=0
unot: exec_operand(opr_unot ,op_unot ); unot: exec_opnodie(opr_unot ,op_unot ); // stack-=0
usub: exec_opnodie(opr_usub ,op_usub ); usub: exec_opnodie(opr_usub ,op_usub ); // stack-=0
add: exec_opnodie(opr_add ,op_add ); add: exec_opnodie(opr_add ,op_add ); // stack-=1
sub: exec_opnodie(opr_sub ,op_sub ); sub: exec_opnodie(opr_sub ,op_sub ); // stack-=1
mul: exec_opnodie(opr_mul ,op_mul ); mul: exec_opnodie(opr_mul ,op_mul ); // stack-=1
div: exec_opnodie(opr_div ,op_div ); div: exec_opnodie(opr_div ,op_div ); // stack-=1
lnk: exec_opnodie(opr_lnk ,op_lnk ); lnk: exec_opnodie(opr_lnk ,op_lnk ); // stack-=1
addc: exec_opnodie(opr_addc ,op_addc ); addc: exec_opnodie(opr_addc ,op_addc ); // stack-=0
subc: exec_opnodie(opr_subc ,op_subc ); subc: exec_opnodie(opr_subc ,op_subc ); // stack-=0
mulc: exec_opnodie(opr_mulc ,op_mulc ); mulc: exec_opnodie(opr_mulc ,op_mulc ); // stack-=0
divc: exec_opnodie(opr_divc ,op_divc ); divc: exec_opnodie(opr_divc ,op_divc ); // stack-=0
lnkc: exec_opnodie(opr_lnkc ,op_lnkc ); lnkc: exec_opnodie(opr_lnkc ,op_lnkc ); // stack-=0
addeq: exec_opnodie(opr_addeq ,op_addeq ); addeq: exec_opnodie(opr_addeq ,op_addeq ); // stack-=1
subeq: exec_opnodie(opr_subeq ,op_subeq ); subeq: exec_opnodie(opr_subeq ,op_subeq ); // stack-=1
muleq: exec_opnodie(opr_muleq ,op_muleq ); muleq: exec_opnodie(opr_muleq ,op_muleq ); // stack-=1
diveq: exec_opnodie(opr_diveq ,op_diveq ); diveq: exec_opnodie(opr_diveq ,op_diveq ); // stack-=1
lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq ); lnkeq: exec_opnodie(opr_lnkeq ,op_lnkeq ); // stack-=1
addeqc: exec_opnodie(opr_addeqc ,op_addeqc ); addeqc: exec_opnodie(opr_addeqc ,op_addeqc ); // stack-=0
subeqc: exec_opnodie(opr_subeqc ,op_subeqc ); subeqc: exec_opnodie(opr_subeqc ,op_subeqc ); // stack-=0
muleqc: exec_opnodie(opr_muleqc ,op_muleqc ); muleqc: exec_opnodie(opr_muleqc ,op_muleqc ); // stack-=0
diveqc: exec_opnodie(opr_diveqc ,op_diveqc ); diveqc: exec_opnodie(opr_diveqc ,op_diveqc ); // stack-=0
lnkeqc: exec_opnodie(opr_lnkeqc ,op_lnkeqc ); lnkeqc: exec_opnodie(opr_lnkeqc ,op_lnkeqc ); // stack-=0
meq: exec_opnodie(opr_meq ,op_meq ); meq: exec_opnodie(opr_meq ,op_meq ); // stack-=1
eq: exec_opnodie(opr_eq ,op_eq ); eq: exec_opnodie(opr_eq ,op_eq ); // stack-=1
neq: exec_opnodie(opr_neq ,op_neq ); neq: exec_opnodie(opr_neq ,op_neq ); // stack-=1
less: exec_opnodie(opr_less ,op_less ); less: exec_opnodie(opr_less ,op_less ); // stack-=1
leq: exec_opnodie(opr_leq ,op_leq ); leq: exec_opnodie(opr_leq ,op_leq ); // stack-=1
grt: exec_opnodie(opr_grt ,op_grt ); grt: exec_opnodie(opr_grt ,op_grt ); // stack-=1
geq: exec_opnodie(opr_geq ,op_geq ); geq: exec_opnodie(opr_geq ,op_geq ); // stack-=1
lessc: exec_opnodie(opr_lessc ,op_lessc ); lessc: exec_opnodie(opr_lessc ,op_lessc ); // stack-=0
leqc: exec_opnodie(opr_leqc ,op_leqc ); leqc: exec_opnodie(opr_leqc ,op_leqc ); // stack-=0
grtc: exec_opnodie(opr_grtc ,op_grtc ); grtc: exec_opnodie(opr_grtc ,op_grtc ); // stack-=0
geqc: exec_opnodie(opr_geqc ,op_geqc ); geqc: exec_opnodie(opr_geqc ,op_geqc ); // stack-=0
pop: exec_opnodie(opr_pop ,op_pop ); pop: exec_opnodie(opr_pop ,op_pop ); // stack-=1
jmp: exec_opnodie(opr_jmp ,op_jmp ); jmp: exec_opnodie(opr_jmp ,op_jmp ); // stack-=0
jt: exec_opnodie(opr_jt ,op_jt ); jt: exec_opnodie(opr_jt ,op_jt ); // stack-=0
jf: exec_opnodie(opr_jf ,op_jf ); jf: exec_opnodie(opr_jf ,op_jf ); // stack-=1
counter: exec_operand(opr_counter ,op_cnt ); counter: exec_opnodie(opr_counter ,op_cnt ); // stack-=0
cntpop: exec_opnodie(opr_cntpop ,op_cntpop ); cntpop: exec_opnodie(opr_cntpop ,op_cntpop ); // stack-=0
findex: exec_opnodie(opr_findex ,op_findex ); findex: exec_operand(opr_findex ,op_findex ); // stack+=1
feach: exec_opnodie(opr_feach ,op_feach ); feach: exec_operand(opr_feach ,op_feach ); // stack+=1
callg: exec_opnodie(opr_callg ,op_callg ); callg: exec_operand(opr_callg ,op_callg ); // stack+=1
calll: exec_opnodie(opr_calll ,op_calll ); calll: exec_operand(opr_calll ,op_calll ); // stack+=1
callv: exec_operand(opr_callv ,op_callv ); callv: exec_opnodie(opr_callv ,op_callv ); // stack-=0
callvi: exec_operand(opr_callvi ,op_callvi ); callvi: exec_opnodie(opr_callvi ,op_callvi ); // stack-=0
callh: exec_operand(opr_callh ,op_callh ); callh: exec_opnodie(opr_callh ,op_callh ); // stack-=0
callfv: exec_operand(opr_callfv ,op_callfv ); callfv: exec_opnodie(opr_callfv ,op_callfv ); // stack-=0
callfh: exec_operand(opr_callfh ,op_callfh ); callfh: exec_opnodie(opr_callfh ,op_callfh ); // stack-=0
callb: exec_operand(opr_callb ,op_callb ); callb: exec_opnodie(opr_callb ,op_callb ); // stack-=0
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // stack+=1
slcend: exec_opnodie(opr_slcend ,op_slcend ); slcend: exec_opnodie(opr_slcend ,op_slcend ); // stack-=1
slc: exec_operand(opr_slc ,op_slc ); slc: exec_opnodie(opr_slc ,op_slc ); // stack-=1
slc2: exec_operand(opr_slc2 ,op_slc2 ); slc2: exec_opnodie(opr_slc2 ,op_slc2 ); // stack-=2
mcallg: exec_opnodie(opr_mcallg ,op_mcallg ); mcallg: exec_operand(opr_mcallg ,op_mcallg ); // stack+=1
mcalll: exec_opnodie(opr_mcalll ,op_mcalll ); mcalll: exec_operand(opr_mcalll ,op_mcalll ); // stack+=1
mcallv: exec_operand(opr_mcallv ,op_mcallv ); mcallv: exec_opnodie(opr_mcallv ,op_mcallv ); // stack-=0
mcallh: exec_operand(opr_mcallh ,op_mcallh ); mcallh: exec_opnodie(opr_mcallh ,op_mcallh ); // stack-=0
ret: exec_opnodie(opr_ret ,op_ret ); ret: exec_opnodie(opr_ret ,op_ret ); // stack-=1
} }
#endif #endif

View File

@ -85,7 +85,7 @@ func()
} }
for(var l=cnt;l<16;l+=1) for(var l=cnt;l<16;l+=1)
print(' '); print(' ');
if(cnt<8) if(cnt<=8)
print(' '); print(' ');
textprint(i); textprint(i);
}(); }();

View File

@ -1,13 +1,12 @@
# Y combinator by ValKmjolnir # Y combinator by ValKmjolnir
import("lib.nas"); import("lib.nas");
var count=0;
var fib=func(f){ var fib=func(f){
return f(f); return f(f);
}( }(
func(f){ func(f){
return func(x){ return func(x){
count+=1;
if(x<2) return x; if(x<2) return x;
return f(f)(x-1)+f(f)(x-2); return f(f)(x-1)+f(f)(x-2);
} }