From 3af510b4d1db129b9bf93305a338e0c2c1e2da19 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 1 Apr 2008 22:11:31 -0400 Subject: [PATCH] removing abandoned experiment: safety/* disassembly/symbol checks --- ChangeLog | 4 + safety/README | 10 -- safety/data/opcodes-i686 | 107 ---------------- safety/data/opcodes-ia64 | 89 -------------- safety/data/opcodes-x86_64 | 104 ---------------- safety/data/references | 94 -------------- safety/safety.py | 245 ------------------------------------- 7 files changed, 4 insertions(+), 649 deletions(-) delete mode 100644 safety/README delete mode 100644 safety/data/opcodes-i686 delete mode 100644 safety/data/opcodes-ia64 delete mode 100644 safety/data/opcodes-x86_64 delete mode 100644 safety/data/references delete mode 100755 safety/safety.py diff --git a/ChangeLog b/ChangeLog index 8eb412500..ad9613758 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-04-01 Frank Ch. Eigler + + * safety/*: Removed subdirectory containing abandoned experiment. + 2008-03-31 Frank Ch. Eigler * configure.ac: Bump version to 0.7. diff --git a/safety/README b/safety/README deleted file mode 100644 index 61eda4a2b..000000000 --- a/safety/README +++ /dev/null @@ -1,10 +0,0 @@ -This is a static safety-checker for SystemTap modules. It attempts to -validate modules by checking the opcodes used and the external references -against a whitelist. - -The script relies on external data files to provide the whitelists, which by -default are in the /data directory. The 'references' file -provides a plain list of allowed references. The 'opcodes' file provides a -list of regular expressions that match allowed opcodes. Either data file may -have an optional kernel and/or architecture suffix, as in 'opcodes-i686' or -'references-2.6.9-32.ELsmp-x86_64'. diff --git a/safety/data/opcodes-i686 b/safety/data/opcodes-i686 deleted file mode 100644 index 123fa2b05..000000000 --- a/safety/data/opcodes-i686 +++ /dev/null @@ -1,107 +0,0 @@ -aaa -aad -aam -aas -adc[bwl]? -add[bwl]? -and[bwl]? -bound[wl]? -bsf[wl]? -bsr[wl]? -bswapl? -btc[wl]? -btr[wl]? -bts[wl]? -bt[wl]? -call -cbtw -cbw -cdq -clc -cld -cli -cltd -cmc -cmovn?(?:a|ae|b|be|c|e|g|ge|l|le|o|p|pe|po|s|z)[wl]? -cmp[bwl]? -cmps[bwl]? -cmpxchg8b -cmpxchg[bwl]? -cpuid -cwd -cwde -cwtd -cwtl -daa -das -dec[bwl]? -div[bwl]? -enter -idiv[bwl]? -imul[bwl]? -inc[bwl]? -je?cxz -jmp -jn?(?:a|ae|b|be|c|e|g|ge|l|le|o|p|pe|po|s|z) -lcall -lds[wl]? -leave -lea[wl]? -les[wl]? -lfence -lfs[wl]? -lgs[wl]? -lods[bwl]? -loopn?[ze]? -lret -lss[wl]? -mfence -movaps -mov[bwl]? -movs[bwl]? -movsb[wl]? -movswl? -movzb[wl]? -movzwl? -mul[bwl]? -neg[bwl]? -nop -not[bwl]? -or[bwl]? -pause -popa[wl]? -popf[wl]? -pop[wl]? -prefetch(?:t[012]|nta) -pusha[wl]? -pushf[wl]? -push[wl]? -rcl[bwl]? -rcr[bwl]? -rdmsr -rdtsc -ret -rol[bwl]? -ror[bwl]? -sahf -sal[bwl]? -sar[bwl]? -sbb[bwl]? -scas[bwl]? -setn?(?:a|ae|b|be|c|e|g|ge|l|le|o|p|pe|po|s|z) -shl[bwl]? -shld[bwl]? -shr[bwl]? -shrd[bwl]? -smov[lw]? -stc -std -sti -stos[bwl]? -sub[bwl]? -test[bwl]? -xadd[bwl]? -xchg[bwl]? -xlat -xlatb -xor[bwl]? diff --git a/safety/data/opcodes-ia64 b/safety/data/opcodes-ia64 deleted file mode 100644 index edb1792e9..000000000 --- a/safety/data/opcodes-ia64 +++ /dev/null @@ -1,89 +0,0 @@ -add[sl]? -addp4 -alloc -and -andcm -br(?:\.cond)?(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.cond(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.call(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.ret(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.cloop(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.ctop(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.cexit(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.wtop(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -br\.wexit(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -brl(?:\.cond)?(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -brl\.call(?:\.(?:spnt|sptk|dpnt|dptk))?(?:\.(?:few|many))?(?:\.clr)? -brp(?:\.(?:sptk|loop|exit|dptk))(?:\.imp)? -brp\.ret(?:\.(?:sptk|loop|exit|dptk))(?:\.imp)? -chk\.s(?:\.[im])? -chk\.a\.(?:clr|nc) -clrrrb -cmp\.(?:eq|ne|l[te]u?|g[te]u?)(?:\.(?:unc|or|and|or.andcm|orcm|andcm|and.orcm))? -cmp4\.(?:eq|ne|l[te]u?|g[te]u?)(?:\.(?:unc|or|and|or.andcm|orcm|andcm|and.orcm))? -cmpxchg[1248]\.(?:acq|rel)(?:\.nt[1a])? -cmp8xchg16\.(?:acq|rel)(?:\.nt[1a])? -cover -czx[12]\.[lr] -dep(?:\.z)? -extr(?:\.u)? -fetchadd[48]\.(?:acq|rel)(?:\.nt[1a])? -getf\.(?:s|d|exp|sig) -hint(?:\.[ibmfx])? -ld[1248](?:\.(?:s|a|sa|c\.nc|c\.clr|c\.clr\.acq|acq|bias))?(?:\.nt[1a])? -ld8\.fill(?:\.nt[1a])? -ld16(?:\.acq)?(?:\.nt[1a])? -ldf8(?:\.(?:s|a|sa|c\.nc|c\.clr))?(?:\.nt[1a])? -lfetch(?:.fault)?(?:\.excl)?(?:\.nt[12a])? -mf -mix[124]\.[lr] -mov(?:\.[im])? -mov(?:\.ret)?(?:\.sptk|\.dptk)?(?:\.imp)? -movl -mux[12] -nop(?:\.[ibmfx])? -or -pack2\.[us]ss -pack4.sss -padd[124] -padd[12]\.(?:sss|uus|uuu) -pavg[12](?:\.raz) -pavgsub[12] -pcmp[124]\.(?:eq|gt) -pmax1\.u -pmax2 -pmin1\.u -pmin2 -pmpy2\.[rl] -pmpyshr2(?:\.u)? -popcnt -psad1 -pshl[24] -pshladd2 -pshr[24](?:\.u)? -pshradd2 -psub[124] -psub[12]\.(?:sss|uus|uuu) -rsm -setf\.(?:s|d|exp|sig) -shl -shladd -shladdp4 -shr(?:\.u)? -shrp -srlz\.[id] -ssm -st[1248](?:\.rel)?(?:\.nta)? -st16(?:\.rel)?(?:\.nta)? -st8\.spill(?:\.nta)? -stf8(?:\.nta)? -sub -sxt[124] -tbit\.n?z(?:\.(?:unc|or|and|or.andcm|orcm|andcm|and.orcm))? -tnat\.n?z(?:\.(?:unc|or|and|or.andcm|orcm|andcm|and.orcm))? -unpack[124]\.[hl] -xchg[1248](?:\.nt[1a])? -xma\.[lh]u? -xmpy\.[lh]u? -xor -zxt[124] diff --git a/safety/data/opcodes-x86_64 b/safety/data/opcodes-x86_64 deleted file mode 100644 index b89df8795..000000000 --- a/safety/data/opcodes-x86_64 +++ /dev/null @@ -1,104 +0,0 @@ -adc[bwlq]? -add[bwlq]? -and[bwlq]? -boundl? -bsf[wlq]? -bsr[wlq]? -bswap[lq]? -btc[wlq]? -btr[wlq]? -bts[wlq]? -bt[wlq]? -callq? -cbtw -cbw -cdq -cdqe -clc -cld -cli -cltd -cltq -cmc -cmovn?(?:a|ae|b|be|c|e|g|ge|l|le|o|p|pe|po|s|z)[wlq]? -cmp[bwlq]? -cmps[bwlq]? -cmpxchg16b -cmpxchg8b -cmpxchg[bwlq]? -cpuid -cqo -cqtd -cqto -cwd -cwde -cwtd -cwtl -dec[bwlq]? -div[bwlq]? -enterq? -idiv[bwlq]? -imul[bwlq]? -inc[bwlq]? -jcxz -jmpq? -jn?(?:a|ae|b|be|c|e|g|ge|l|le|o|p|pe|po|s|z) -lcallq? -leaveq? -lea[wlq]? -lfence -lfs[wl]? -lgs[wl]? -lods[bwlq]? -loopn?[ze]? -lretq? -lss[wl]? -mfence -movaps -mov[bwlq]? -movs[bwlq]? -movsb[wlq]? -movslq? -movsw[lq]? -movzb[wlq]? -movzw[lq]? -mul[bwlq]? -neg[bwlq]? -nop -not[bwlq]? -or[bwlq]? -pause -popf[wlq]? -pop[wlq]? -prefetch(?:t[012]|nta) -pushf[wlq]? -push[wlq]? -rcl[bwlq]? -rcr[bwlq]? -rdmsr -rdtsc -retq? -rol[bwlq]? -ror[bwlq]? -sahf -sal[bwlq]? -sar[bwlq]? -sbb[bwlq]? -scas[bwlq]? -setn?(?:a|ae|b|be|c|e|g|ge|l|le|o|p|pe|po|s|z) -shl[bwlq]? -shld[bwlq]? -shr[bwlq]? -shrd[bwlq]? -smov[lw]? -stc -std -sti -stos[bwlq]? -sub[bwlq]? -test[bwlq]? -xadd[bwlq]? -xchg[bwlq]? -xlat -xlatb -xor[bwlq]? diff --git a/safety/data/references b/safety/data/references deleted file mode 100644 index bfea8e867..000000000 --- a/safety/data/references +++ /dev/null @@ -1,94 +0,0 @@ -__alloc_percpu -autoremove_wake_function -__bitmap_weight -cond_resched -__const_udelay -copy_from_user -__copy_from_user_ll -copy_to_user -__copy_user -copy_user_generic -cpu_callout_map -cpu_online_map -cpu_possible_map -cpu_to_node -create_proc_entry -del_timer_sync -__divdi3 -do_gettimeofday -__down_failed -__find_next_bit -find_next_bit -finish_wait -free_percpu -__get_user_4 -init_timer -__init_timer_base -jiffies -kallsyms_lookup_name -kfree -__kmalloc -kmalloc_node -kmem_cache_alloc -malloc_sizes -memcmp -memcpy -memset -__might_sleep -__moddi3 -__mod_timer -mod_timer -msleep -node_online_map -param_get_int -param_get_long -param_get_string -param_set_copystring -param_set_int -param_set_long -per_cpu__cpu_info -prepare_to_wait -printk -proc_mkdir -proc_root -_read_lock -_read_trylock -_read_unlock -register_kprobe -register_kretprobe -register_profile_notifier -register_timer_hook -remove_proc_entry -schedule -schedule_delayed_work -scnprintf -simple_strtol -snprintf -_spin_lock -_spin_lock_irqsave -_spin_trylock -_spin_unlock -_spin_unlock_irqrestore -sprintf -strcmp -strlcat -strlcpy -strlen -strncmp -strncpy -__strncpy_from_user -strsep -__udivdi3 -__umoddi3 -unregister_kprobe -unregister_kretprobe -unregister_profile_notifier -unregister_timer_hook -unw_init_running -unw_unwind -__up_wakeup -vscnprintf -vsnprintf -__wake_up -_write_trylock -_write_unlock diff --git a/safety/safety.py b/safety/safety.py deleted file mode 100755 index 8607ce750..000000000 --- a/safety/safety.py +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# vim: noet sw=4 ts=4 enc=utf-8 -"A static safety-checker for SystemTap modules." - -# Copyright (C) 2006 Intel Corporation. -# -# This file is part of systemtap, and is free software. You can -# redistribute it and/or modify it under the terms of the GNU General -# Public License (GPL); either version 2, or (at your option) any -# later version. - - -# in python 2.4, set & frozenset are builtins -# in python 2.3, the equivalents live in the 'sets' module -from sys import hexversion as __hexversion -if __hexversion < 0x020400f0: - from sets import Set as set, ImmutableSet as frozenset - - -def main(argv): - """ - CLI to the SystemTap static safety-checker. - - Provides a command-line interface for running the SystemTap module - safety checker. Use '-h' or '--help' for a description of the - command-line options. - - Returns the number of modules that failed the check. - """ - bad = 0 - (options, args) = __parse_args(argv[1:]) - safe = StaticSafety(options.arch, options.release, options.datapath) - for m in args: - if not safe.check_module(m): - bad += 1 - return bad - - -def __parse_args(argv): - from optparse import OptionParser - parser = OptionParser(usage="usage: %prog [options] [module]...", - description=__doc__) - parser.add_option('--data-path', dest='datapath', metavar='PATH', - help='specify the whitelist data files [default: /data]') - parser.add_option('-m', '--machine', '--architecture', dest='arch', - help='specify the machine architecture of the target') - parser.add_option('-r', '--kernel-release', dest='release', - help='specify the kernel release running on the target') - return parser.parse_args(argv) - - -class StaticSafety: - "Manage a safety-checking session." - - def __init__(self, arch=None, release=None, datapath=None): - from os import uname - self.__arch = arch or uname()[4] - self.__release = release or uname()[2] - self.__build_data_path(datapath) - self.__build_search_suffixes() - self.__load_allowed_references() - self.__load_allowed_opcodes() - - def __build_data_path(self, datapath): - "Determine where the data directory resides." - from sys import argv - from os.path import dirname, isdir, realpath - if datapath is None: - local = dirname(realpath(argv[0])) - self.__data_path = local + '/data' - else: - self.__data_path = datapath - - if not isdir(self.__data_path): - raise StandardError( - "Can't find the data directory! (looking in %s)" - % self.__data_path) - - def __build_search_suffixes(self): - "Construct arch & kernel-versioning search suffixes." - ss = set() - - # add empty string - ss.add('') - - # add architecture search path - archsfx = '-%s' % self.__arch - ss.add(archsfx) - - # add full kernel-version-release (2.6.NN-FOOBAR) + arch - relsfx = '-%s' % self.__release - ss.add(relsfx) - ss.add(relsfx + archsfx) - - # add kernel version (2.6.NN) + arch - dash_i = relsfx.find('-') - if dash_i > 0: - ss.add(relsfx[:dash_i]) - ss.add(relsfx[:dash_i] + archsfx) - - # start dropping decimals - dot_i = relsfx.rfind('.', 0, dash_i) - while dot_i > 0: - ss.add(relsfx[:dot_i]) - ss.add(relsfx[:dot_i] + archsfx) - dot_i = relsfx.rfind('.', 0, dot_i) - - self.__search_suffixes = frozenset(ss) - - def __load_allowed_references(self): - "Build the list of allowed external references from the data files." - wr = set() - for sfx in self.__search_suffixes: - try: - refs = open(self.__data_path + '/references' + sfx) - for line in refs: - wr.add(line.rstrip()) - refs.close() - except IOError: - pass - if not len(wr): - raise StandardError("No whitelisted references found!") - self.__white_references = frozenset(wr) - - def __load_allowed_opcodes(self): - "Build the regular expression matcher for allowed opcodes from the data files." - from re import compile - wo = [] - for sfx in self.__search_suffixes: - try: - opcs = open(self.__data_path + '/opcodes' + sfx) - for line in opcs: - wo.append(line.rstrip()) - opcs.close() - except IOError: - pass - if not len(wo): - raise StandardError("No whitelisted opcodes found!") - self.__white_opcodes_re = compile(r'^(?:' + r'|'.join(wo) + r')$') - - def __check_references(self, module): - "Check that all unresolved references in the module are allowed." - from os import popen - from re import compile - - sym_re = compile(r'^([\w@.]+) [Uw]\s+$') - def check(line): - m = sym_re.match(line) - if m: - ref = m.group(1) - if ref not in self.__white_references: - print 'ERROR: Invalid reference to %s' % ref - return False - return True - print 'WARNING: Unmatched line:\n %s' % `line` - return True - - command = 'nm --format=posix --no-sort --undefined-only ' + `module` - ok = True - nm = popen(command) - for line in nm: - ok &= check(line) - if nm.close(): - ok = False - return ok - - def __check_opcodes(self, module): - "Check that all disassembled opcodes in the module are allowed." - from os import popen - from re import compile - - skip_ud2a = [0] - - ignore_re = compile(r'^$|^\s+\.{3}$|^.*Disassembly of section|^.*file format') - if self.__arch == 'ia64': - opc = r'(?:\[[IBFLMX]{3}\]\s+)?(?:\(p\d\d\)\s+)?([\w.]+)\b' - elif self.__arch == 'x86_64' or self.__arch == 'i686': - opc = r'(?:lock\s+)?|(?:repn?[ze]?\s+)?|(?:rex\w+\s+)?(\w+)\b' - else: - opc = r'(\w+)\b' - opc_re = compile(r'^[A-Fa-f\d]+\s+<([^>]+)>\s+%s' % opc) - def check(line): - m = ignore_re.match(line) - if m: - return True - m = opc_re.match(line) - if m: - loc, opc = m.groups() - if opc == 'ud2a': - # The kernel abuses ud2a for BUG checks by following it - # directly with __LINE__ and __FILE__. Objdump doesn't - # know this though, so it tries to interpret the data as - # real instructions. Because x86(-64) instructions are - # variable-length, it's hard to tell when objdump is synced - # up again. We'll fast-forward to the next function - # boundary and hope things are better there. - for skip in objdump: - mskip = opc_re.match(skip) - if mskip: - locskip = mskip.group(1) - # a loc without an offset marks a new function - if '+' not in locskip: - return check(skip) - skip_ud2a[0] += 1 - return True - elif not self.__white_opcodes_re.match(opc): - print "ERROR: Invalid opcode '%s' at <%s>" % (opc, loc) - return False - return True - print 'WARNING: Unmatched line:\n %s' % `line` - return True - - command = 'objdump --disassemble --prefix-addresses ' + `module` - ok = True - objdump = popen(command) - for line in objdump: - ok &= check(line) - if objdump.close(): - ok = False - - if skip_ud2a[0]: - #print 'WARNING: Skipped %d lines due to ud2a corruption' % skip_ud2a[0] - pass - - return ok - - def check_module(self, module): - "Check a module for exclusively safe opcodes and external references." - from os.path import isfile - if not isfile(module): - print 'ERROR: %s is not a file!' % `module` - return False - res = self.__check_references(module) and self.__check_opcodes(module) - if res: - print 'PASS: %s' % module - else: - print 'FAIL: %s' % module - return res - - -if __name__ == '__main__': - from sys import exit, argv - exit(main(argv)) - -- 2.43.5