def test_get_or_create_latest(self): # First game r0, status = Round.get_or_create_latest(num=0) assert_equals(status, Round.FIRST_GAME) assert_equals(r0.num, 0) assert_equals(r0, Round.current_round()) # New round r1, status = Round.get_or_create_latest(num=1) assert_equals(status, Round.NEW_ROUND) assert_equals(r1.num, 1) assert_equals(r1, Round.current_round()) assert_equals(r0, Round.prev_round()) # Same round r1b, status = Round.get_or_create_latest(num=1) assert_equals(status, Round.SAME_ROUND) assert_equals(r1b.num, 1) assert_equals(r1b, Round.current_round()) assert_equals(r0, Round.prev_round()) assert_equals(r1, r1b) # New game r0b, status = Round.get_or_create_latest(num=0) assert_equals(status, Round.NEW_GAME) assert_equals(r0b.num, 0) assert_equals(r0b, Round.current_round()) assert_is_none(Round.prev_round())
def test_prev_round_on_new_game(self): Round.create(num=99) assert_equals(Round.prev_round(), None) r0 = Round.create(num=0) assert_equals(Round.prev_round(), None) Round.create(num=1) assert_equals(Round.prev_round(), r0)
def test_prev_round(self): assert_equals(Round.prev_round(), None) Round.create(num=0) assert_equals(Round.prev_round(), None) r1 = Round.create(num=1) Round.create(num=2) assert_equals(Round.prev_round(), r1)
def should_submit(target_cs): # FIXME: this should be generalized per challenge set introduction # don't submit on the first round if Round.current_round().num == 0: LOG.info("Not submitting on round 0.") return False # don't submit if we haven't submitted an exploit before this round if ExploitSubmissionCable.select().join( Exploit).where((ExploitSubmissionCable.cs == target_cs) & (ExploitSubmissionCable.processed_at != None) & (ExploitSubmissionCable.processed_at <= Round.current_round().created_at) & (Exploit.method != "backdoor")).exists(): LOG.info("There's an exploit that's over a round old!.") return True # don't submit if we haven't found an crash before the last round prev_round = Round.prev_round() if prev_round is not None and Crash.select().where( (Crash.cs == target_cs) & (Crash.created_at <= prev_round.created_at)).exists(): LOG.info("There's a crash that's over two rounds old!") return True LOG.info("Patch conditions not met!") return False
def patch_decision_simple(target_cs, round_): """ Determines the CBNs to submit. Returns None if no submission should be made. We only submit 1 patch type per CS. """ LOG.info("CB SUBMISSION START: %s (round %d)", target_cs.name, round_.num) # make sure that this binary is not new this round if not (target_cs.id in [cs.id for cs in ChallengeSet.fielded_in_round(round_)] and Round.prev_round() is not None and target_cs.id in [ cs.id for cs in ChallengeSet.fielded_in_round(Round.prev_round()) ]): LOG.info("%s - not patching in the first round", target_cs.name) return current_fielding = ChallengeSetFielding.latest(cs=target_cs, team=Team.get_our(), round=round_) # Fielding should always be not None, or we are in a # race condition and do not want to do anything right # now, we will be run again, at which point fieldings # should be set. if current_fielding is None: LOG.warning( "%s - hit the race condition for latest fielding being None", target_cs.name) return LOG.info("%s - current patch type: %s", target_cs.name, (current_fielding.cbns[0].patch_type.name if current_fielding.cbns[0].patch_type is not None else "None")) # if we just submitted, wait a round before making any decisions if current_fielding.poll_feedback is not None and ( current_fielding.poll_feedback.timeout + current_fielding.poll_feedback.success + current_fielding.poll_feedback.function + current_fielding.poll_feedback.connect == 0): LOG.warning("%s - skipping 'downed' round", target_cs.name) return # if we don't have any patches ready, let's wait all_patches = target_cs.cbns_by_patch_type() if len(all_patches) == 0: return best_patch_type = sorted(all_patches.keys(), key=lambda pt: pt.exploitability)[0] has_feedback = { k: v for k, v in all_patches.iteritems() if len(v[0].poll_feedbacks) > 0 } pull_back = any(cbns[0].min_cb_score is not None and cbns[0].min_cb_score < MIN_CB_SCORE for cbns in all_patches.values()) for k, v in has_feedback.items(): LOG.info("%s - minimum score of patch %s is %s", target_cs.name, k.name, v[0].min_cb_score) if pull_back: LOG.info("%s - pulling back the patch :-(", target_cs.name) new_cbns = target_cs.cbns_original else: # if we've already patched, and we're not pulling back, forget about it if best_patch_type.name != 'manual' and not CBSubmitter.same_cbns( current_fielding.cbns, target_cs.cbns_original): LOG.info("%s - already patched -- aborting!", target_cs.name) return LOG.info("%s - chose %s patch type!", target_cs.name, best_patch_type.name) new_cbns = all_patches[best_patch_type] # Check if we have submitted in this round? submitted_fielding = ChallengeSetFielding.submissions( cs=target_cs, team=Team.get_our(), round=round_) if submitted_fielding is not None: LOG.info("%s - we have an earlier submission this round...", target_cs.name) prior_submission = list(submitted_fielding.cbns) else: LOG.info("%s - submitting for the first time this round...", target_cs.name) prior_submission = list(current_fielding.cbns) # if we submitted an exploit for the first time this round, let's not patch if not pull_back and ExploitSubmissionCable.select( ).join(Exploit).where( (ExploitSubmissionCable.cs == target_cs) & (ExploitSubmissionCable.processed_at != None) & (ExploitSubmissionCable.processed_at >= round_.created_at) & (Exploit.method != "backdoor")).exists( ) and not ExploitSubmissionCable.select().join(Exploit).where( (ExploitSubmissionCable.cs == target_cs) & (ExploitSubmissionCable.processed_at != None) & (ExploitSubmissionCable.processed_at < round_.created_at) & (Exploit.method != "backdoor")).exists(): LOG.info( "%s - not submitting because we first found an exploit last round", target_cs.name) new_cbns = list(current_fielding.cbns) if CBSubmitter.same_cbns(new_cbns, prior_submission): LOG.info("%s - nothing to do, this would be a resubmission", target_cs.name) return else: LOG.info("%s - we have not yet submitted these CBNs this round!", target_cs.name) return new_cbns