Exemple #1
0
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)
Exemple #2
0
 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)
Exemple #3
0
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)))
Exemple #5
0
 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)
Exemple #6
0
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)
Exemple #8
0
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)
Exemple #9
0
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)
Exemple #10
0
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)
Exemple #12
0
 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)
Exemple #13
0
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)
Exemple #14
0
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)
Exemple #15
0
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)))
Exemple #17
0
 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)))
Exemple #18
0
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))
Exemple #22
0
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)
Exemple #23
0
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))))
Exemple #24
0
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
Exemple #25
0
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)
Exemple #26
0
 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
Exemple #27
0
 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)
Exemple #28
0
 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)
Exemple #29
0
    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())))))