def impl_invariants_py(ctx): conj = [] conj.append( z3.And( util.global_value(ctx, '@counter') >= 0, util.global_value(ctx, '@counter') <= dt.MAX_UINT)) return conj
def state_equiv(ctx, kernelstate): conj = [] module = sys.modules[__name__] for k in kernelstate._meta.keys(): if not k in kernelstate._structs: continue getattr(module, k + '_equiv')(conj, ctx, kernelstate) conj.append(kernelstate.current == util.global_value(ctx, '@current')) conj.append( kernelstate.pages_ptr_to_int == util.global_ptr_to_int(ctx, '@pages')) conj.append(kernelstate.proc_table_ptr_to_int == util.global_ptr_to_int( ctx, '@proc_table')) conj.append(kernelstate.page_desc_table_ptr_to_int == util.global_ptr_to_int(ctx, '@page_desc_table')) conj.append(kernelstate.file_table_ptr_to_int == util.global_ptr_to_int( ctx, '@file_table')) conj.append(kernelstate.devices_ptr_to_int == util.global_ptr_to_int( ctx, '@devices')) conj.append(kernelstate.dmapages_ptr_to_int == util.global_ptr_to_int( ctx, '@dmapages')) conj.append(impl_invariants(ctx)) return z3.And(*conj)
def state_equiv(ctx, kernelstate): #add:开始时,状态等价(main.HV6.setUp调用的) conj = [] module = sys.modules[__name__] for k in kernelstate._meta.keys(): if not k in kernelstate._structs: continue if k == 'esbs' or k == 'to' or k == 'from_' or k == 'ehn' or k == 's_bufs' or k == 'current_esb': #/*new* jump the equiv verify of esbs/ continue #/*new*/ getattr(module, k + '_equiv')(conj, ctx, kernelstate) conj.append(kernelstate.current == util.global_value(ctx, '@current')) conj.append( kernelstate.pages_ptr_to_int == util.global_ptr_to_int(ctx, '@pages')) conj.append(kernelstate.proc_table_ptr_to_int == util.global_ptr_to_int( ctx, '@proc_table')) conj.append(kernelstate.esb_table_ptr_to_int == util.global_ptr_to_int( ctx, '@esb_table')) #/*new*/ conj.append(kernelstate.page_desc_table_ptr_to_int == util.global_ptr_to_int(ctx, '@page_desc_table')) conj.append(kernelstate.file_table_ptr_to_int == util.global_ptr_to_int( ctx, '@file_table')) conj.append(kernelstate.devices_ptr_to_int == util.global_ptr_to_int( ctx, '@devices')) conj.append(kernelstate.dmapages_ptr_to_int == util.global_ptr_to_int( ctx, '@dmapages')) conj.append(impl_invariants(ctx)) return z3.And(*conj)
def state_equiv(ctx, state): conj = [] conj.append(state.counter == util.global_value(ctx, '@counter')) return z3.And(*conj)
def impl_invariants_py(ctx): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) pn = util.FreshBitVec('pn', dt.pn_t) fd = util.FreshBitVec('fd', dt.fd_t) # fn = util.FreshBitVec('fn', dt.fn_t) # embryos, runnable or running processes own the pages in their structs conj.append(z3.ForAll([pid], z3.Implies( z3.Or(util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_EMBRYO, util.global_field_element( ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_RUNNING, util.global_field_element( ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_RUNNABLE, util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_SLEEPING), z3.And( pn_has_owner_and_type(ctx, util.global_field_element( ctx, '@proc_table', 'page_table_root', pid), pid, dt.page_type.PAGE_TYPE_X86_PML4), pn_has_owner_and_type(ctx, util.global_field_element( ctx, '@proc_table', 'hvm', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA), pn_has_owner_and_type(ctx, util.global_field_element( ctx, '@proc_table', 'stack', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA), )))) # sleeping processes own their ipc_page conj.append(z3.ForAll([pid], z3.Implies(z3.And(is_pid_valid(pid), util.global_field_element(ctx, '@proc_table', 'state', pid) != dt.proc_state.PROC_ZOMBIE), z3.Implies(util.global_field_element(ctx, '@proc_table', 'use_io_bitmap', pid) != 0, z3.And( is_pn_valid(util.global_field_element(ctx, '@proc_table', 'io_bitmap_a', pid)), is_pn_valid(util.global_field_element(ctx, '@proc_table', 'io_bitmap_b', pid)), pn_has_owner_and_type(ctx, util.global_field_element(ctx, '@proc_table', 'io_bitmap_a', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA), pn_has_owner_and_type(ctx, util.global_field_element(ctx, '@proc_table', 'io_bitmap_b', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA)))))) # sleeping processes own their ipc_page conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid), z3.Implies(util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_SLEEPING, pn_has_owner_and_type(ctx, util.global_field_element(ctx, '@proc_table', 'ipc_page', pid), pid, dt.page_type.PAGE_TYPE_FRAME))))) conj.append(z3.ForAll([pid], z3.And( is_pn_valid(util.global_field_element( ctx, '@proc_table', 'page_table_root', pid)), is_pn_valid(util.global_field_element( ctx, '@proc_table', 'hvm', pid)), is_pn_valid(util.global_field_element(ctx, '@proc_table', 'stack', pid))))) # sleeping processes' ipc fd are empty if valid conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid), z3.Implies(util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_SLEEPING, z3.Implies(is_fd_valid(util.global_field_element(ctx, '@proc_table', 'ipc_fd', pid)), util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, util.global_field_element(ctx, '@proc_table', 'ipc_fd', pid))) == z3.BitVecVal(0, dt.fn_t)))))) conj.append(z3.ForAll([pid], z3.And( is_pn_valid(util.global_field_element( ctx, '@proc_table', 'page_table_root', pid)), is_pn_valid(util.global_field_element( ctx, '@proc_table', 'hvm', pid)), is_pn_valid(util.global_field_element(ctx, '@proc_table', 'stack', pid))))) # page has an owner <=> page is not free conj.append(z3.ForAll([pn], z3.Implies(is_pn_valid(pn), is_pid_valid(util.global_field_element(ctx, '@page_desc_table', 'pid', pn)) == (util.global_field_element(ctx, '@page_desc_table', 'type', pn) != dt.page_type.PAGE_TYPE_FREE)))) # unused procs have zero refcnt conj.append(z3.ForAll([pid], z3.Implies( z3.And( is_pid_valid(pid), util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_UNUSED), z3.And( util.global_field_element(ctx, '@proc_table', 'nr_children', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_fds', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_pages', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_dmapages', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_devs', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_ports', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_vectors', pid) == z3.BitVecVal(0, dt.size_t), util.global_field_element(ctx, '@proc_table', 'nr_intremaps', pid) == z3.BitVecVal(0, dt.size_t))))) # conj.append(z3.ForAll([pid, fd], z3.Implies(z3.And(is_pid_valid(pid), is_fd_valid(fd)), # z3.Implies( # util.global_field_element(ctx, '@proc_table', 'nr_fds', pid) == z3.BitVecVal(0, dt.size_t), # z3.Not(is_fn_valid(util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)))))))) # # unused procs have zero fds # conj.append(z3.ForAll([pid, fd], z3.Implies(z3.And(is_pid_valid(pid), is_fd_valid(fd)), # z3.Implies( # util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_UNUSED, # util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)) == z3.BitVecVal(0, dt.fn_t))))) # fds valid conj.append(z3.ForAll([pid, fd], z3.Implies(z3.And(is_pid_valid(pid), is_fd_valid(fd)), z3.Or( util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)) == z3.BitVecVal(0, dt.fn_t), is_fn_valid(util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd))))))) # # FD_NONE's refcount is 0 # conj.append(z3.ForAll([fn], z3.Implies( # z3.And( # is_fn_valid(fn), # util.global_field_element(ctx, '@file_table', 'type', fn) == dt.file_type.FD_NONE), # util.global_field_element(ctx, '@file_table', 'refcnt', fn) == z3.BitVecVal(0, dt.size_t)))) # # FD never points to FD_NONE # conj.append(z3.ForAll([pid, fd], z3.Implies( # z3.And( # is_pid_valid(pid), # is_fd_valid(fd), # is_fn_valid(util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)))), # util.global_field_element(ctx, '@file_table', 'type', # util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd))) != dt.file_type.FD_NONE))) # page freelist is well formed conj.append(z3.ForAll([pn], z3.Implies(is_pn_valid(pn), z3.And( is_pn_valid(util.global_field_element(ctx, '@page_desc_table', ['link', 'prev'], pn)), is_pn_valid(util.global_field_element(ctx, '@page_desc_table', ['link', 'next'], pn)))))) # ready queue is well formed # don't use is_pid_valid as some ->prev and ->next are zeros conj.append(z3.ForAll([pid], z3.Implies(is_pid_bounded(pid), z3.And( is_pid_bounded(util.global_field_element(ctx, '@proc_table', ['ready', 'prev'], pid)), is_pid_bounded(util.global_field_element(ctx, '@proc_table', ['ready', 'next'], pid)))))) # Current is always a valid and running conj.append(is_pid_valid(util.global_value(ctx, '@current'))) conj.append(util.global_field_element(ctx, '@proc_table', 'state', util.global_value(ctx, '@current')) == dt.proc_state.PROC_RUNNING) return z3.And(*conj)