Пример #1
0
def _testlist(args, races):
    def toctou_handle_attack(exe, string):
        pid = os.fork()
        if pid == 0:
            exe.prepare()
            args = string.split()
            assert args[0] == 'attack'
            toctou.attack_toctou(args[1], args[2:])
            os._exit(0)
        else:
            os.waitpid(pid, 0)

    def toctou_bookmark_cb(exe, logfile, scribe, id, npr):
        logging.info('    running generic attack script...')
        try:
            log = re.sub('\.log$', '.toctou', logfile)
            for line in open(log, 'r').readlines():
                toctou_handle_attack(exe, line)
            scribe.stop()
        except:
            traceback.print_exc(file=sys.stdout)
        return False

    if args.toctou:
        bookmark_cb = scribewrap.Callback(toctou_bookmark_cb)
    else:
        bookmark_cb = None

    for n in races:
        t_start = datetime.datetime.now()
        logfile = '%s.%d.log' % (args.path, n)
        if not os.access(logfile, os.R_OK):
            break
        verbose = 'RACE %d: ' % n
        ret = scribewrap.scribe_replay(args,
                                       logfile,
                                       verbose,
                                       test_replay=replay_test_script,
                                       bookmark_cb=bookmark_cb)
        t_end = datetime.datetime.now()
        dt = t_end - t_start
        logging.info('    time:  %.2f' %
                     (dt.seconds + dt.microseconds / 1000000.0))
        if not ret and not args.keepgoing:
            return False
    return True
Пример #2
0
def _testlist(args, races):

    def toctou_handle_attack(exe, string):
        pid = os.fork()
        if pid == 0:
            exe.prepare()
            args = string.split()
            assert args[0] == 'attack'
            toctou.attack_toctou(args[1], args[2:])
            os._exit(0)
        else:
            os.waitpid(pid, 0)

    def toctou_bookmark_cb(exe, logfile, scribe, id, npr):
        logging.info('    running generic attack script...')
        try:
            log = re.sub('\.log$', '.toctou', logfile)
            for line in open(log, 'r').readlines():
                toctou_handle_attack(exe, line)
            scribe.stop()
        except:
            traceback.print_exc(file=sys.stdout)
        return False

    if args.toctou:
        bookmark_cb = scribewrap.Callback(toctou_bookmark_cb)
    else:
        bookmark_cb = None

    for n in races:
        t_start = datetime.datetime.now()
        logfile = '%s.%d.log' % (args.path, n)
        if not os.access(logfile, os.R_OK):
            break
        verbose = 'RACE %d: ' % n
        ret = scribewrap.scribe_replay(args, logfile, verbose,
                                       test_replay=replay_test_script,
                                       bookmark_cb=bookmark_cb)
        t_end = datetime.datetime.now()
        dt = t_end - t_start
        logging.info('    time:  %.2f' %
                     (dt.seconds + dt.microseconds / 1000000.0))
        if not ret and not args.keepgoing:
            return False
    return True
Пример #3
0
def instrumented_replay(graph, args, queriers):
    bookmarks = list()
    events = networkx.algorithms.dag.topological_sort(graph)

    for node in events:
        if not node.is_a(scribe.EventSyscallExtra):
            continue

        node.queriers = list()

        for querier in queriers:
            if querier.need_bookmark(node, before=True):
                node.queriers.append(querier)
                bookmarks.append(dict({node.proc: NodeLoc(node, 'before')}))
            if querier.need_bookmark(node, after=True):
                node.queriers.append(querier)
                bookmarks.append(dict({node.proc: NodeLoc(node, 'after')}))

    out = args.path + '.pre.log'
    save_modify_log(graph, out, bookmarks, None, None, None)

    def predetect_bookmark_cb(**kargs):
        bookmarks = kargs['bookmarks']
        exe = kargs['exe']
        id = kargs['id']

        for nl in bookmarks[id].values():
            for querier in nl.node.queriers:
                querier.upon_bookmark(nl.node, exe,
                                      before=nl.before,
                                      after=nl.after)
        return True

    bookmark_cb = scribewrap.Callback(predetect_bookmark_cb, bookmarks=bookmarks)

    ret = scribewrap.scribe_replay(args, logfile=out, bookmark_cb=bookmark_cb)
    if not ret:
        raise execute.ExecuteError(
                'pre-detect replay failed: try with --skip-predetect', ret)

    for node in events:
        for querier in queriers:
            querier.after_replay(graph, node)
Пример #4
0
def do_one_test(args, t_name, t_exec):
    if args.chroot and not os.access(args.chroot, os.R_OK | os.X_OK):
        os.mkdir(args.chroot)

    if args.scratch and os.access(args.scratch, os.F_OK):
        cmd = 'rm -rf %s' % args.scratch
        execute.sudo(cmd.split())
        os.mkdir(args.scratch)

    logging.info('Processing test: %s' % (t_name))

    args.pdir = args.outdir + '/' + t_name
    args.path = args.outdir + '/' + t_name + '/out'

    def def_script_name(path):
        return path if os.access(path, os.R_OK | os.X_OK) else None

    args._run = args.run if 'run' in args else '%s' % t_exec
    args._test = args.test \
        if 'test' in args else def_script_name('%s.test' % t_name)
    args._pre = args.pre \
        if 'pre' in args else def_script_name('%s.pre' % t_name)
    args._post = args.post \
        if 'post' in args else def_script_name('%s.post' % t_name)

    logging.debug('%s %s' % (t_name, t_exec))

    if args._test and not os.access(args._test, os.X_OK):
        logging.error('%s: test script request but not found' % args._test)
        return False
    if args._pre and not os.access(args._pre, os.X_OK):
        logging.error('%s: pre script request but not found' % args._pre)
        return False
    if args._post and not os.access(args._post, os.X_OK):
        logging.error('%s: post script request but not found' % args._post)
        return False

    opts = ''
    if args.debug: opts += ' -d'
    if args.verbose: opts += ' -v'

    logging.info('  output in directory %s' % args.pdir)

    if not args.skip_record:
        if os.access(args.pdir, os.R_OK):
            cmd = 'rm -rf %s' % args.pdir
            execute.sudo(cmd.split())
    cmd = 'mkdir -p %s' % args.pdir
    execute.sudo(cmd.split())

    if args.quiet:
        args.redirect = open(args.path + '.out', 'w')
    else:
        args.redirect = None

    t_start = datetime.datetime.now()

    if not args.skip_record:
        logging.info('  recording original exceution (twice)')
        if not scribewrap.scribe_record(args):
            return True if args.keepgoing else False
        if not args.jailed and not scribewrap.scribe_record(args):
            return True if args.keepgoing else False

        t_replay = datetime.datetime.now()

        # If args.max_runtimes was enabled, then recording may have stopped
        # an "external" script; We expect replay to also stop similarly, so
        # we don't need to temporarilty turn off args.max_runtime.
        logging.info('  replaying original execution')
        max_runtime = args.max_runtime
        args.max_runtime = 0
        if not scribewrap.scribe_replay(args):
            return True if args.keepgoing else False
        args.max_runtime = max_runtime

    else:
        t_replay = t_start

    t_record = datetime.datetime.now()

    if not args.skip_findrace:
        logging.info('  generating the races')
        if not _findraces(args, opts):
            return True if args.keepgoing else False

    t_findrace = datetime.datetime.now()

    if not args.skip_testrace:
        logging.info('  testing the races (auto)')
        if not _testraces(args):
            return True if args.keepgoing else False

    t_stop = datetime.datetime.now()

    if args.race_list:
        logging.info('  testing the races (list)')
        if not _testlist(args, map(int, args.race_list.split(':'))):
            return True if args.keepgoing else False

    if args.race_file:
        logging.info('  testing the races (list)')
        with open(args.race_file) as file:
            for line in file:
                if not _testlist(args, map(int, line.split(':'))):
                    return True if args.keepgoing else False

    dt_replay = t_replay - t_start
    dt_record = t_record - t_replay
    dt_findrace = t_findrace - t_record
    dt_testrace = t_stop - t_findrace
    dt_total = t_stop - t_start
    logging.info('total time:     %.2f' %
                 (dt_total.seconds + dt_total.microseconds / 1000000.0))
    logging.info('total record:   %.2f' %
                 (dt_record.seconds + dt_record.microseconds / 1000000.0))
    logging.info('total replay:   %.2f' %
                 (dt_replay.seconds + dt_replay.microseconds / 1000000.0))
    logging.info('total findrace: %.2f' %
                 (dt_findrace.seconds + dt_findrace.microseconds / 1000000.0))
    logging.info('total testrace: %.2f' %
                 (dt_testrace.seconds + dt_testrace.microseconds / 1000000.0))

    return True
Пример #5
0
def do_one_test(args, t_name, t_exec):
    if args.chroot and not os.access(args.chroot, os.R_OK | os.X_OK):
        os.mkdir(args.chroot)

    if args.scratch and os.access(args.scratch, os.F_OK):
        cmd = 'rm -rf %s' % args.scratch
        execute.sudo(cmd.split())
        os.mkdir(args.scratch)

    logging.info('Processing test: %s' % (t_name))

    args.pdir = args.outdir + '/' + t_name
    args.path = args.outdir + '/' + t_name + '/out'

    def def_script_name(path):
        return path if os.access(path, os.R_OK | os.X_OK) else None

    args._run = args.run if 'run' in args else '%s' % t_exec
    args._test = args.test \
        if 'test' in args else def_script_name('%s.test' % t_name)
    args._pre = args.pre \
        if 'pre' in args else def_script_name('%s.pre' % t_name)
    args._post = args.post \
        if 'post' in args else def_script_name('%s.post' % t_name)

    logging.debug('%s %s' % (t_name, t_exec))

    if args._test and not os.access(args._test, os.X_OK):
        logging.error('%s: test script request but not found' % args._test)
        return False
    if args._pre and not os.access(args._pre, os.X_OK):
        logging.error('%s: pre script request but not found' % args._pre)
        return False
    if args._post and not os.access(args._post, os.X_OK):
        logging.error('%s: post script request but not found' % args._post)
        return False

    opts = ''
    if args.debug: opts += ' -d'
    if args.verbose: opts += ' -v'

    logging.info('  output in directory %s' % args.pdir)

    if not args.skip_record:
        if os.access(args.pdir, os.R_OK):
            cmd = 'rm -rf %s' % args.pdir
            execute.sudo(cmd.split())
    cmd = 'mkdir -p %s' % args.pdir
    execute.sudo(cmd.split())

    if args.quiet:
        args.redirect = open(args.path + '.out', 'w')
    else:
        args.redirect = None

    t_start = datetime.datetime.now()

    if not args.skip_record:
        logging.info('  recording original exceution (twice)')
        if not scribewrap.scribe_record(args):
            return True if args.keepgoing else False
        if not args.jailed and not scribewrap.scribe_record(args):
            return True if args.keepgoing else False

        t_replay = datetime.datetime.now()

        # If args.max_runtimes was enabled, then recording may have stopped
        # an "external" script; We expect replay to also stop similarly, so
        # we don't need to temporarilty turn off args.max_runtime.
        logging.info('  replaying original execution')
        max_runtime = args.max_runtime
        args.max_runtime = 0
        if not scribewrap.scribe_replay(args):
            return True if args.keepgoing else False
        args.max_runtime = max_runtime

    else:
        t_replay = t_start

    t_record = datetime.datetime.now()

    if not args.skip_findrace:
        logging.info('  generating the races')
        if not _findraces(args, opts):
            return True if args.keepgoing else False

    t_findrace = datetime.datetime.now()

    if not args.skip_testrace:
        logging.info('  testing the races (auto)')
        if not _testraces(args):
            return True if args.keepgoing else False

    t_stop = datetime.datetime.now()

    if args.race_list:
        logging.info('  testing the races (list)')
        if not _testlist(args, map(int, args.race_list.split(':'))):
            return True if args.keepgoing else False

    if args.race_file:
        logging.info('  testing the races (list)')
        with open(args.race_file) as file:
            for line in file:
                if not _testlist(args, map(int, line.split(':'))):
                    return True if args.keepgoing else False

    dt_replay = t_replay - t_start
    dt_record = t_record - t_replay
    dt_findrace = t_findrace - t_record
    dt_testrace = t_stop - t_findrace
    dt_total = t_stop - t_start
    logging.info('total time:     %.2f' %
                 (dt_total.seconds + dt_total.microseconds / 1000000.0))
    logging.info('total record:   %.2f' %
                 (dt_record.seconds + dt_record.microseconds / 1000000.0))
    logging.info('total replay:   %.2f' %
                 (dt_replay.seconds + dt_replay.microseconds / 1000000.0))
    logging.info('total findrace: %.2f' %
                 (dt_findrace.seconds + dt_findrace.microseconds / 1000000.0))
    logging.info('total testrace: %.2f' %
                 (dt_testrace.seconds + dt_testrace.microseconds / 1000000.0))

    return True