def spec_lemma_nr_ports_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) port = util.FreshBitVec('port', dt.uint16_t) # unused procs don't own any ports # valid([port:pid]) ==> [port:pid].state != UNUSED conj.append( z3.ForAll([port], z3.Implies( is_pid_valid(kernelstate.io[port].owner), kernelstate.procs[kernelstate.io[port].owner].state != dt.proc_state.PROC_UNUSED))) # pid.state == UNUSED ==> pid.nr_ports == 0 conj.append( z3.ForAll( [pid], z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_ports() == z3.BitVecVal( 0, dt.size_t)))) # Correctness definition for `permutation` based refcount kernelstate.procs.nr_ports.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=lambda n: z3.BoolVal(True), max_refs=2**dt.uint16_t.size(), ownerfn=lambda port0: kernelstate.io[port0].owner) return z3.And(*conj)
def sys_create(self): fd = util.FreshBitVec('fd', dt.fd_t) fn = util.FreshBitVec('fn', dt.fn_t) type = util.FreshBitVec('type', dt.uint64_t) value = util.FreshBitVec('value', dt.uint64_t) omode = util.FreshBitVec('omode', dt.uint64_t) return (fd, fn, type, value, omode)
def _sys_map(): pid = util.FreshBitVec('pid', dt.pid_t) frm = util.FreshBitVec('from', dt.pn_t) index = util.FreshBitVec('index', dt.size_t) n = util.FreshBitVec('n', dt.size_t) perm = util.FreshBitVec('perm', dt.pte_t) return (pid, frm, index, n, perm)
def pages_equiv(conj, ctx, kernelstate): pn = util.FreshBitVec('pn', dt.pn_t) idx = util.FreshBitVec('page_index', 64) conj.append( z3.ForAll([pn, idx], z3.Implies( z3.And(is_pn_valid(pn), z3.ULT(idx, 512)), util.global_to_uf_dict(ctx, '@pages')[()]( util.i64(0), pn, idx) == kernelstate.pages[pn].data(idx)))) conj.append( z3.ForAll( [pn], z3.Implies( is_pn_valid(pn), util.global_field_element(ctx, '@page_desc_table', 'pid', pn) == kernelstate.pages[pn].owner))) conj.append( z3.ForAll( [pn], z3.Implies( is_pn_valid(pn), util.global_field_element(ctx, '@page_desc_table', 'type', pn) == kernelstate.pages[pn].type)))
def sys_send(self): pid = util.FreshBitVec('pid', dt.pid_t) val = util.FreshBitVec('val', dt.uint64_t) pn = util.FreshBitVec('pn', dt.pn_t) size = util.FreshBitVec('size', dt.size_t) fd = util.FreshBitVec('fd', dt.fd_t) return (pid, val, pn, size, fd)
def _sys_alloc(): pid = util.FreshBitVec('pid', dt.pid_t) frm = util.FreshBitVec('from', dt.pn_t) index = util.FreshBitVec('index', dt.size_t) to = util.FreshBitVec('to', dt.pn_t) perm = util.FreshBitVec('perm', dt.pte_t) return (pid, frm, index, to, perm)
def state_equiv(kernelstate, userstate): conj = [] pid = util.FreshBitVec('pid.eq', kdt.pid_t) idx1 = util.FreshBitVec('idx1.eq', kdt.size_t) idx2 = util.FreshBitVec('idx2.eq', kdt.size_t) idx3 = util.FreshBitVec('idx', kdt.size_t) idx4 = util.FreshBitVec('idx', kdt.size_t) conj.append(z3.ForAll([pid, idx1, idx2, idx3, idx4], z3.Implies( z3.And( kspec.is_pid_valid(pid), kspec.is_status_live(kernelstate.procs[pid].state), z3.ULT(idx1, 512), z3.ULT(idx2, 512), z3.ULT(idx3, 512), z3.ULT(idx4, 512), ), z3.And( pgwalk_rw(kernelstate, pid, idx1, idx2, idx3, idx4) == userstate.writable(pid, idx1, idx2, idx3, idx4) )))) return z3.And(*conj)
def spec_lemma_nr_dmapages_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) dmapn = util.FreshBitVec('dmapn', dt.dmapn_t) # General invariant -- a free dma page has no owner conj.append( z3.ForAll([dmapn], z3.Implies( is_dmapn_valid(dmapn), is_pid_valid(kernelstate.dmapages[dmapn].owner) == ( kernelstate.dmapages[dmapn].type != dt.page_type.PAGE_TYPE_FREE)))) # PROC_UNUSED state implies refcount is 0 (sys_clone needs this) conj.append( z3.ForAll( [pid], z3.Implies( is_pid_valid(pid), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_dmapages() == z3.BitVecVal( 0, dt.size_t))))) # # Correctness definition for `permutation` based refcount kernelstate.procs.nr_dmapages.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=is_dmapn_valid, max_refs=dt.NDMAPAGE, ownerfn=lambda dmapn: kernelstate.dmapages[dmapn].owner) return z3.And(*conj)
def spec_lemma_nr_devs_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) devid = util.FreshBitVec('devid', dt.devid_t) # unused procs don't own any devices conj.append( z3.ForAll([devid], z3.Implies( is_pid_valid(kernelstate.pci[devid].owner), kernelstate.procs[kernelstate.pci[devid].owner].state != dt.proc_state.PROC_UNUSED))) conj.append( z3.ForAll( [pid], z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_devs() == z3.BitVecVal(0, dt.size_t)))) # Correctness definition for `permutation` based refcount kernelstate.procs.nr_devs.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=lambda n: z3.BoolVal(True), max_refs=2**dt.devid_t.size(), ownerfn=lambda devid0: kernelstate.pci[devid0].owner) return z3.And(*conj)
def mmap_impl(old, current, va, perm): new = old idx1, idx2, idx3, idx4 = va # Pick a few pages -- we don't care how they are picked. pml4 = old.procs[current].page_table_root pdptpn = util.FreshBitVec('pdptpn', kdt.pn_t) pdpn = util.FreshBitVec('pdpn', kdt.pn_t) ptpn = util.FreshBitVec('ptpn', kdt.pn_t) framepn = util.FreshBitVec('framepn', kdt.pn_t) condpdpt, new = kspec.sys_alloc_pdpt(new, current, pml4, idx1, pdptpn, perm) condpdpt = z3.Or( condpdpt, z3.And( z3.ULT(idx1, 512), new.pages[pml4].pgtable_pn(idx1) == pdptpn, (new.pages[pml4].data(idx1) & kdt.PTE_P) != z3.BitVecVal( 0, kdt.size_t), new.pages[pml4].pgtable_perm(idx1) == perm, # The above implies this # new.pages[pml4].data(idx1) == (((z3.UDiv(new.pages_ptr_to_int, util.i64(4096)) + pdptpn) << kdt.PTE_PFN_SHIFT) | perm), )) condpd, new = kspec.sys_alloc_pd(new, current, pdptpn, idx2, pdpn, perm) condpd = z3.Or( condpd, z3.And( z3.ULT(idx2, 512), new.pages[pdptpn].pgtable_pn(idx2) == pdpn, (new.pages[pdptpn].data(idx2) & kdt.PTE_P) != z3.BitVecVal( 0, kdt.size_t), new.pages[pdptpn].pgtable_perm(idx2) == perm, )) condpt, new = kspec.sys_alloc_pt(new, current, pdpn, idx3, ptpn, perm) condpt = z3.Or( condpt, z3.And( z3.ULT(idx3, 512), new.pages[pdpn].pgtable_pn(idx3) == ptpn, (new.pages[pdpn].data(idx3) & kdt.PTE_P) != z3.BitVecVal( 0, kdt.size_t), new.pages[pdpn].pgtable_perm(idx3) == perm, )) condframe, new = kspec.sys_alloc_frame(new, current, ptpn, idx4, framepn, perm) cond = z3.And(condpdpt, condpd, condpt, condframe) return cond, util.If(cond, new, old)
def impl_invariants_c(ctx): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) pn = util.FreshBitVec('pn', dt.pn_t) fd = util.FreshBitVec('fd', dt.fd_t) try: old_solver = ctx.solver old_globals = ctx.globals def implies(ctx, a, b): return z3.Implies(a, b) def and_(ctx, *args): return z3.And(*args) def or_(ctx, *args): return z3.Or(*args) ctx.globals['@implies'] = implies ctx.globals['@and2'] = and_ ctx.globals['@and3'] = and_ ctx.globals['@and4'] = and_ ctx.globals['@and5'] = and_ ctx.globals['@and6'] = and_ ctx.globals['@and7'] = and_ ctx.globals['@and8'] = and_ ctx.globals['@and9'] = and_ ctx.globals['@or2'] = or_ ctx.globals['@or3'] = or_ ctx.globals['@or4'] = or_ ctx.solver = solver.Solver() ctx.solver.add(z3.BoolVal(False)) conj.append(z3.ForAll([pid], ctx.call('@inv_proc_owns_pns', pid))) conj.append(z3.ForAll([pid], ctx.call( '@inv_sleeping_proc_owns_ipc', pid))) conj.append(z3.ForAll([pid], ctx.call( '@inv_sleeping_proc_ipc_fd_valid_empty', pid))) conj.append(z3.ForAll([pid], ctx.call('@inv_proc_pns_valid', pid))) conj.append(z3.ForAll([pid], ctx.call('@inv_io_bitmap', pid))) conj.append(z3.ForAll([pn], ctx.call('@inv_page_owner', pn))) conj.append(z3.ForAll([pn], ctx.call('@inv_proc_unused_refs', pn))) conj.append(z3.ForAll([pid, fd], ctx.call( '@inv_proc_fds_valid', pid, fd))) conj.append(z3.ForAll([pn], ctx.call('@inv_page_freelist_valid', pn))) conj.append(z3.ForAll([pid], ctx.call('@inv_proc_freelist_valid', pid))) conj.append(ctx.call('@inv_current_valid')) conj.append(ctx.call('@inv_current_running')) finally: ctx.solver = old_solver ctx.globals = old_globals return z3.And(*conj)
def kk_send(self): pid = util.FreshBitVec('pid', dt.pid_t) s_len = util.FreshBitVec('s_len', dt.tU4) service=util.FreshBitVec('service',dt.tU2) # pn = util.FreshBitVec('pn', dt.pn_t) # size = util.FreshBitVec('size', dt.size_t) # fd = util.FreshBitVec('fd', dt.fd_t) #test = util.FreshBitVec('test', dt.test_t) #esbid = util.FreshBitVec('esbid', dt.esbid_t) # return (pid, val, pn, size, fd,test) return (pid,service,s_len)
def spec_lemma_nr_fds_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) fd = util.FreshBitVec('fd', dt.fd_t) # unused procs do not have any fds. # valid(pid) & state(pid)== PROC_UNUSED ==> pid.nr_fds == 0 conj.append( z3.ForAll( [pid], z3.Implies( is_pid_valid(pid), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_fds() == z3.BitVecVal( 0, dt.size_t))))) # unused procs do not have any opened files # valid(pid) & valid(fd) & state(pid) == PROC_UNUSED ==> !valid(openedfile(pid, fd)) conj.append( z3.ForAll( [pid, fd], z3.Implies( z3.And(is_pid_valid(pid), is_fd_valid(fd)), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, z3.Not(is_fn_valid(kernelstate.procs[pid].ofile(fd))))))) # a procs have opened a file, the state of this procs must not be UNUSED # valid(pid) & valid(fd) & valid(fn) ==> state(pid) != PROC_UNUSED conj.append( z3.ForAll( [pid, fd], z3.Implies( z3.And(is_pid_valid(pid), is_fd_valid(fd), is_fn_valid(kernelstate.procs[pid].ofile(fd))), kernelstate.procs[pid].state != dt.proc_state.PROC_UNUSED))) # Correctness definition for `permutation` based refcount kernelstate.procs.nr_fds.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=is_fd_valid, max_refs=dt.NOFILE, ownedby=lambda pid, fd: is_fn_valid(kernelstate.procs[pid].ofile(fd))) return z3.And(*conj)
def spec_lemma_nr_pages_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) # PROC_UNUSED state implies refcount is 0 (sys_clone needs this) conj.append( z3.ForAll( [pid], z3.Implies( is_pid_valid(pid), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_pages() == z3.BitVecVal( 0, dt.size_t))))) # Correctness definition for `permutation` based refcount kernelstate.procs.nr_pages.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=is_pn_valid, max_refs=dt.NPAGE, ownerfn=lambda pn: kernelstate.pages[pn].owner) return z3.And(*conj)
def spec_corollary_pgwalk(kernelstate): pid = util.FreshBitVec('pid', dt.pid_t) va = dt.FreshVA() pml4 = kernelstate.procs[pid].page_table_root # Abstract model of a page_walk starting from some root page, writable, present = page_walk(kernelstate, pml4, *va) # If a four level page-walk from some pid returns a page, # that page must be exclusively owned by the pid. # furthermore, if the page is writable, # it has to be a frame. isolation = util.Implies( present, kernelstate.pages[page].owner == pid, z3.Implies( writable, kernelstate.pages[page].type == dt.page_type.PAGE_TYPE_FRAME)) # valid(pid) & pid.state == active & valid(va) ==> page.owner == pid && page.type == FRAME (active is either EMBRYO, RUNNABLE or RUNNING) return z3.ForAll([pid] + va, z3.Implies( z3.And( is_pid_valid(pid), is_status_live(kernelstate.procs[pid].state), is_va_valid(va), ), isolation))
def intremaps_equiv(conj, ctx, kernelstate): index = util.FreshBitVec('index', dt.size_t) # intremap index conj.append( z3.ForAll([index], z3.Implies( is_intremap_valid(index), util.global_field_element( ctx, '@intremap_table', 'state', index) == kernelstate.intremaps[index].state))) conj.append( z3.ForAll([index], z3.Implies( is_intremap_valid(index), util.global_field_element( ctx, '@intremap_table', 'devid', index) == kernelstate.intremaps[index].devid))) conj.append( z3.ForAll([index], z3.Implies( is_intremap_valid(index), util.global_field_element( ctx, '@intremap_table', 'vector', index) == kernelstate.intremaps[index].vector)))
def test_fault(self): with self.assertRaises(util.NoReturn): self.ctx.call('@fault') pid = util.FreshBitVec('pid', dt.pid_t) s = self.state.copy() s.procs[s.current].killed = z3.BoolVal(True) newstate = spec.switch_proc(s, pid)[1] self._prove(z3.Exists([pid], spec.state_equiv(self.ctx, newstate)))
def spec_lemma_files_refcnt(kernelstate, syscall=None): conj = [] if syscall == 'clone_proc': conj.append(spec_lemma_nr_fds_refcnt(kernelstate)) pid = util.FreshBitVec('pid', dt.pid_t) fd = util.FreshBitVec('fd', dt.fd_t) kernelstate.files.refcnt.check(conj, is_owner_valid=is_fn_valid, is_owned1_valid=is_pid_valid, is_owned2_valid=is_fd_valid, max_refs=(dt.NPROC - 1) * dt.NOFILE, ownerfn=lambda pidfn: \ kernelstate.procs[pidfn[0]].ofile(pidfn[1])) return z3.And(*conj)
def vectors_equiv(conj, ctx, kernelstate): vector = util.FreshBitVec('vector', dt.uint8_t) conj.append( z3.ForAll([vector], util.global_to_uf_dict(ctx, '@vector_table')[()]( util.i64(0), z3.ZeroExt( 64 - vector.size(), vector)) == kernelstate.vectors[vector].owner))
def io_equiv(conj, ctx, kernelstate): port = util.FreshBitVec('port', dt.uint16_t) conj.append( z3.ForAll([port], util.global_to_uf_dict(ctx, '@io_table')[()]( util.i64(0), z3.ZeroExt(64 - port.size(), port)) == kernelstate.io[port].owner))
def pci_equiv(conj, ctx, kernelstate): devid = util.FreshBitVec('devid', dt.devid_t) conj.append( z3.ForAll([devid], util.global_to_uf_dict(ctx, '@pci_table')[()]( util.i64(0), z3.ZeroExt(64 - devid.size(), devid)) == kernelstate.pci[devid].owner))
def spec_lemma_nr_children_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) # pid has a parent <=> pid is not PROC_UNUSED # valid(pid) & valid(ppid) ==> state(pid) != PROC_UNUSED conj.append( z3.ForAll([pid], z3.Implies( is_pid_valid(pid), is_pid_valid(kernelstate.procs[pid].ppid) == ( kernelstate.procs[pid].state != dt.proc_state.PROC_UNUSED)))) # valid(pid) & state(pid) == PROC_UNUSED ==> !valid(ppid) conj.append( z3.ForAll( [pid], z3.Implies( is_pid_valid(pid), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, z3.Not(is_pid_valid(kernelstate.procs[pid].ppid)))))) # PROC_UNUSED state implies refcnt is 0 # valid(pid) & state(pid) == PROC_UNUSED ==> pid.nr_children == 0 conj.append( z3.ForAll( [pid], z3.Implies( is_pid_valid(pid), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_children() == z3.BitVecVal( 0, dt.size_t))))) # unused procs don't have a parent conj.append( z3.ForAll( [pid], z3.Implies( z3.And( is_pid_valid(pid), kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED), kernelstate.procs[pid].ppid == z3.BitVecVal(0, dt.pid_t)))) # Correctness definition for `permutation` based refcount kernelstate.procs.nr_children.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=is_pid_valid, max_refs=dt.NPROC - 1, ownerfn=lambda pid0: kernelstate.procs[pid0].ppid) return z3.And(*conj)
def spec_lemma_iommu_tlb_ok(kernelstate, oldstate=None): if kernelstate is oldstate or oldstate is None: return z3.BoolVal(True) pn = util.FreshBitVec('pn', dt.pn_t) idx = util.FreshBitVec('page_index', dt.size_t) return z3.ForAll( [pn, idx], z3.Implies( z3.And( # Arguments are valid is_pn_valid(pn), z3.ULT(idx, 512), is_iommu_page_table_type(oldstate.pages[pn].type)), z3.And( z3.Implies( oldstate.pages[pn].data(idx) != kernelstate.pages[pn].data(idx), kernelstate.iotlbinv))))
def newctx(): ctx = libirpy.newctx() # If we don't need the values of any constants we don't have to # initialize them, slightly faster execution time. ctx.eval.declare_global_constant = ctx.eval.declare_global_variable libirpy.initctx(ctx, hv6) ctx.globals['#tlbinv'] = util.FreshFunction('tlbinv', dt.pid_t, dt.bool_t) ctx.globals['#iotlbinv'] = util.FreshBool('iotlbinv') ctx.globals['@panic'] = panic ctx.globals['@bzero'] = bzero ctx.globals['@memset'] = memset ctx.globals['@memcpy'] = memcpy ctx.globals['@putchar'] = putchar ctx.globals['@hvm_set_cr3'] = hvm_set_cr3 ctx.globals['@hvm_copy'] = hvm_copy ctx.globals['@hvm_flush'] = hvm_flush ctx.globals['@hvm_set_timer'] = hvm_set_timer ctx.globals['@hvm_set_io_bitmap'] = hvm_set_io_bitmap ctx.globals['@hvm_invalidate_tlb'] = hvm_invalidate_tlb ctx.globals['@hvm_switch'] = hvm_switch ctx.globals['@pdb'] = pdb ctx.globals['@syslog'] = syslog ### after ctx.globals['@libs_cprintf'] = libs_cprintf # iommu fns ctx.globals['@iommu_set_dev_root'] = iommu_set_dev_root ctx.globals['@iommu_get_dev_root'] = iommu_get_dev_root ctx.globals['@iommu_set_intremap'] = iommu_set_intremap ctx.globals['@iommu_reset_intremap'] = iommu_reset_intremap ctx.globals['@iommu_reset_dev_root'] = iommu_reset_dev_root ctx.globals['@iommu_flush'] = iommu_flush ctx.globals['@iommu_hack_root'] = iommu_hack_root ctx.globals['@iommu_entry'] = iommu_entry ctx.globals['@ms_to_cycles'] = ms_to_cycles # Provide the "integer value" of some globals ctx.ptr_to_int[ctx.globals['@pages']._ref._name] = util.FreshBitVec( '(uintptr)@pages', 64) ctx.ptr_to_int[ctx.globals['@proc_table']._ref._name] = util.FreshBitVec( '(uintptr)@proc_table', 64) ctx.ptr_to_int[ ctx.globals['@page_desc_table']._ref._name] = util.FreshBitVec( '(uintptr)@page_desc_table', 64) ctx.ptr_to_int[ctx.globals['@file_table']._ref._name] = util.FreshBitVec( '(uintptr)@file_table', 64) ctx.ptr_to_int[ctx.globals['@devices']._ref._name] = util.FreshBitVec( '(uintptr)@devices', 64) ctx.ptr_to_int[ctx.globals['@devices']._ref._name] = util.FreshBitVec( '(uintptr)@devices', 64) ctx.ptr_to_int[ctx.globals['@dmapages']._ref._name] = util.FreshBitVec( '(uintptr)@dmapages', 64) return ctx
def spec_lemma_nr_fds_refcnt(kernelstate): conj = [] pid = util.FreshBitVec('pid', dt.pid_t) fd = util.FreshBitVec('fd', dt.fd_t) conj.append( z3.ForAll( [pid], z3.Implies( is_pid_valid(pid), z3.Implies( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, kernelstate.procs[pid].nr_fds() == 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( kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED, z3.Not(is_fn_valid(kernelstate.procs[pid].ofile(fd))))))) conj.append( z3.ForAll( [pid, fd], z3.Implies( z3.And(is_pid_valid(pid), is_fd_valid(fd), is_fn_valid(kernelstate.procs[pid].ofile(fd))), kernelstate.procs[pid].state != dt.proc_state.PROC_UNUSED))) kernelstate.procs.nr_fds.check( conj, is_owner_valid=is_pid_valid, is_owned_valid=is_fd_valid, max_refs=dt.NOFILE, ownedby=lambda pid, fd: is_fn_valid(kernelstate.procs[pid].ofile(fd))) return z3.And(*conj)
def new(self): if self.get_arity() == 0: types = self.get_types() assert len(types) == 1 typ = types[0] if typ == z3.BoolSort(): value = util.FreshBool(self._prefix + self._name) else: value = util.FreshBitVec(self._prefix + self._name, typ) else: value = util.FreshFunction(self._prefix + self._name, *self.get_types()) return value
def sys_call(self): pid = util.FreshBitVec('pid', dt.pid_t) val = util.FreshBitVec('val', dt.uint64_t) inpn = util.FreshBitVec('inpn', dt.pn_t) size = util.FreshBitVec('size', dt.size_t) outpn = util.FreshBitVec('outpn', dt.pn_t) outfd = util.FreshBitVec('outfd', dt.fd_t) return (pid, val, inpn, size, outpn, outfd)
def sys_map_page(self): pid = util.FreshBitVec('pid', dt.pid_t) frm = util.FreshBitVec('from', dt.pn_t) index = util.FreshBitVec('index', dt.size_t) pa = util.FreshBitVec('pa', dt.size_t) perm = util.FreshBitVec('perm', dt.pte_t) from_type = util.FreshBitVec('from_type', dt.uint64_t) return (pid, frm, index, pa, perm, from_type)
def test_mmap_writable(self): kstate = kdt.KernelState() ustate = dt.UserState() self.solver.add(spec.state_equiv(kstate, ustate)) self.solver.add(kspec.spec_invariants(kstate)) self.solver.add(kspec.spec_lemma_isolation(kstate)) current = kstate.current idx1 = util.FreshBitVec('idx1', kdt.size_t) idx2 = util.FreshBitVec('idx2', kdt.size_t) idx3 = util.FreshBitVec('idx3', kdt.size_t) idx4 = util.FreshBitVec('idx4', kdt.size_t) kcond, nkstate = mmap_impl(kstate, current, (idx1, idx2, idx3, idx4), kdt.PTE_P | kdt.PTE_W) ucond, nustate = mmap_spec(ustate, current, (idx1, idx2, idx3, idx4), kdt.PTE_P | kdt.PTE_W) self._prove( z3.Implies(z3.And(kcond == ucond), spec.state_equiv(nkstate, nustate)))
def get_sub_type(type): return util.If( type == dt.page_type.PAGE_TYPE_X86_PML4, dt.page_type.PAGE_TYPE_X86_PDPT, util.If( type == dt.page_type.PAGE_TYPE_X86_PDPT, dt.page_type.PAGE_TYPE_X86_PD, util.If( type == dt.page_type.PAGE_TYPE_X86_PD, dt.page_type.PAGE_TYPE_X86_PT, util.If( type == dt.page_type.PAGE_TYPE_X86_PT, dt.page_type.PAGE_TYPE_FRAME, util.FreshBitVec('invalid', dt.page_type.PAGE_TYPE_FRAME.size())))))