def get_initramfs_address(xml_spec): """ Return virtual address of initramfs so its mapped directly adjacent to the existing initramfs. """ phys_regions = xml_spec.xpath("/system/memory/memory" + "[@type='subject_initrd']") if len(phys_regions) > 1: print("Warning: Muen system policy has multiple initramfs regions.") return None if len(phys_regions) == 0: return muutils.int_to_ada_hex(INITRAMFS_VIRTUAL_ADDRESS) phys_name = phys_regions[0].attrib['name'].lower() mems = xml_spec.xpath( "/system/subjects/subject/memory/memory[@physical='" + phys_name + "']") if len(mems) == 0: return muutils.int_to_ada_hex(INITRAMFS_VIRTUAL_ADDRESS) size = muutils.ada_hex_to_int(phys_regions[0].attrib['size']) virtual_address = mems[0].attrib['virtualAddress'] for mapping in mems: if mapping.attrib['virtualAddress'] != virtual_address: print("Warning: Initramfs mappings not at same virtual address.") return None new_address = muutils.ada_hex_to_int(virtual_address) + size return muutils.int_to_ada_hex(new_address)
def set_rip(xml_spec, binary): """ Set RIP in XML spec to entry point of given ELF binary. """ rip = src_spec.xpath("/component/requires/vcpu/registers/gpr/rip")[0] rip.text = muutils.int_to_ada_hex(binary.header.entrypoint) print("* Setting RIP to " + rip.text)
def add_channel(name, channels): """ Add channel reader/writer XML elements for Solo5 device with given name. """ global chanAddr, chanSize print("* Adding channels for device '" + name + "'") channels.append( etree.Element("reader", logical=name + "|in", virtualAddress=muutils.int_to_ada_hex(chanAddr), size=muutils.int_to_ada_hex(chanSize))) chanAddr += chanSize channels.append( etree.Element("writer", logical=name + "|out", virtualAddress=muutils.int_to_ada_hex(chanAddr), size=muutils.int_to_ada_hex(chanSize))) chanAddr += chanSize
def add_ram_memory(xml_spec, binary, binary_end, ram_size_mb): """ Add RAM memory region of given size and set RSP to top of RAM in XML spec. """ print("* Adding RAM region with size " + str(ram_size_mb) + " MB") ram_size = ram_size_mb * 2**20 provides = src_spec.xpath("/component/provides")[0] etree.SubElement(provides, "memory", logical="ram", virtualAddress=muutils.int_to_ada_hex(binary_end), size=muutils.int_to_ada_hex(ram_size), executable="false", writable="true", type="subject") rsp = src_spec.xpath("/component/requires/vcpu/registers/gpr/rsp")[0] rsp.text = muutils.int_to_ada_hex(binary_end + ram_size - 8) print("* Setting RSP to " + rsp.text)
def add_provides_memory(xml_spec, name, region_type, address, filename, size, executable, writable): """ Add file-backed memory region with given name and size to <provides> section of XML spec. The size is rounded up to the next 4K. """ provides = xml_spec.xpath("/component/provides")[0] mem_size = size mem_size -= mem_size % -4096 print("* Adding '" + name + "' region with size " + str(mem_size) + " bytes, address " + address + ", type " + region_type) mem = etree.Element("memory", logical=name, virtualAddress=address, size=muutils.int_to_ada_hex(mem_size), executable=executable, writable=writable, type=region_type) etree.SubElement(mem, "file", filename=filename, offset="none") provides.append(mem)
def add_linux_channels(doc, comp_channels, subject_name): """ Add logcal channels for given component channels to Linux subject. """ subj_channels = doc.xpath("/system/subjects/subject[@name='" + LINUX_NAME + "']/channels")[0] address = LINUX_BASE_ADDR for comp_chan in comp_channels: # Flip channel role chan_type = "reader" if comp_chan.tag == "writer" else "writer" log_name = comp_chan.get("logical") size = muutils.ada_hex_to_int(comp_chan.get("size")) phys_name = subject_name + "_" + log_name.replace('|', '_') addr_str = muutils.int_to_ada_hex(address) print("* Adding NIC Linux channel " + chan_type + " '" + phys_name + "' @ " + addr_str) etree.SubElement(subj_channels, chan_type, logical=log_name, physical=phys_name, virtualAddress=addr_str) address += size
def add_elf_memory(xml_spec, binary, filename): """ Add memory regions for given ELF binary with specified name to <requires> section of XML spec. Each ELF segment of type LOAD is processed with the region name being a concatenation of contained ELF section names, truncated to fit the maximum name length after expansion to physical memory regions. Returns the virtual end address of the highest binary memory region. """ global comp_name # Component name+'|' is prepended to physical names of required resources max_len = MAX_NAME_LEN - (len(comp_name) + 1) end_addr = 0 provides = xml_spec.xpath("/component/provides")[0] for segment in binary.segments: if segment.type == ELF.SEGMENT_TYPES.LOAD: sections = segment.sections if len(sections) == 0: continue n = "+".join([section.name for section in sections]) mem_name = (n[:max_len - 2] + '..') if len(n) > max_len else n print("* Adding memory region '" + mem_name + "'") w = ELF.SEGMENT_FLAGS.W in segment x = ELF.SEGMENT_FLAGS.X in segment virtual_addr = segment.virtual_address phy_size = segment.physical_size # Round up to page size phy_size -= phy_size % -4096 vaddr_str = muutils.int_to_ada_hex(virtual_addr) offset_str = muutils.int_to_ada_hex(segment.file_offset) mem = etree.Element("memory", logical=mem_name, virtualAddress=vaddr_str, size=muutils.int_to_ada_hex(phy_size), executable=muutils.bool_to_str(x), writable=muutils.bool_to_str(w), type="subject_binary") etree.SubElement(mem, "file", filename=filename, offset=offset_str) provides.append(mem) # Add fill region if virtual_size is larger than physical_size mem_size = segment.virtual_size mem_size -= mem_size % -4096 if phy_size < mem_size: vaddr = virtual_addr + phy_size vaddr_str = muutils.int_to_ada_hex(vaddr) size_str = muutils.int_to_ada_hex(mem_size - phy_size) print("* Adding memory region '" + mem_name + "|fill'") mem = etree.Element("memory", logical=mem_name + "|fill", virtualAddress=vaddr_str, size=size_str, executable=muutils.bool_to_str(x), writable=muutils.bool_to_str(w), type="subject_binary") etree.SubElement(mem, "fill", pattern="16#00#") provides.append(mem) end_addr = segment.virtual_address + mem_size return end_addr
is_file = content_node.tag == 'file' if is_file: f_offset = content_node.get('offset') if f_offset != 'none': offset = f_offset t = node.get('type') content_size = content_node.get('size') if not content_size: sys.exit('Error: No size attribute in file node, ' 'use mucfgmemhashes to add one') offset_nr = muutils.ada_hex_to_int(offset) size_nr = muutils.ada_hex_to_int(size) content_size_nr = muutils.ada_hex_to_int(content_size) - offset_nr usage = str( ((content_size_nr * 100) + (size_nr - 1)) / size_nr) + '%' content_size = muutils.int_to_ada_hex(content_size_nr) content = content_node.get('filename') else: t = 'fill_pattern' content = content_node.get('pattern') content_size = size f.write(name + ';' + addr + ';' + size + ';' + offset + ';' + content_size + ';' + usage + ';' + t + ';' + content + '\n')