Skip to content

Commit

Permalink
Work on proxy elfbac policy, some moving around
Browse files Browse the repository at this point in the history
  • Loading branch information
mjkoo committed Jan 6, 2016
1 parent c2e902e commit 7647f62
Show file tree
Hide file tree
Showing 51 changed files with 63 additions and 88 deletions.
7 changes: 7 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[submodule "tools/elfbac-ld/examples/hammer"]
path = tools/elfbac-ld/examples/hammer
url = https://github.com/pesco/hammer.git
[submodule "tools/elfbac-ld/examples/proxy"]
path = tools/elfbac-ld/examples/proxy
url = https://github.com/mjkoo/proxy.git
branch = elfbac
12 changes: 6 additions & 6 deletions linux/arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,18 +267,18 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
unsigned char *copy_page = NULL;

/* From access_error above */
unsigned int mask = VM_READ;
unsigned int access = VM_READ;

if (fsr & FSR_WRITE)
mask = VM_WRITE;
access = VM_WRITE;
if (fsr & FSR_LNX_PF)
mask = VM_EXEC;
access = VM_EXEC;

fault = VM_FAULT_BADACCESS;

spin_lock_irqsave(&mm->elfbac_policy->lock, sflags);

if (!elfbac_access_ok(mm->elfbac_policy, addr, mask, regs->ARM_lr,
if (!elfbac_access_ok(mm->elfbac_policy, addr, access, regs->ARM_lr,
&next_state, &access_flags, &copy_size)) {
if ((vma->vm_flags & VM_GROWSDOWN)) {
access_flags = VM_READ | VM_WRITE;
Expand All @@ -288,8 +288,8 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
// permissions to all states. Also handle vdso pages above stack.
access_flags = vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC);
} else {
printk("GOT ELFBAC VIOLATION: state: %ld, addr: %08lx, pc: %lx, mask: %x\n",
mm->elfbac_policy->current_state->id, addr, regs->ARM_pc, mask);
printk("GOT ELFBAC VIOLATION: state: %ld, addr: %08lx, pc: %lx, access: %x\n",
mm->elfbac_policy->current_state->id, addr, regs->ARM_pc, access);

spin_unlock_irqrestore(&mm->elfbac_policy->lock, sflags);
goto out;
Expand Down
2 changes: 1 addition & 1 deletion linux/include/linux/elfbac.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/* Define an upper bound on policy size to prevent exhausting kernel resources,
* can re-examine this later. */
#define ELFBAC_POLICY_SIZE_MAX (PAGE_SIZE)
#define ELFBAC_NUM_STATES_MAX (0xff)
#define ELFBAC_NUM_STATES_MAX (0x100)
#define ELFBAC_UNDEFINED_STATE_ID (ULONG_MAX)
#define PT_ELFBAC_POLICY (PT_LOOS + 0xfe7fbac)

Expand Down
6 changes: 3 additions & 3 deletions linux/kernel/elfbac.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ bool elfbac_access_ok(struct elfbac_policy *policy, unsigned long addr,

// Check for return from a call transition
// TODO: Need 1 return_state_id per state per task for shared policies
if ((mask & VM_EXEC) && addr == policy->current_state->return_addr &&
if ((mask & VM_EXEC) && addr == (policy->current_state->return_addr & ~1) &&
policy->current_state->return_state_id != ELFBAC_UNDEFINED_STATE_ID) {
state = get_state_by_id(policy, policy->current_state->return_state_id);
if (state) {
Expand Down Expand Up @@ -888,10 +888,10 @@ bool elfbac_access_ok(struct elfbac_policy *policy, unsigned long addr,
if (!state)
continue;

if (call_transition->addr == addr) {
if ((call_transition->addr & ~1) == addr) {
*next_state = state;
*copy_size = call_transition->param_size;
state->return_addr = lr;
state->return_addr = lr & ~1;
state->return_size = call_transition->return_size;
state->return_state_id = policy->current_state->id;
goto good_transition;
Expand Down
4 changes: 0 additions & 4 deletions tools/.gitignore

This file was deleted.

File renamed without changes.
78 changes: 43 additions & 35 deletions tools/elfbac-ld.py → tools/elfbac-ld/elfbac-ld.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import tempfile

from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

def is_bss(description):
sections = description.split(' ')
Expand Down Expand Up @@ -79,11 +80,11 @@ def generate_binary_policy(policy, section_map, symbol_map, must_resolve=True, v
CALL_TRANSITION = 4

chunks = []
states = policy['states']
states_ = policy['states']
data_transitions = policy.get('data_transitions', [])
call_transitions = policy.get('call_transitions', [])
state_names = [s['name'] for s in states]
stack_names = stable_unique([s['stack'] for s in states])
state_names = [s['name'] for s in states_]
stack_names = stable_unique([s['stack'] for s in states_])

if verbose:
print '=' * 80
Expand All @@ -92,6 +93,11 @@ def generate_binary_policy(policy, section_map, symbol_map, must_resolve=True, v
chunks.append(struct.pack('<I', len(stack_names)))

# Pack states
states = list(states_)
if 'start' in state_names:
states.insert(0, states.pop(state_names.index('start')))
state_names = [s['name'] for s in states]

for state in states:
if verbose:
print 'State %s:' % state['name']
Expand Down Expand Up @@ -120,6 +126,30 @@ def generate_binary_policy(policy, section_map, symbol_map, must_resolve=True, v

chunks.append(struct.pack('<IIII', SECTION, base, size, flags))

# Pack call transitions
for transition in call_transitions:
from_state = state_names.index(transition['from'])
to_state = state_names.index(transition['to'])
param_size = int(transition['param_size'])
return_size = int(transition['return_size'])

address_symbol = transition['address']

if re.match(r'0x[0-9a-f]+', address_symbol):
address = int(address_symbol, 16)
else:
address = symbol_map.get(address_symbol, 0)

if must_resolve and not address:
raise KeyError('Error resolving call transition at %s' % address_symbol)

if verbose:
print 'Call Transition from %08x->%08x on %x,%x,%x' % (from_state, to_state,
address, param_size, return_size)

chunks.append(struct.pack('<IIIIII', CALL_TRANSITION, from_state, to_state,
address, param_size, return_size))

# Pack data transitions
for transition in data_transitions:
from_state = state_names.index(transition['from'])
Expand All @@ -134,7 +164,7 @@ def generate_binary_policy(policy, section_map, symbol_map, must_resolve=True, v
base = symbol_map.get(base_symbol, 0)

if must_resolve and not base:
raise KeyError('Error resolving call transition at %s' % base_symbol)
raise KeyError('Error resolving data transition at %s' % base_symbol)

flags = 0
flags |= (0x1 if 'r' in transition['flags'] else 0)
Expand All @@ -148,30 +178,6 @@ def generate_binary_policy(policy, section_map, symbol_map, must_resolve=True, v
chunks.append(struct.pack('<IIIIII', DATA_TRANSITION, from_state, to_state,
base, size, flags))

# Pack call transitions
for transition in call_transitions:
from_state = state_names.index(transition['from'])
to_state = state_names.index(transition['to'])
param_size = int(transition['param_size'])
return_size = int(transition['return_size'])

address_symbol = transition['address']

if re.match(r'0x[0-9a-f]+', address_symbol):
address = int(address_symbol, 16)
else:
address = symbol_map.get(address_symbol, 0)

if must_resolve and not address:
raise KeyError('Error resolving data transition at %s' % address_symbol)

if verbose:
print 'Call Transition from %08x->%08x on %x,%x,%x' % (from_state, to_state,
address, param_size, return_size)

chunks.append(struct.pack('<IIIIII', CALL_TRANSITION, from_state, to_state,
address, param_size, return_size))

if verbose:
print '=' * 80

Expand All @@ -191,14 +197,11 @@ def parse_link_map(link_map):

# Find all allocated sections minus our stub policy section and return their
# addresses and sizes in a map
sections = re.findall(r'^(\.[a-zA-Z0-9_.]+)\s+(0x[a-f0-9]+)\s+(0x[a-f0-9]+)\s+.*$', link_map, re.MULTILINE)
section_map = { name: (int(address, 16), int(size, 16)) for (name, address, size) in sections \
sections = re.findall(r'^((\.|__)[a-zA-Z0-9_.]+)\s+(0x[a-f0-9]+)\s+(0x[a-f0-9]+)\s+.*$', link_map, re.MULTILINE)
section_map = { name: (int(address, 16), int(size, 16)) for (name, _, address, size) in sections \
if name != '.elfbac' and int(size, 16) > 0 }

symbols = re.findall(r'^ {16}(0x[a-f0-9]+)\s+(\w+)$', link_map, re.MULTILINE)
symbol_map = { name: int(address, 16) for (address, name) in symbols }

return (section_map, symbol_map)
return section_map

def main(argv=None):
if argv is None:
Expand Down Expand Up @@ -244,16 +247,21 @@ def main(argv=None):
cmd = [args.linker] + args.linker_args + \
['-Wl,' + arg if args.use_compiler else arg for arg in ['-M', '-T', f.name]]
link_map = subprocess.check_output(cmd)
section_map, symbol_map = parse_link_map(link_map)
section_map = parse_link_map(link_map)

# TODO: make sure our heuristic for finding this doesn't clobber something
symbol_map = {}
if os.path.exists(output_file):
with open(output_file, 'rb') as f:
contents = f.read()
f.seek(0, 0)
ef = ELFFile(f)
elfbac_section = ef.get_section_by_name('.elfbac')

symbol_table_section = [s for s in ef.iter_sections() if isinstance(s, SymbolTableSection)][0]
assert(symbol_table_section['sh_size'] > 0)
symbol_map = { s.name: s['st_value'] for s in symbol_table_section.iter_symbols() }

assert(elfbac_section['sh_size'] == policy_len)
offset = elfbac_section['sh_offset']

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
*.d
*_nopol
*_pol
*/Makefile

File renamed without changes.
1 change: 1 addition & 0 deletions tools/elfbac-ld/examples/hammer
Submodule hammer added at a1d86f
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions tools/elfbac-ld/examples/proxy
Submodule proxy added at a6d3f0
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
{
"name": "libc",
"stack": "stack1",
"stack": "stack2",
"sections" : [
{ "name": ".data.buf", "create": false, "flags": "rw" },
{ "name": ".data.xxx", "create": false, "flags": "rw" },
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion tools/examples/proxy/link.txt

This file was deleted.

36 changes: 0 additions & 36 deletions tools/examples/proxy/policy.json

This file was deleted.

0 comments on commit 7647f62

Please sign in to comment.