open Core_kernel open Bap.Std open Log_utils let name = "CWE560" let version = "0.1" let upper_bound_of_correct_umask_arg_value = 100 let upper_bound_of_correct_chmod_arg_value = 1000 let collect_int_values = Exp.fold ~init:[] (object inherit [word list] Exp.visitor method! enter_int x addrs = x :: addrs end) let is_chmod_style_arg umask_arg = umask_arg > upper_bound_of_correct_umask_arg_value && umask_arg < upper_bound_of_correct_chmod_arg_value let check_umask_arg tid_map blk w = try let umask_arg = Word.to_int_exn w in if is_chmod_style_arg umask_arg then let address = Address_translation.translate_tid_to_assembler_address_string (Term.tid blk) tid_map in let tid = Address_translation.tid_to_string @@ Term.tid blk in let umask_arg_str = sprintf "%d" umask_arg in let description = sprintf "(Use of umask() with chmod-style Argument) Function %s calls umask with argument %s" address umask_arg_str in let other = [["umask_arg"; umask_arg_str]] in let cwe_warning = cwe_warning_factory name version ~addresses:[address] ~tids:[tid] ~other:other description in collect_cwe_warning cwe_warning with _ -> Log_utils.error "Caught exception in module [CWE560]." let check_umask_callsite tid_map blk = Seq.iter (Term.enum def_t blk) ~f:(fun d -> let rhs = Def.rhs d in let int_values = collect_int_values rhs in List.iter int_values ~f:(fun x -> check_umask_arg tid_map blk x) ) let blk_calls_umask sym_umask blk = Term.enum jmp_t blk |> Seq.exists ~f:(fun callsite -> Symbol_utils.calls_callsite_symbol callsite sym_umask) let check_subfunction program tid_map sym_umask sub = if Symbol_utils.sub_calls_symbol program sub "umask" then Term.enum blk_t sub |> Seq.filter ~f:(fun blk -> blk_calls_umask sym_umask blk) |> Seq.iter ~f:(fun blk -> check_umask_callsite tid_map blk) else () let check_subfunctions program tid_map sym_umask = Seq.iter (Term.enum sub_t program) ~f:(fun sub -> check_subfunction program tid_map sym_umask sub) let check_cwe program _ tid_map _ _ = let sym = Symbol_utils.get_symbol_of_string program "umask" in match sym with | None -> () | Some sym_umask -> check_subfunctions program tid_map sym_umask (* Functions made available for unit tests *) module Private = struct let is_chmod_style_arg = is_chmod_style_arg end