Re: [RFC,PATCH 1/2] seccomp_filters: system call filtering using BPF

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For anyone who is interested I hacked up a program to turn what I think
is a readable seccomp syntax into BPF rules.  It should make it easier
to prototype this new thing.  The translator needs a LOT of love to be
worth much, but for now it can handle a couple of things and can build a
set of rules!

The rules are of the form:
label object:
	value label

So using Will's BPF example code in my syntax looks like:

start syscall:
        rt_sigreturn success
        sigreturn success
        exit_group success
        exit success
        read read
        write write
read arg0:
        0 success
write arg0:
        1 success
        2 success

So this says the first label is "start" and it is going to deal with the
syscall number.  The first value is 'rt_sigreturn' and if syscall ==
rt_sigreturn will cause you to jump to 'success' (success and fail are
implied labels).  If the syscall is 'write' we will jump to 'write.'
The write rules look at arg0.  If arg0 == "1" we jump to "success".  If
you run that syntax through my translator you should get Will's BPF
rules!

You'll quickly notice that the translator only understands "syscall" and
"arg0" and only x86_32, but it should be easy to add more, support the
right registers on different arches, etc, etc.  If others think they
might want to hack on the translator I put it at:

http://git.infradead.org/users/eparis/bpf-translate.git

-Eric
#! /usr/bin/python -Es

import sys

if len(sys.argv) > 1:
	file = open(sys.argv[1])
else:
	file = sys.stdin

linecount = 0
sections = []
rules = {}
output = []
section_map = {}

def new_section(section):
	if section[1] == "syscall":
		output.append(("BPF_STMT(BPF_LD+BPF_W+BPF_IND, regoffset(orig_eax)),", section[0]))
	elif section[1] == "arg0":
		output.append(("BPF_STMT(BPF_LD+BPF_W+BPF_IND, regoffset(ebx)),", section[0]))
	elif section[0] == "success":
		output.append(("BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),", section[0]))
	elif section[0] == "fail":
		output.append(("BPF_STMT(BPF_RET+BPF_A,0),", section[0]))

def new_rule(rule, section, last=None):
	string = "BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, %s, %s, 0)," % (rule[0], rule[1])
	if last:
		string = string.replace(", 0)", ", fail)")
	output.append((string, "0"))

if __name__ == '__main__':
	while 1:
		line = file.readline()
		if not line:
			break
		linecount = linecount + 1
		if ":" in line:
			sections.append(line.strip().strip(":").split())
		else:
			key = sections[-1][0]
			current_list = rules.get(key, [])
			newrule = line.strip().split()
			if sections[-1][1] == "syscall":
				newrule = ["__NR_%s" % newrule[0], newrule[1]]
			current_list.append(newrule)
			rules[key] = current_list
			
		

sections.append(["success", "*"])
sections.append(["fail", "*"])

for section in sections:
	new_section(section)
	if rules.has_key(section[0]):
		for rule in rules[section[0]]:
			if rule == rules[section[0]][-1]:
				new_rule(rule, section, 1)
			else:
				new_rule(rule, section)

for lineno,line in enumerate(output):
	if (line[1] == "0"):
		continue
	section_map[line[1]] = lineno

for lineno,line in enumerate(output):
	line = line[0]
	for section in section_map.keys():
		# Only replace in those last 2 commas 
		#if VALUE == section:
			#replace VALUE with str(section_map[section] - lineno - 2)
		splitline = line.split(",")
		if section in splitline[-3]:
			splitline[-3] = splitline[-3].replace(section, str(section_map[section] - lineno - 1))
		if section in splitline[-2]:
			splitline[-2] = splitline[-2].replace(section, str(section_map[section] - lineno - 1))
		line = ",".join(splitline)
	print line

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux