From 7844d40e00dec29f01b28ad905dc3edede093de7 Mon Sep 17 00:00:00 2001 From: Andras Slemmer Date: Mon, 6 Feb 2017 10:56:16 +0000 Subject: [PATCH] edger8r, psw: Add [enclave_id] non-pointer attribute Signed-off-by: Andras Slemmer --- psw/urts/enclave.cpp | 10 ++++---- psw/urts/linux/sig_handler.cpp | 6 ++--- psw/urts/tcs.h | 5 ++-- sdk/edger8r/linux/Ast.ml | 11 ++++++--- sdk/edger8r/linux/CodeGen.ml | 39 ++++++++++++++++++----------- sdk/edger8r/linux/Parser.mly | 45 ++++++++++++++++++++++++---------- 6 files changed, 76 insertions(+), 40 deletions(-) diff --git a/psw/urts/enclave.cpp b/psw/urts/enclave.cpp index 8890077b7e..d5e4021777 100644 --- a/psw/urts/enclave.cpp +++ b/psw/urts/enclave.cpp @@ -43,7 +43,7 @@ using namespace std; int do_ecall(const int fn, const void *ocall_table, const void *ms, CTrustThread *trust_thread); -int do_ocall(const bridge_fn_t bridge, void *ms); +int do_ocall(const bridge_fn_t bridge, sgx_enclave_id_t enclave_id, void *ms); CEnclave::CEnclave(CLoader &ldr) : m_loader(ldr) @@ -193,7 +193,7 @@ int CEnclave::ocall(const unsigned int proc, const sgx_ocall_table_t *ocall_tabl se_rdunlock(&m_rwlock); bridge_fn_t bridge = reinterpret_cast(ocall_table->ocall[proc]); - error = do_ocall(bridge, ms); + error = do_ocall(bridge, m_enclave_id, ms); if (!se_try_rdlock(&m_rwlock)) { @@ -478,7 +478,7 @@ bool CEnclave::update_trust_thread_debug_flag(void* tcs_address, uint8_t debug_f if(debug_info->enclave_type == ET_DEBUG) { - + if(!se_write_process_mem(pid, reinterpret_cast(tcs_address) + sizeof(uint64_t), &debug_flag2, sizeof(uint64_t), NULL)) return FALSE; @@ -490,13 +490,13 @@ bool CEnclave::update_trust_thread_debug_flag(void* tcs_address, uint8_t debug_f bool CEnclave::update_debug_flag(uint8_t debug_flag) { debug_tcs_info_t* tcs_list_entry = m_enclave_info.tcs_list; - + while(tcs_list_entry) { if(!update_trust_thread_debug_flag(tcs_list_entry->TCS_address, debug_flag)) return FALSE; - tcs_list_entry = tcs_list_entry->next_tcs_info; + tcs_list_entry = tcs_list_entry->next_tcs_info; } return TRUE; diff --git a/psw/urts/linux/sig_handler.cpp b/psw/urts/linux/sig_handler.cpp index 8651538f2d..e1e11617e8 100644 --- a/psw/urts/linux/sig_handler.cpp +++ b/psw/urts/linux/sig_handler.cpp @@ -130,7 +130,7 @@ void sig_handler(int signum, siginfo_t* siginfo, void *priv) } //If we can't fix the exception within enclave, then give the handle to other signal hanlder. //Call the previous signal handler. The default signal handler should terminate the application. - + enclave->rdunlock(); CEnclavePool::instance()->unref_enclave(enclave); } @@ -248,11 +248,11 @@ int do_ecall(const int fn, const void *ocall_table, const void *ms, CTrustThread return status; } -int do_ocall(const bridge_fn_t bridge, void *ms) +int do_ocall(const bridge_fn_t bridge, sgx_enclave_id_t enclave_id, void *ms) { int error = SGX_ERROR_UNEXPECTED; - error = bridge(ms); + error = bridge(enclave_id, ms); save_and_clean_xfeature_regs(NULL); diff --git a/psw/urts/tcs.h b/psw/urts/tcs.h index 39c3484f13..0ea79c5a7a 100644 --- a/psw/urts/tcs.h +++ b/psw/urts/tcs.h @@ -36,6 +36,7 @@ #include "se_wrapper.h" #include "util.h" #include "sgx_error.h" +#include "sgx_eid.h" #include "se_debugger_lib.h" #include "se_lock.hpp" #include @@ -43,7 +44,7 @@ using namespace std; -typedef int (*bridge_fn_t)(const void*); +typedef int (*bridge_fn_t)(sgx_enclave_id_t enclave_id, const void*); class CEnclave; @@ -87,7 +88,7 @@ protected: inline CTrustThread * get_free_thread(); int bind_thread(const se_thread_id_t thread_id, CTrustThread * const trust_thread); CTrustThread * get_bound_thread(const se_thread_id_t thread_id); - + vector m_free_thread_vector; Node *m_thread_list; Mutex m_thread_mutex; //protect both thread_cache list and fress tcs list. The mutex is recursive. diff --git a/sdk/edger8r/linux/Ast.ml b/sdk/edger8r/linux/Ast.ml index 3bc15aae27..5a1f03ec6a 100644 --- a/sdk/edger8r/linux/Ast.ml +++ b/sdk/edger8r/linux/Ast.ml @@ -86,10 +86,15 @@ type ptr_attr = { pa_chkptr : bool; (* Whether to generate code to check pointer *) } +type non_ptr_attr = { + npa_enclave_id : bool; +} +let default_non_ptr_attr = { npa_enclave_id = false; } + (* parameter type *) type parameter_type = - | PTVal of atype (* Passed by value *) - | PTPtr of atype * ptr_attr (* Passed by address *) + | PTVal of atype * non_ptr_attr (* Passed by value *) + | PTPtr of atype * ptr_attr (* Passed by address *) type call_conv = CC_CDECL | CC_STDCALL | CC_FASTCALL | CC_NONE @@ -241,7 +246,7 @@ let rec get_tystr (ty: atype) = (* Get the plain `atype' from a `parameter_type'. *) let get_param_atype (pt: parameter_type) = match pt with - | PTVal t -> t + | PTVal (t, _) -> t | PTPtr (t, _) -> t (* Convert attr_value to string *) diff --git a/sdk/edger8r/linux/CodeGen.ml b/sdk/edger8r/linux/CodeGen.ml index 441025302d..1bf2de7d58 100644 --- a/sdk/edger8r/linux/CodeGen.ml +++ b/sdk/edger8r/linux/CodeGen.ml @@ -31,6 +31,7 @@ open Printf open Util (* for failwithf *) +open List (* -------------------------------------------------------------------- * We first introduce a `parse_enclave_ast' function (see below) to @@ -139,7 +140,7 @@ let is_foreign_array (pt: Ast.parameter_type) = let is_naked_func (fd: Ast.func_decl) = fd.Ast.rtype = Ast.Void && fd.Ast.plist = [] -(* +(* * If user only defined a trusted function w/o neither parameter nor * return value, the generated trusted bridge will not call any tRTS * routines. If the real trusted function doesn't call tRTS function @@ -192,6 +193,7 @@ let conv_array_to_ptr (pd: Ast.pdecl): Ast.pdecl = let retval_name = "retval" let retval_declr = { Ast.identifier = retval_name; Ast.array_dims = []; } let eid_name = "eid" +let enclave_id_name = "enclave_id" let ms_ptr_name = "pms" let ms_struct_val = "ms" let mk_ms_member_name (pname: string) = "ms_" ^ pname @@ -209,8 +211,8 @@ let mk_ubridge_name (file_shortnm: string) (funcname: string) = sprintf "%s_%s" file_shortnm funcname let mk_ubridge_proto (file_shortnm: string) (funcname: string) = - sprintf "static sgx_status_t SGX_CDECL %s(void* %s)" - (mk_ubridge_name file_shortnm funcname) ms_ptr_name + sprintf "static sgx_status_t SGX_CDECL %s(sgx_enclave_id_t %s, void* %s)" + (mk_ubridge_name file_shortnm funcname) enclave_id_name ms_ptr_name (* Common macro definitions. *) let common_macros = "#include /* for size_t */\n\n\ @@ -237,6 +239,13 @@ let get_theader_name (file_shortnm: string) = let get_tsource_name (file_shortnm: string) = !g_trusted_dir ^ separator_str ^ file_shortnm ^ "_t.c" +let filter_non_enclave_id_params (params: Ast.pdecl list) = + filter (fun (p,_) -> + match p with + Ast.PTVal(_, npattr) -> not npattr.Ast.npa_enclave_id + | _ -> true + ) params + (* Construct the string of structure definition *) let mk_struct_decl (fs: string) (name: string) = sprintf "typedef struct %s {\n%s} %s;\n" name fs name @@ -317,7 +326,7 @@ let get_param_tystr (pt: Ast.parameter_type) = (* Generate marshaling structure definition *) let gen_marshal_struct (fd: Ast.func_decl) (errno: string) = let member_list_str = errno ^ - let new_param_list = List.map conv_array_to_ptr fd.Ast.plist in + let new_param_list = filter_non_enclave_id_params (List.map conv_array_to_ptr fd.Ast.plist) in List.fold_left (fun acc (pt, declr) -> acc ^ mk_ms_member_decl pt declr) "" new_param_list in let struct_name = mk_ms_struct_name fd.Ast.fname in @@ -326,7 +335,7 @@ let gen_marshal_struct (fd: Ast.func_decl) (errno: string) = a marshaling struct. *) Ast.Void -> if fd.Ast.plist = [] && errno = "" then "" else mk_struct_decl member_list_str struct_name - | _ -> let rv_str = mk_ms_member_decl (Ast.PTVal fd.Ast.rtype) retval_declr + | _ -> let rv_str = mk_ms_member_decl (Ast.PTVal(fd.Ast.rtype, Ast.default_non_ptr_attr)) retval_declr in mk_struct_decl (rv_str ^ member_list_str) struct_name let gen_ecall_marshal_struct (tf: Ast.trusted_func) = @@ -457,7 +466,7 @@ let gen_entry_table (ec: enclave_content) = *) let gen_tproxy_proto (fd: Ast.func_decl) = let parm_list = - match fd.Ast.plist with + match filter_non_enclave_id_params fd.Ast.plist with [] -> "" | x :: xs -> List.fold_left (fun acc pd -> @@ -654,7 +663,9 @@ let add_foreign_array_ptrref else arg let mk_parm_name_ubridge (pt: Ast.parameter_type) (declr: Ast.declarator) = - add_foreign_array_ptrref mk_parm_name_raw pt declr + match pt with + Ast.PTVal(_, attr) when attr.Ast.npa_enclave_id -> enclave_id_name + | _ -> add_foreign_array_ptrref mk_parm_name_raw pt declr let mk_parm_name_ext (pt: Ast.parameter_type) (declr: Ast.declarator) = let name = declr.Ast.identifier in @@ -723,7 +734,7 @@ let fill_ms_field (isptr: bool) (pd: Ast.pdecl) = in if declr.Ast.array_dims = [] then match pt with - Ast.PTVal(aty) -> assignment_str false aty + Ast.PTVal(aty, npattr) -> assignment_str false aty | Ast.PTPtr(aty, pattr) -> if pattr.Ast.pa_isary then gen_setup_foreign_array aty @@ -844,7 +855,7 @@ let gen_check_tbridge_length_overflow (plist: Ast.pdecl list) = let gen_check_length (ty: Ast.atype) (attr: Ast.ptr_attr) (declr: Ast.declarator) = let name = declr.Ast.identifier in let tmp_ptr_name= mk_tmp_var name in - + let mk_len_size v = match v with Ast.AString s -> mk_tmp_var s @@ -870,7 +881,7 @@ let gen_check_tbridge_length_overflow (plist: Ast.pdecl list) = in match attr.Ast.pa_size.Ast.ps_count with None -> "" - | Some a -> sprintf "%s\n\n" (gen_check_overflow a size_str) + | Some a -> sprintf "%s\n\n" (gen_check_overflow a size_str) in List.fold_left (fun acc (pty, declr) -> @@ -1241,7 +1252,7 @@ let gen_ocalloc_block (fname: string) (plist: Ast.pdecl list) = in let s1 = List.fold_left (fun acc pd -> acc ^ do_count_ocalloc_size pd) local_vars_block new_param_list in List.fold_left (fun acc s -> acc ^ s) s1 do_gen_ocalloc_block - + (* Generate trusted proxy code for a given untrusted function. *) let gen_func_tproxy (ufunc: Ast.untrusted_func) (idx: int) = let fd = ufunc.Ast.uf_fdecl in @@ -1282,7 +1293,7 @@ let gen_func_tproxy (ufunc: Ast.untrusted_func) (idx: int) = begin func_body := local_vars :: !func_body; func_body := ocalloc_ms_struct:: !func_body; - List.iter (fun pd -> func_body := tproxy_fill_ms_field pd :: !func_body) fd.Ast.plist; + List.iter (fun pd -> func_body := tproxy_fill_ms_field pd :: !func_body) (filter_non_enclave_id_params fd.Ast.plist); func_body := ocall_with_ms :: !func_body; if fd.Ast.rtype <> Ast.Void then func_body := update_retval :: !func_body; List.fold_left (fun acc s -> acc ^ "\t" ^ s ^ "\n") func_open (List.rev !func_body) ^ func_close @@ -1396,9 +1407,9 @@ let start_parsing (fname: string) : Ast.enclave = let fullpath = Util.get_file_path fname in let preprocessed = save_file fullpath; Preprocessor.processor_macro(fullpath) in - let lexbuf = + let lexbuf = match preprocessed with - | None -> + | None -> let chan = open_in fullpath in Lexing.from_channel chan | Some(preprocessed_string) -> Lexing.from_string preprocessed_string diff --git a/sdk/edger8r/linux/Parser.mly b/sdk/edger8r/linux/Parser.mly index a5dabc3368..cbf56c9368 100644 --- a/sdk/edger8r/linux/Parser.mly +++ b/sdk/edger8r/linux/Parser.mly @@ -175,6 +175,22 @@ let get_ptr_attr (attr_list: (string * Ast.attr_value) list) = then check_invalid_ary_attr pattr else check_invalid_ptr_size pattr |> check_ptr_dir +let get_non_ptr_attr (attr_list: (string * Ast.attr_value) list) = + let update_attr (key: string) (value: Ast.attr_value) (ores: Ast.non_ptr_attr option) = + match ores with + None -> None + | Some res -> match key with + "enclave_id" -> Some { res with Ast.npa_enclave_id = true; } + | _ -> Some res + in + let rec do_get_non_ptr_attr alist res_attr = + match alist with + [] -> res_attr + | (k,v) :: xs -> do_get_non_ptr_attr xs (update_attr k v res_attr) + in do_get_non_ptr_attr attr_list (Some Ast.default_non_ptr_attr) + + + (* Untrusted functions can have these attributes: * * a. 3 mutual exclusive calling convention specifier: @@ -366,23 +382,26 @@ param_type: attr_block all_type { Ast.Ptr _ -> fun x -> Ast.PTPtr($2, get_ptr_attr $1) | _ -> if $1 <> [] then - let attr = get_ptr_attr $1 in match $2 with Ast.Foreign s -> - if attr.Ast.pa_isptr || attr.Ast.pa_isary then fun x -> Ast.PTPtr($2, attr) - else - (* thinking about 'user_defined_type var[4]' *) - fun is_ary -> - if is_ary then Ast.PTPtr($2, attr) - else failwithf "`%s' is considerred plain type but decorated with pointer attributes" s - | _ -> - fun is_ary -> + let attr = get_ptr_attr $1 in + if attr.Ast.pa_isptr || attr.Ast.pa_isary then fun x -> Ast.PTPtr($2, attr) + else + (* thinking about 'user_defined_type var[4]' *) + fun is_ary -> if is_ary then Ast.PTPtr($2, attr) - else failwithf "unexpected pointer attributes for `%s'" (Ast.get_tystr $2) + else failwithf "`%s' is considerred plain type but decorated with pointer attributes" s + | _ -> + fun is_ary -> + if is_ary then Ast.PTPtr($2, get_ptr_attr $1) + else + match get_non_ptr_attr $1 with + Some attr -> Ast.PTVal($2, attr) + | None -> failwithf "unexpected pointer attributes for `%s'" (Ast.get_tystr $2) else fun is_ary -> if is_ary then Ast.PTPtr($2, get_ptr_attr []) - else Ast.PTVal $2 + else Ast.PTVal($2, Ast.default_non_ptr_attr) } | all_type { match $1 with @@ -390,7 +409,7 @@ param_type: attr_block all_type { | _ -> fun is_ary -> if is_ary then Ast.PTPtr($1, get_ptr_attr []) - else Ast.PTVal $1 + else Ast.PTVal($1, Ast.default_non_ptr_attr) } | attr_block Tconst type_spec pointer { let attr = get_ptr_attr $1 @@ -551,7 +570,7 @@ parameter_def: param_type declarator { let pt = $1 (Ast.is_array $2) in let is_void = match pt with - Ast.PTVal v -> v = Ast.Void + Ast.PTVal(v, _) -> v = Ast.Void | _ -> false in if is_void then